Big Bang

パソコンの電源を入れた時、メモリー空間に無限の宇宙が拡がる

Twitter API 愛の劇場のソース

| 1件のコメント

こないだの記事「Twitterで愛の劇場」のソースです。

このソースを書くにあたってIBMの記事「Twitter REST API の使い方」を参考にさせていただきました。非常にわかりやすい記事です。

要はRESTで簡単にTwitterのつぶやきを取りこめるAPIが提供されているということです。

たとえばブラウザのアドレスバーに「https://twitter.com/statuses/user_timeline.xml?id=Tom3suteki」と打ち込めばそれだけでTom3sutekiのつぶやきデータがXMLで取得できます。

あとは、取得したそのデータを加工すれば、好きなようにTwitterのつぶやきを表示できるというものです。

http://twitter.com/statuses/user_timeline.xml?id=Tom3suteki

取得できるフォーマットはXMLの他にJSON、Atom、RSSがあります。
青文字のxmljsonにすればJSONが、atomにすればAtomが、rssにすればRSSが取得できます。

idに呼び出したいTwitterのid(Tomさんの場合@Tom3suteki)を指定すれば、好きな人のつぶやきが見られます。

ただし、これには制約があって「Twitter ヘルプセンター」によると、1時間に150アクセスまでの制限があって、それを越えると一定時間エラーが帰ってくるようです。

また、指定しないと一度に得られるつぶやきは20個までしか帰って来ません。
数を指定したい時は、count=200というように指定します。ただし最大値は200です。

https://twitter.com/statuses/user_timeline.rss?id=Tom3suteki&count=1
RSSで1個だけ帰ってくるように指定した場合

このほかにもたくさんの種類のAPIがあって、「WebService/Twitter/API – わすWiki」というページで日本語訳を作ってくれています。

最初、IBMのページだけを見て、サクッとPHPでソースを書いて公開したのがリレー小説「Twitterで愛の劇場」ビューワーでした。

ところが、ある時を境にリレー小説の1人が表示されなくなります。はじめは、まさか1時間で150アクセスあったんだろうか?と考えましたが違いました。

他のことをつぶやいているうちに最新20の中にリレー小説がなくなったから表示されなかっただけでした。

以下のソースは、その不備のあるソースです。上に書いた以外にもかなり不備があります。
現在は改訂版を使っていますが、改訂版のソースは別に公開したいと思います。

ブログ側ソース(PHPのデータを取得)

<!-- 表示エリア -->
<div id="twitter_div"></div>

<script type="text/javascript">
//専用スタイルシートを取得
var css=document.createElement('link');
css.setAttribute('type','text/css');
css.setAttribute('rel','stylesheet');
css.setAttribute('href','http://api.dwm.me/twitter/twitter.css');

var head=document.getElementsByTagName('head');
head[0].appendChild(css);

//スクリプトを取得(スクリプト内の関数で表示エリアにHTMLを埋め込む)
var script=document.createElement('script');
script.setAttribute('type','text/javascript');
script.setAttribute('src','http://api.dwm.me/twitter/');

head[0].appendChild(script);
</script>

PHPソース(サーバーに設置 / 前述のように不備があります)

<?php
//HTMLヘッダを送信
//このPHPのソースはUTF-8で書いていますが、ブログに合わせてShift_JISで送信
header("Content-Type: text/javascript; charset=Shift_JIS");

//ob_end_flush用コールバック
function ob_callback($buffer){
	//文字コードをShift_JISに変換
	return mb_convert_encoding($buffer,"SJIS","UTF-8");
}

//送信前に文字コードを変換するためバッファリング
ob_start("ob_callback");

$novel=array();
$rest="https://twitter.com/statuses/user_timeline.xml";
$url_base="https://twitter.com/#!/";
//リレー小説なので2人のidからつぶやきを取得
$user=array(
	//sinceより後のつぶやきのみを指定(sinceは含まれない)
	array("id"=>"Tom3suteki","since"=>"200851367760363520"),
	array("id"=>"welcome2ourshop","since"=>"197014233546883072")
);

