simフリー版ドコモメールの着信をIMAP4 IDLE→IFTTT→PushBullet でプッシュ通知
ドコモ回線で SIMフリー端末(Android)へ変更すると、ドコモメール(spモードメール)の着信が特殊SMSで通知されなくなる
simフリー端末用の公式ドコモメールアプリは、15分間隔でのポーリング受信
連絡は他のツールに移りつつあるため、あまり支障はないが、実験的メモです
注意
キャリア端末での着信通知は SMSで起動するため、Android端末が Doze 状態でも通知されますが、今回の方法は Androidのプッシュを最終的に利用しているため、Dozeの影響を受けます
着信トリガーで、SMSや電話着信を起動すれば、リアルタイム性を保つことは可能かと思います(今回はそこまで突っ込んでません)
試したけどNGだった事
- ドコモメール設定(spモード接続)から user-agentを iPhone へ変更して、着信お知らせメール(SMS)をオンにしてみる → 通常SMSが到着した形跡なし
- ドコモ公式端末から DcmWapPushHelper.apk と jp.nttdocomo.carriermail-2.apk を移植 → jp.nttdocomo.carriermail-2.apk(ドコモメール)は、起動と強制終了を繰り返して利用できず、DcmWapPushHelper.apk + ドコモメール(simフリー用)は、プッシュの反応なし
ということで、IMAP4 の IDLEを用いて、メール着信イベントを取得するしかないという事になりました
IMAP4 IDLE は早い話、セッションをつないだままにしてボックスに変化があったらサーバからクライアントへメッセージを送る --- という方法なため、端末アプリで IMAP4 IDLE を用いると、常にセッションを張り続ける→電池を消耗する という事は容易に想像されます。
今回は、常時起動したサーバ(今回は手持ちのVPS)で、IMAP4 IDLEを監視して、メール受信イベント → IFTTT WebHook → PushBullet で端末に「何か来たよ」の通知を行う事としました
メール受信イベント以下は、Gmailへ通知を送るなどでも同じです
※ imap.select('inbox') で受信フォルダを選択しています
それ以外のフォルダの通知を受ける場合、他のを指定する必要があります
日本語の場合 utf7でエンコード?(未確認)
Pyhotnソース(終了は ctrl + d) 同じ場所に log ディレクトリを作成してください
- import datetime
- import imaplib
- import httplib2
- import urllib
- import time
- import signal
- import os
- signal.signal(signal.SIGINT, signal.SIG_DFL) # ctrl + d
- # imap4へ接続して imapオブジェクトを返す(失敗は False)
- def connect_iamp_server():
- imap_server = 'imap.spmode.ne.jp'
- imap_port = '993'
- imap_user = '******@docomo.ne.jp'
- imap_pass = '******'
- try:
- imap = imaplib.IMAP4_SSL(imap_server,imap_port)
- sock = imap.socket()
- # sock.settimeout(60 * 15) # NATタイマーにかかる場合タイムアウトを設定
- imap.login(imap_user,imap_pass)
- except imaplib.IMAP4_SSL.error as e:
- print(e)
- return False
- else:
- return imap
- # Http GET or POST
- def httpExecute(url, user = '', passwd = '', postData = ''):
- for key in postData:
- if postData[key] == None:
- postData[key] = ''
- http = httplib2.Http(timeout=8)
- if user != '':
- http.add_credentials(user, passwd)
- if postData != '':
- try:
- content = http.request(url,
- method="POST",
- headers={'Content-type': 'application/x-www-form-urlencoded'},
- body=urllib.parse.urlencode(postData) )[1]
- return content.decode()
- except httplib2.ServerNotFoundError:
- return ''
- else:
- try:
- (resp, content) = http.request(url, 'GET')
- return content.decode()
- except httplib2.ServerNotFoundError:
- return ''
- def printtime(s):
- now = datetime.datetime.now()
- writeLn = now.strftime("%Y-%m-%d %H:%M:%S ") + s
- print(writeLn)
- logFile = os.path.dirname(os.path.abspath(__file__)) + os.sep + "log" + os.sep + now.strftime("%Y%m%d") + ".log"
- with open(logFile, mode='a') as f:
- f.write(writeLn + '\n')
- def main():
- while True:
- mailExists = False
- imap = connect_iamp_server()
- if imap != False:
- printtime('M: Connected IMAP4 Host')
- imap.select('inbox')
- imap_idletag = imap._new_tag()
- printtime('C: %s IDLE'%(imap_idletag.decode('utf-8')))
- imap.send(b'%s IDLE\r\n'%(imap_idletag))
- imap_line = imap.readline().strip().decode('utf-8')
- printtime('S: ' + imap_line)
- if imap_line == '+ .':
- try:
- while True:
- imap_line = imap.readline().strip().decode('utf-8')
- printtime('S: ' + imap_line)
- if imap_line.startswith('* BYE ') or (len(imap_line) == 0):
- mailExists = False
- break
- if imap_line.endswith('EXISTS'):
- mailExists = True
- printtime('C: DONE')
- imap.send(b'DONE\r\n')
- imap_line = imap.readline().strip().decode('utf-8')
- printtime('S: ' + imap_line)
- break
- # 上記以外のコマンドはループ(IMAP4を操作してもレスポンスが返ってくる)
- except:
- mailExists = False
- pass
- finally:
- # imap.close() # タイムアウト時にエラーが発生
- imap.logout()
- printtime('M: Disconnect IMAP4 Host')
- if mailExists:
- printtime('M: mail Exists')
- # メール到着処理
- postData = {'value1': 'ドコモメール'}
- httpresponse = httpExecute('https://maker.ifttt.com/trigger/*******/with/key/*******', '', '', postData)
- printtime('M: IFTTT > ' + httpresponse)
- else:
- # 接続NG -> 60秒待ち
- time.sleep(60)
- if __name__ == '__main__':
- main()
ドコモの仕様書どおり IDLE 30分で BYE切断になるが、NATタイマーがそれ以下の場合、タイムアウトを設定する(コメントアウトを外す)
コマンドラインでうまくいったら、pythonをデーモン化するメモ あたりでデーモンとして監視させればOK
参考文献
imap4libでpush通知と遊んでみる --- デーモン移行時、改行コードに注意
コメント