Monthly Archives: 2月 2010

twitterを携帯メールに転送するGAEアプリ

iPhoneも、Androidも、そもそも自宅ネット環境もない私はもっぱら、携帯でTwitterを使っています。

tmitter(http://tmitter.org/)でタイムラインが取得できなくなってしまったので、GAEの勉強もかねて作ってみました。

package ishigami.twittermail;
import java.io.IOException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.mail.MailServiceFactory;
import com.google.appengine.api.mail.MailService.Message;
import twitter4j.Paging;
import twitter4j.ResponseList;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
@SuppressWarnings("serial")
public class TwitterMailServlet extends HttpServlet {
// 設定情報
private static final String SYSTEM_ADMIN_MAIL = "XXXXXXXXXXXXXXXXXXXX";
private static final String YOUR_MAIL = "XXXXXXXXXXXXXXXXXXX";
private static final String YOUR_MAIL_POST_ADDRESS = "";
private static final String TWITTER_ID = "XXXXXXXXXXXXX";
private static final String TWITTER_PW = "XXXXXXXXXXXXX";
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
String path = request.getRequestURI().substring(request.getContextPath().length());
if (path.equals("/tl") || path.equals("/reply")) {
DatastoreService dataService = DatastoreServiceFactory.getDatastoreService();
StringBuilder text = new StringBuilder();
Twitter twitter = new TwitterFactory().getInstance(TWITTER_ID, TWITTER_PW);
if (path.equals("/tl")) {
// 保存された最新のIDを取得
long lastId = -1;
try {
Entity entity = dataService.get(KeyFactory.createKey("twitter", "timeline"));
Object id = entity.getProperty("lastId");
if (id != null) {
lastId = (Long) id;
}
} catch (EntityNotFoundException e) {
}
try {
ResponseList<Status> timeline = twitter.getHomeTimeline();
for (Status status : timeline) {
if (lastId == status.getId()) {
break;
}
text.append(status.getUser().getScreenName() + ":" + status.getText() + "\n");
}
// 最新のIDを保存
long theLastId = timeline.get(0).getId();
Entity entity = new Entity("twitter", "timeline");
entity.setProperty("lastId", theLastId);
dataService.put(entity);
} catch (TwitterException e) {
response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");
response.getWriter().println("twitter error" + e.getMessage());
}
} else if (path.equals("/reply")) {
// 保存された最新のIDを取得
long lastId = -1;
try {
Entity entity = dataService.get(KeyFactory.createKey("twitter", "reply"));
Object id = entity.getProperty("lastId");
if (id != null) {
lastId = (Long) id;
}
} catch (EntityNotFoundException e) {
}
try {
ResponseList<Status> mentions = twitter.getMentions(new Paging(1, 8));
for (Status status : mentions) {
if (lastId == status.getId()) {
break;
}
text.append(status.getUser().getScreenName() + ":" + status.getText() + "\n");
}
// 最新のIDを保存
long theLastId = mentions.get(0).getId();
Entity entity = new Entity("twitter", "reply");
entity.setProperty("lastId", theLastId);
dataService.put(entity);
} catch (TwitterException e) {
throw new RuntimeException(e);
}
if (text.length() > 0) {
text.append("\n" + YOUR_MAIL_POST_ADDRESS);
}
}
if (text.length() > 0) {
Message message = new Message();
message.setSubject("Twitter Timeline");
message.setTo(YOUR_MAIL);
message.setSender(SYSTEM_ADMIN_MAIL);
message.setTextBody(text.toString());
MailServiceFactory.getMailService().send(message);
}
}
}
}

web.xml

<web-app>
<servlet>
<servlet-name>TwitterMail</servlet-name>
<servlet-class>ishigami.TwitterMailServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TwitterMail</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>

cronで、定期的に"/reply"をリクエストするように設定しとくと、
自分にメッセージが来たときに携帯にメールが来るので便利です。

自分用なので、荒削りでごめんなさい。

取り扱いについては、煮るなり焼くなり好きにしろですが、保証は一切いたしません。
使いたい方は自分でGAEのアカウントを取得して、上の方の定数に適当な値を入れてください。

見て分かる通り、ソースにIDとかパスワードとかべた書きなので、
そう言うのが気に入らない人は使わないようにお願いします:D