foreach($user as $u){
	//simplexmlでXMLを取り込む
	$url=$rest."?id=".$u["id"]."&since_id=".$u["since"];
	$xml=simplexml_load_file($url);

	//エラー時の処理
	if(!$xml){
		print "<p>データの取得に失敗しました。</p>";
		ob_end_flush();
		exit();
	}

	foreach($xml->status as $status){
		//リレー小説の目印として「つづく」があれば取り込み
		//実際にはsearch APIを使う方がいいです
		if(preg_match("/つづく(。)?$/",$status->text)){
			//連想配列を作成
			$array["text"]=$status->text;
			$array["name"]=$status->user->name;
			$array["screen_name"]=$status->user->screen_name;
			$array["profile_image_url"]=
				$status->user->profile_image_url;
			//要素が連想配列の配列
			$novel["$status->id"]=$array;
		}
	}
}

//公開順にソート(キーはid)
ksort($novel,SORT_NUMERIC);

?>

//表示順並び替え用JavaScript
//詳細は別記事「JavaScriptで表の並び替え
var swap=function(id){
	var table=document.getElementById(id);
	if(!table){return;}

	var tr=table.getElementsByTagName('tr');
	var min=0,max=tr.length-1;

	while(min<max){
		var td_min=tr[min].getElementsByTagName('td');
		var td_max=tr[max].getElementsByTagName('td');
		var tmp1=td_min[0].innerHTML;
		var tmp2=td_min[1].innerHTML;
		td_min[0].innerHTML=td_max[0].innerHTML;
		td_min[1].innerHTML=td_max[1].innerHTML;
		td_max[0].innerHTML=tmp1;
		td_max[1].innerHTML=tmp2;
		min++;
		max--;
	}
}

<?php
	//JavaScriptで処理する配列を作成
	$sep="";

	print 'var value=[';

	foreach($novel as $val){
		print $sep."{'url_base':'".$url_base.
			"','image_url':'".$val['profile_image_url'].
			"','name':'".$val["name"]."','screen_name':'".
			$val["screen_name"]."','text':'"
			.preg_replace('/^\s*(@.+)?\s/',
				'<a class="reply" href="'.$url_base
				.'$1" target="_blank">$1</a>&'
				.'nbsp;',$val["text"])
			."'}";

		$sep=",";
	}

	print '];';
?>

//配列処理用JavaScript
var div=document.getElementById('twitter_div');

if(div){
	var buff='<p style="text-align:right">'
		+'<input type="button" value="新しいのを上にする" '
		+'onclick="swap(\'twitter\');'
		+'this.value
			=this.value==\'古いのを上にする\''
			+'?\'新しいのを上にする\':\'古いのを上にする\';"/>'
		+'</p>'
		+'<table id="twitter">'
		+'<caption>Twitter愛のリレー小説<br/>'
		+'<span>「セルヴーズの雨傘」</span>'
		+'</caption>';

	for(var i=0;i<value.length;i++){
		buff+='<tr>'
			+'<td>'
			+'<a href="'+value[i].url_base
			+value[i].screen_name+'" target="_blank">'
			+'<img src="'+value[i].image_url+'"/></a>'
			+'</td>'
			+'<td>'
			+'<a class="name" href="'+value[i].url_base
			+value[i].screen_name+'" target="_blank">'
			+value[i].name+'</a>&nbsp;'
			+'<a class="screen_name" href="'
			+value[i].url_base+value[i].screen_name
			+'" target="_blank">'
			+'@'+value[i].screen_name+'</a>'
			+'<br/>'+value[i].text
			+'</td>'
			+'</tr>';
	}

	div.innerHTML=buff+'</table>';
}

//PHPの閉じタグがないのは意図的
/* PHP コードのみからなるファイルでは、終了タグ ("?>") は決して含めてはいけません。これは必須なものではなく、 終了タグを省略することで、ファイルの最後にある空白文字が出力に影響することを防ぎます。 */
<?php ob_end_flush();

これはPHP コードのみからなるファイルではありませんが、説明の内容からするとファイルの最後がPHPの場合は、という判断でいいのではないかと思います。私はHTMLとの混合PHPの場合でも、最後がPHPの場合はいつも閉じタグを書きませんが、エラーが出たことはありません。

1件のコメント

  1. 教えてくれてありがとう。よく分かったー

コメントを残す

Top