GAEからim.kayac.comを使ってGmailの新着をPush通知
Gmailの新着がAtomフィードとして提供されていることを知ったので作ってみました。Push通知を受けとるアプリもiTunesStoreで販売されていますが、メールの内容をPush通知させるということは外部のサーバにメールの内容(一部?)を送信しているということになるのでそういう心配を回避する為という理由もあります。
Basic認証を使用していますが、httpsのURLなので暗号化経路となり、通信経路上でパスワードが漏洩することはないです。
gdispatch.pyを使っていますが、今回はその機能のほとんどを使用していません(^^;)
- Life is beautiful: Google App Engine入門:実行効率を犠牲にせずに開発効率だけを上げるテクニック
- GitHub - snakajima/gdispatch: URL routing mechanism for webapp for Google App Engine Developer
# coding: utf-8 import logging from google.appengine.ext import webapp from google.appengine.ext import db from google.appengine.api import urlfetch import gdispatch import base64 import time import urllib import yaml from xml.etree import ElementTree as etree class MessageTime(db.Model): time = db.FloatProperty() def latesttime(id, password): auth = base64.encodestring('%s:%s' % (id,password))[:-1] headers = {'Authorization': 'Basic %s' % auth} url = 'https://mail.google.com/mail/feed/atom/' res = urlfetch.fetch(url, '', urlfetch.GET, headers) dom = etree.fromstring(res.content) namespace = 'http://purl.org/atom/ns#' items = dom.findall('.//{%s}entry/{%s}modified' % (namespace,namespace)) if len(items) < 1: return None latest = max(map( lambda x: time.mktime(time.strptime(x.text, '%Y-%m-%dT%H:%M:%SZ')), items)) return latest def notifykayac(kayacid,message): urlfetch.fetch('http://im.kayac.com/api/post/%s' % kayacid, 'message=%s' % message, urlfetch.POST, {}) gdispatch.route(lambda: ('/.*', MainHandler)) class MainHandler(webapp.RequestHandler): @gdispatch.kwargs def get(self): account = yaml.load(open('gmailaccount.yaml')) for ac in account: latest = latesttime(ac['id'], ac['password']) if latest is None: self.response.out.write('no mail') continue keyname = 'latest_%s' % ac['id'] t = MessageTime.get_by_key_name(keyname) if t is None: t = MessageTime(key_name=keyname) t.time = 0.0 if t.time < latest: notifykayac(ac['kayacid'],urllib.quote(ac['message'].encode('utf-8'))) self.response.out.write(ac['message']) t.time = latest t.put() def main(): gdispatch.run() if __name__ == '__main__': main()
設定ファイル(gmailaccount.yaml)は複数アカウントに対応しています。
--- - id: GmailAccount1 password: GmailPassword1 kayacid: KayacId1 message: 'メールがきたようだ' - id: GmailAccount2 password: GmailPassword2 kayacid: KayacId1 message: 'メールチェックだ'
[参考]