im.kayac.comでiPhoneにtwitterをプッシュ通知するphpソースコードサンプル


特定のユーザのtwitterの投稿をiPhoneにプッシュ通知してくれるアプリが欲しい。
そういうアプリはなさそうなので、本当はそういうアプリを作りたかったのだけれど、大変そうなのでim.kayac.comとphpとcronで実現してみた。
im.kayac.com(App Store)
このiPhoneアプリはいろいろ便利。プログラムかければいろんなのをプッシュ通知できる。

以下サンプルソース。変なところがあったら教えて欲しい。
これをcronで5分毎に実行する。
(cronで実行するときは、1行目に#!/usr/local/bin/phpって書く)

<?php
// 取得したいツイッターユーザの名前(ID)を配列で設定。
$tnames = array("tweetid");
 
// im.kayacのユーザ名
define(K_NAME, 'username');
// im.kayacでパスワード認証を設定している場合
define(K_PASS, 'pass'); //
// im.kayacで秘密鍵認証を設定している場合
define(K_SIG, 'pass');
 
// 重複取得回避用のログファイル
define(LOG_FILE_NAME, 'tw_log.php');
// エラーログ記録用のファイル
define(ERRLOG_FILE_NAME, 'tw_errlog.log');
 
// 取得したメッセージをim.kayac.comへ。
function outMessage($message){
	// メッセージの内容
 
	// 時間
	$timestamp = strtotime($message->created_at);
	$content = date("Y/m/d H:i",$timestamp)."@";
	// 名前
	$content .= $message->user->name.">>";
	// 内容
	$content .= $message->text."";
 
	// imkayacを使ってプッシュ
	imkayac($content);
	return;
}
 
// http://project-p.jp/halt/anubis/blog_show/1269をほぼそのまんま
// cURLでできるんじゃなかろうか。
function imkayac($message){
 
	$data = array(
	    "message" => $message,
	    "password" => K_PASS,
	);
 
	$data['sig'] = sha1($data['message'] . K_SIG);
	unset($data['password']);
 
	$data = http_build_query($data, "", "&");
 
	//header
	$header = array(
	    "Content-Type: application/x-www-form-urlencoded",
	    "Content-Length: ".strlen($data)
	);
 
	$context = array(
	    "http" => array(
	        "method"  => "POST",
	        "header"  => implode("\r\n", $header),
	        "content" => $data
	    )
	);
 
	$url = "http://im.kayac.com/api/post/".K_NAME;
	file_get_contents($url, false, stream_context_create($context));
	return;
}
 
 
// ログ取得(重複tweet読込回避)
function getLog(){
	$retval = array();
	if( ($fp = fopen(LOG_FILE_NAME,"r+") ) ){
		while (! feof($fp)) {
			$line = fgets ($fp, 4096);
			$data = explode(",", trim($line));
			$retval[$data[0]] = $data[1];
		}
		fclose($fp);
	}
	return $retval;
}
 
// ログ保存(重複tweet読込回避)
function saveLog($datas){
	$log = '';
	if(!empty($datas) && is_array($datas)){
		foreach($datas as $name => $id){
			if(!empty($name) && $id){
				$log .= $name.",".$id."\n";
			}
		}
	}
	$fp = fopen(LOG_FILE_NAME,"w+");
	flock($fp, LOCK_EX);
	fputs($fp, $log);
	flock($fp, LOCK_UN);
	fclose($fp);
	return;
}
 
// エラーログ保存(念のため)
function saveErrLog($message){
	$fp = fopen(ERRLOG_FILE_NAME,"a+");
	$date = date('Y/m/d h:i:s');
	$logmessage = $date." ".$message."\n";
	flock($fp, LOCK_EX);
	fputs($fp, $logmessage);
	flock($fp, LOCK_UN);
	fclose($fp);
	return;
}
 
// 重複取得回避用
$logs = getLog();
 
foreach($tnames as $tname){
	// 重複取得回避用
	if(!empty($logs[$tname])){
		$since_id = "?since_id=".$logs[$tname];
	} else {
		$since_id = "";
	}
 
	// 特定のユーザーのタイムライン取得用API
	$apiURL = "http://api.twitter.com/1/statuses/user_timeline/".$tname.".xml".$since_id;
 
	// cURLを使ってXML取得
	$ch = curl_init(); 
	curl_setopt($ch, CURLOPT_URL, $apiURL);
	curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	$retXML = curl_exec($ch); 
	curl_close($ch);
 
	// 取得したXMLを解析
	if(!empty($retXML) && ereg("^<\?xml", $retXML) && 
	   $xml = simplexml_load_string($retXML)
	){
		if($xml->status){
			foreach($xml->status as $message){
				// 重複取得回避用
				if($logs[$tname] <= $message->id){
					$logs[$tname] = $message->id;
				}
				// 取得したTLを出力
				outMessage($message);
			}
		}
	} else {
		// 一応エラーログ記録
		saveErrLog("xml取得失敗");
	}
}
 
// 重複取得回避用
saveLog($logs);
?>

twiiterAPIと通信する部分をいろいろ変えればReplyとかmentionとかだけ取得することも可能。
そんときはログインも必要になるので、「phpでTwitterをハンドリングするサンプル」を参考に変えたらいいと思う。
他に欲しい情報とかあったら、Twitter API Wikiのサイトをみればだいたい分かる。
英語読めなくても結構わかる。

※参考サイト

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


二 + 4 =