The jonki

呼ばれて飛び出てじょじょじょじょーんき

Google TalkからXMPPでTwitterに投稿する。

すっきりわかるGoogle App Engine for Javaクラウドプログラミング

今回のプログラムは、「すっきりわかるGoogle App Engine for Javaクラウドプログラミング」の10.3章のサンプルとほぼ同じです(一部修正)。役立つサンプルが多く載ってるし、解説も分かりやすいのでオススメの本です。Javaの基本文法は知ってるけど、Servletと聞くだけで青ざめてしまうレベルの人(自分)にも分かりやすいです。

概要

今回はXMPP 【eXtensible Messaging and Presence Protocol】というプロトコルを利用して、Google App Engine(以下GAE)に展開したServlet経由でTwitterに投稿をします。投稿するにはGoogle Talkを利用します。
文字だけの説明だと分かりにくいと思うので、下図から何となくイメージしてください。

ツイート例

準備

Google TalkでJID (アプリケーション名@appspot.com)を指定し、それをGAEのServletXMPP受信し、その内容をツイートします。このServletプログラムをこんな感じです。POSTでXMPPメッセージを受信し、その受信したデータをtwitter4jを利用してツイートしてるだけです。web.xmlでこのServletクラスを指定しているので、XMPPを利用してるだけで通常のServletと使い方は同じ。OAuthを利用するのであらかじめTwitterのアプリケーション登録等の手続きは済ませておいて下さい。登録方法はPythonですがここに書いてあります。

メインプログラム(XMPP2Twitter.java)
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.conf.ConfigurationBuilder;

import com.google.appengine.api.xmpp.Message;
import com.google.appengine.api.xmpp.XMPPService;
import com.google.appengine.api.xmpp.XMPPServiceFactory;

public class XMPP2Twitter extends HttpServlet{
	static Logger logger = Logger.getLogger("XMPP2Twitter");
	static String xmppAccount = "xxx@gmail.com";
	
	static String consumerKey = "xxx";
	static String consumerSecret = "xxx";
	
	static String accessToken = "xxx";
	static String accessTokenSecret = "xxx";

	public void doPost(HttpServletRequest req, HttpServletResponse resp )
			throws IOException {
		//XMPPServiceを作成
		XMPPService xmpp = XMPPServiceFactory.getXMPPService();
		//リクエストからメッセージを取り出し
		Message message = xmpp.parseMessage(req);
		
		String xmppAddr = message.getFromJid().getId();
		logger.info("xmppAddr = " + xmppAddr );
		
		//登録されているJIDからでなければログに書いてリターn
		if(!xmppAddr.startsWith(xmppAccount)){
			logger.severe(xmppAddr + " does not match");
			return;
		}
		
		//Twitterに書き出し
		//http://twitter4j.org/ja/configuration.html
		TwitterFactory factory = new TwitterFactory();
		ConfigurationBuilder cb = new ConfigurationBuilder();
		cb.setDebugEnabled(true)
			.setOAuthAccessToken(accessToken)
			.setOAuthAccessTokenSecret(accessTokenSecret)
			.setOAuthConsumerKey(consumerKey)
			.setOAuthConsumerSecret(consumerSecret);
		
		Twitter twitter = new TwitterFactory(cb.build()).getInstance();
		try {
			twitter.updateStatus(message.getBody());
		} catch (TwitterException e) {
			logger.log(Level.SEVERE, "Twitter error", e);
		}

	}
}


ちなみに本に載っているソースコードではetOAuthAuthorizedInstanceという関数を使ってますが、現行のtwitter4jでは廃止されたのかそのような関数はありませんでした。本家のページを見ると、この関数ではなく上記に示したような形式でカスタマーキー等を設定していました。下が本に書いてあったソース。

Twitter twitter = 
    factory.getOAuthAuthorizedInstance(consumerKey, consumerSecret, new AccessToken(accessToken, accessTokenSecret))
XMPPの受信指定(appengine-web.xml)
<inbound-services>
		<service>xmpp_message</service>
</inbound-services>
リダイレクト設定(web.xml)
<servlet>
	<servlet-name>xmpp2Twitter</servlet-name>
	<servlet-class>hogehoge.XMPP2Twitter</servlet-class></servlet>
<servlet-mapping>
<servlet-mapping>
	<servlet-name>xmpp2Twitter</servlet-name>
	<url-pattern>/_ah/xmpp/message/chat/</url-pattern></servlet-mapping>
<security-constraint>

投稿テスト

GMail上のチャットエリアから、JID (ノード@ドメイン名)を指定して招待します。JIDは<アプリケーション名@appspot.com>です。

これでツイートしたい内容をチャット感覚で送信。ツイートできてれば成功です。ツイートできてなかったらGAEの管理画面からログを見て、エラー原因を探ってみると良いです。


おしまい。