復興ログ

未来の被災地にいるアナタと数十年後のキミたちへ。すべての記録を残します。

TwitterAPIのJSONをTLに変換するJS関数

TwitterAPIがJSONで返してくる場合にJSONからタイムラインに変換したくなります。
また、Twitpicの画像がURL中に含まれていた場合にサムネイル画像を表示してあげる方法です。
このツイートを


JSONから以下の画像のように表示します。

  • URLをリンク付きに
  • @付きをユーザページへのリンクに
  • ハッシュタグを検索ページに
  • twitpicの画像サムネイルを表示する

f:id:hebita164:20100805010946p:image

jQueryを使って以下のような記述で行けます。

ちょっとkwabiraki.jpで作ったのでまとめておきますね。

JS部分

jQueryの呼び出し
<head>
<!-- jQueryの呼び出し -->
<script type="text/javascript"> 
	google.load("jquery", "1.4.2");
</script>
</head>
処理対象のJSON

以下は1ユーザのツイートのみ
本当は100件まで取れます

var ishinomaki = {"results":[{"profile_image_url":"http://a3.twimg.com/profile_images/1074666115/24398716_77756349_normal.jpg","created_at":"Wed, 04 Aug 2010 15:09:01 +0000","from_user":"harry0711","metadata":{"result_type":"recent"},"to_user_id":114988755,"text":"@hoya_expo \u4eca\u66f4\u306a\u306e\u3067\u3059\u304c\u3001\u77f3\u5dfb\u306b\u4f4f\u3093\u3067\u3044\u306a\u304c\u3089\u30db\u30e4\u304c\u552f\u4e00\u306e\u5acc\u3044\u306a\u98df\u3079\u7269\u306a\u50d5\u306f\u3069\u3046\u3057\u305f\u3089\u3044\u3044\u306e\u3067\u3057\u3087\u3046\uff1f","id":20311103645,"from_user_id":133850665,"to_user":"hoya_expo","geo":null,"iso_language_code":"ja","source":"&lt;a href=&quot;http://twitter.com/&quot;&gt;web&lt;/a&gt;"},"max_id":20311103645,"since_id":0,"refresh_url":"?since_id=20311103645&q=%E7%9F%B3%E5%B7%BB+OR+%E5%B7%9D%E9%96%8B%E3%81%8D+OR+%23kawabiraki","next_page":"?page=2&max_id=20311103645&rpp=100&q=%E7%9F%B3%E5%B7%BB+OR+%E5%B7%9D%E9%96%8B%E3%81%8D+OR+%23kawabiraki","results_per_page":100,"page":1,"completed_in":0.072175,"query":"%E7%9F%B3%E5%B7%BB+OR+%E5%B7%9D%E9%96%8B%E3%81%8D+OR+%23kawabiraki"}]}
処理ロジック

非同期でid=userTimeLineにツイートを流し込みます。

$.each(ishinomaki.results,function(tweet){	
	if( start <= counter && end > counter) {
		var html = makeTweet(ishinomaki.results[tweet]);
		$("#userTimeLine").append(html);
	}
});

makeTweet = function(status){
	var html = '';
	var image_url = status.user.profileImageUrl;
	var screenName = status.user.screenName;
	var	text = t_hash(t_at(t_link(status.text)));
	var img = twitpic(status.text);
	var create = status.createdAt;
		
	html += '<li class="tweet">';
	html += '<span class="thumb"><a href="http://twitter.com/' + screenName + '">';
	html += '<img src="' + image_url + '" border="0" width="48" height="48">';
	html += '</a></span>';
	html += '<span class="status-body"><h3>@<a href="http://twitter.com/'+ screenName +'" target="_blank" class="twitter-anywhere-user">' + screenName + '</a></h3>';
	html += text + '<br />';
	html += '<span class="createTime">'+create2date(create)+'</span>';
	if(img){
		html += '<div style="text-align:right">'+img+'</div>';
	}
	html += '</span></li>';
	return html;
}
 
create2date = function(create){
	var date = new Date(create);
	date.setHours(date.getHours()); // UTC -> JST (+9時間)
	var y    = date.getFullYear();         // 月取得
	var mon  = date.getMonth() + 1;     // 月取得
	var day  = date.getDate();          // 日取得
	var h    = date.getHours();
	var min  = date.getMinutes();
	if (min < 10) {
		min = "0" + min;
	}
	create = y+ '年' + mon + '月' + day +'日 ' + h + '時' + min + '分';
	return create;
}

t_link = function(t) {
	return t.replace(/[htps]+:\/\/[a-z0-9-_]+\.[a-z0-9-_:~%&\?\/.=]+[^:\.,\)\s*$]/ig, function(m) {
			return '<a href="' + m + '" target="_blank">' + m + '</a>';
	});
}

t_at = function(t) {
	return t.replace(/(^|[^\w]+)\@([a-zA-Z0-9_]{1,15})/g, function(m, m1, m2) {
			return m1 + '@<a href="http://twitter.com/' + m2 + '" target="_blank" class="twitter-anywhere-user">' + m2 + '</a>';
	});
}

t_hash = function(t) {
	return t.replace(/(^|[^\w'"]+)\#([a-zA-Z0-9_]+)/g, function(m, m1, m2) {
			return m1 + '#<a href="http://twitter.com/search?q=%23' + m2 + '" target="_blank">' + m2 + '</a>';
	});
}

twitpic = function(text) {
  var ret = '';
  var urls = text.match(/http:\/\/twitpic.com\/\w{6}/g);
  if (urls) {
    for (var i = 0; i < urls.length; i++) {
      ret += '<a href=\"' + urls[i] + '\" target=\"_blank\">'
      + '<img height=\"150\" width=\"150\" src=\"'
      + urls[i].replace('twitpic.com', 'twitpic.com/show/thumb')
      + '\" /></a> '
    }
  }
  
  return ret;
}

関数 makeTweet()に流しこむことですべてを加工してくれます。
とういか、、ライブラリにすればいいのか。。
上記関数は、その辺りに落ちているソースです。ありがとうございました。

デザイン

JSの中でデザインを抱えてしまっているので、参考までにCSSを記述しておきます。

<style type="text/css"><!--
.timeLine {
	font-size:14px;
	list-style-image:none;
	list-style-position:outside;
	list-style-type:none;
}
.timeLine .tweet{
	display:block;
	margin:0 0 20px 0;
	position:relative;
}
.timeLine .thumb {
	display:block;
	height:50px;
	left:0;
	margin:0 10px 0 0;
	overflow:hidden;
	position:absolute;
	width:50px;
	z-index:10;
}
.timeLine span.status-body {
	display:block;
	margin-left:56px;
	min-height:48px;
	overflow:hidden;
	width:600px;
}
.timeLine h3 {
	font-size:123%;
	font-weight:normal;
	margin:0;
}
.timeLine span.createTime {
	color:#008000;
	font-size:90%;
}
--></style>

<!-- タイムラインを流し込む表示部分 -->
<div class="timeLine"> 
	<div id="userTimeLine"> 
	</div> 
</div> 

.timelineは主にデザインで。
#userTimeLineは主にタイムラインを流し込むためだけに使用します。

こんなややこしい作りなのも、先行して作ったtwitterクライアントの流れを組むロジックだからです。。

ぜひ、twitterのタイムラインをAPIから提供されるJSONから作ってみたい場合には参考にしてみてください。

Twitterに投稿 Facebookでshare