前提条件:http://im.kayac.com/
ちょっと引っ越す予定なので自宅サーバーを止めていて、tiarraが動いていない。
今までtiarraからim.kayac.comでiPhoneに通知させていたTwitterのリプライなどが来なくなってしまって寂しいので、Twitterの情報はGoogleAppEngineを使ってAPI経由で情報を取得して通知するようにしてみた。
#!/usr/bin/env python # -*- coding: utf-8 -*- import base64 import logging import urllib import yaml from django.utils import simplejson from google.appengine.api import memcache from google.appengine.api import urlfetch from google.appengine.ext import webapp from google.appengine.ext.webapp import util # 以下のような config.yaml を用意しておく # --- # username: sugyan # password: ******** # search_words: # - 検索したいワード。 # - ORで検索するので # - 複数指定でもおk config = yaml.load(open('config.yaml')) def get_fetch_result(url): auth_header = { 'Authorization' : 'Basic ' + base64.b64encode( '%s:%s' % (config['username'], config['password']) ) } response = urlfetch.fetch( url = url, headers = auth_header, ) if response.status_code == 200: return simplejson.loads(response.content) else: logging.error(response.content) return [] def post_im(message): logging.debug(message) response = urlfetch.fetch( url = 'http://im.kayac.com/api/post/sugyan', method = urlfetch.POST, payload = 'message=%s' % message.encode('utf-8'), ) if response.status_code == 200: logging.debug(response.content) return simplejson.loads(response.content)['result'] else: logging.error(response.content) class Mentions(webapp.RequestHandler): def get(self): since_id = memcache.get('reply') if since_id: query = 'since_id=%s' % since_id else: query = '' result = get_fetch_result( 'http://twitter.com/statuses/mentions.json?%s' % query) if len(result) > 0: memcache.set('reply', result[0]['id']) for status in result: message = '@%s: %s' % (status['user']['screen_name'], status['text']) post_result = post_im(message) logging.debug(post_result) class DirectMessage(webapp.RequestHandler): def get(self): since_id = memcache.get('message') if since_id: query = 'since_id=%s' % since_id else: query = '' result = get_fetch_result( 'http://twitter.com/direct_messages.json?%s' % query) if len(result) > 0: memcache.set('message', result[0]['id']) for status in result: logging.debug(status) message = '[DM] @%s: %s' % (status['sender']['screen_name'], status['text']) post_result = post_im(message) logging.debug(post_result) class Search(webapp.RequestHandler): def get(self): parameter = { 'q' : ' OR '.join([x.encode('utf-8') for x in config['search_words']]), } since_id = memcache.get('search') if since_id: parameter['since_id'] = since_id result = get_fetch_result( 'http://search.twitter.com/search.json?%s' % urllib.urlencode(parameter) )['results'] if len(result) > 0: memcache.set('search', result[0]['id']) for status in result: message = '@%s: %s' % (status['from_user'], status['text']) post_result = post_im(message) logging.debug(post_result) def main(): logging.getLogger().setLevel(logging.DEBUG) application = webapp.WSGIApplication([ ('/mentions', Mentions), ('/message', DirectMessage), ('/search', Search), ], debug=True) util.run_wsgi_app(application) if __name__ == '__main__': main()
app.yamlではいちおうadmin指定だけしておく
application: ******** version: 1 runtime: python api_version: 1 handlers: - url: .* script: main.py login: admin
で、cronでそれぞれ叩く
cron: - description: mentions url: /mentions schedule: every 1 minutes - description: direct messages url: /message schedule: every 2 minutes - description: search url: /search schedule: every 5 minutes
おしまい。一応since_idをmemcacheで記録しながら使っているので重複はない、はず。初回起動時には一気にきてしまうけどw