Motivation
au携帯をpovoにしてキャリアメールが使えなくなり、長女の公文終了時に来るメールをキャリアメールに転送してプッシュ通知してたのが、通常メールだと気付かず迎えを待たせてしまう。
gmailのフィルタで重要にタグ付けすれば、iPhoneでプッシュ通知できるはずなのだが、どう頑張っても私のiPhoneは通知してくれないので、gmailからメール転送してtwilioからsmsを送るようにした忘備録
こんなことせずとも海外キャリアだとemailからsmsに転送してくれるんだけど。。。
yahooメールとかに転送すればいいのですが。留守電は自宅の固定電話に転送するようにした。
やったこと
基本は下記twilioサイトのとおりなのだが、github上にあるソースコードがpython2用のものなので、直し直し動かした。
Send And Receive SMS Messages via Email with Twilio and SendGrid
ドメイン取得
gmailからのメール転送をトリガにSendGridのInbound Parse Webhookでheroku上のweb apiを叩くためにメールを受けるドメインとる必要があり、下記サイトを参考にfreenomというところでタダでドメイン取ろうとしたが、全然登録できないので、あきらめてAWSのRoute 53で年間9ドルでドメイン取得、DNSもRoute 53を使った。時間を無駄にしたので、やっぱりタダより高いものは無い。
SendGrid 新人成長記 第六回 Domain Authentication: メールの到達率を高めるために
DNS登録
Route 53でドメイン取得したら、上記サイトを参考にsendgridのSettings/Sender Authenticationにドメインを登録
SendGridのホストを新しいドメインのホストで引けるようにDNS(Route 53)に指示されるがままCNAMEを設定、新ドメイン宛のメールもmx.sendgrid.netが受けるようMXレコードも設定
DNSの反映は10分以上かかった。
twilioで電話番号購入
(2022/10/5追記)
twilioが8末で個人利用できなくなったので、twilioからvonageに移行してみたで、vonageに移行してます。
twilioでSMS送信元となる電話番号を購入する。日本の番号ではSMS送れないようなのでUSの番号を買う。番号維持料は157円/月くらい。
買った電話番号をProgrammable Messaging/Messageing serviceに紐づける。
heroku上にWebアプリ構築
(2022/9/11追記)
herokuのfree serviceは11末で廃止になるのでheroku上のweb serviceをrenderに移行してみた。で、render.comに移行してます。
前記twilioのサイトを参考に
$git clone https://github.com/jpf/sms-via-email.git
$cd sms-via-email
virtual env環境作る
$python3 -m venv venv
$source venv/bin/activate
git初期化
(venv)$git init
herokuにログインして、Webサイトを作成。web browserにパスワード入力求められる。
(venv)$heroku login
(venv)$heroku create
Creating app... done, ⬢ xxxxxxx-xxxxx-xxxxx
https://xxxxxx-xxxxx-xxxxx.herokuapp.com/ | https://git.heroku.com/xxxxxxx-xxxxx-xxxxx.git
上記URL+/handle-emailを後述sendgridのSettings/Inbound Parseに登録する。
(venv)$heroku git:remote -a xxxxxxx-xxxxx-xxxxx
twilioのDashboardに出てくるACCOUNT SID/AUTH TOKENを環境変数として設定
(venv)$heroku config:set TWILIO_ACCOUNT_SID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
(venv)$heroku config:set TWILIO_AUTH_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
前述の通りgit上のapp.pyはpython2で書かれている、twilioのlibraryが更新されているので、python3で動くように修正(下記diff参照)
app.pyの中で勝手にtwilioのweb api叩いてくれるので、メールをSMSに転送するだけなら前述以上のtwilioサイト上の設定はいらない。
3,4c3
< import configparser
< from urllib.parse import urlparse, parse_qs
---
> import ConfigParser
9c8
< from twilio.rest import Client
---
> from twilio.rest import TwilioRestClient
24c23
< user_list = configparser.ConfigParser()
---
> user_list = ConfigParser.ConfigParser()
34c33
< twilio_api = Client(konf.twilio_account_sid, konf.twilio_auth_token)
---
> twilio_api = TwilioRestClient()
93c92
< except Exception as e:
---
> except Exception, e:
108c107
< except Exception as e:
---
> except Exception, e:
155c154
< print(str(address_book))
---
> print str(address_book)
186c185
< except InvalidInput as e:
---
> except InvalidInput, e:
206,213d204
< warn("envelope: "+str(envelope))
< warn("request.form[to]: "+str(request.form['to']))
< warn("request.form[from]: "+str(request.form['from']))
< warn("request.form[text]: "+str(lines[0]))
< if envelope['to'][0] != request.form['to']:
< email_from = 'zzzzzzz@gmail.com'
< else:
< email_from = envelope['from']
215,216c206,207
< 'to': email_to_phone(envelope['to'][0]),
< 'from_': lookup.phone_for_email(email_from),
---
> 'to': email_to_phone(request.form['to']),
> 'from_': lookup.phone_for_email(envelope['from']),
219c210
< except InvalidInput as e:
---
> except InvalidInput, e:
223d213
< warn("sms: "+str(sms))
227,228c217,218
< print("oh no")
< print(str(e))
---
> print "oh no"
> print str(e)
237c227
< print("in debug mode")
---
> print "in debug mode"
206~216行目あたりは、転送かけると、ヘッダとエンベロープのfrom/toが異なるので、違った場合は転送元(zzzzzzz@gmail)に紐付けた番号からsms送るように修正
requirement.txtも同様に修正
10c10
< phonenumbers
---
> phonenumbers==6.0.0
15,16c15,17
< twilio
< unittest2
---
> twilio==3.6.6
> unittest2==0.5.1
> wsgiref==0.1.2
address-book.cfgを作成
[users]
+8180xxxxxxxx: 8180xxxxxxxx@mail.yyyyyyy.de
+1571wwwwwww: zzzzzz@gmail.com
herokuのgitにpush
(venv)$git status
(venv)$git add -A
(venv)$git commit -m "hoge"
(venv)$git remote show heroku
(venv)$git push heroku master
SendGridのInbound Parse Webhook設定
SendGrid 新人成長記 第七回 Inbound Parse Webhookを用いてメールを受信する
上記サイトを参考にSendGridのSettings/Inbound Parseで新ドメイン宛のメールを受信したら前述heroku上のweb api https://xxxxxx-xxxxx-xxxxx.herokuapp.com/handle-email を叩くように設定する。host名にmailがついてますが、再登録時につけるとエラーになったのでmailなしドメイン名だけで登録し直してます。
メール転送
gmail(zzzzzzz@gmail.com)から8180xxxxxxxx@mail.yyyyyyy.deにメールを送ったときのheroku logs
抜粋、ちゃんとtwilio上で購入した+1571wwwwwwwからSMSきた。
2021-04-10T06:55:57.204402+00:00 app[web.1]: WARNING:root:['テスト\r\n']
2021-04-10T06:55:57.216212+00:00 app[web.1]: WARNING:root:{'to': '+8180xxxxxxxx', 'from_': '+1571wwwwwww', 'body': 'テスト\r\n'}
2021-04-10T06:55:57.920606+00:00 heroku[router]: at=info method=POST path="/handle-email" host=xxxxxxx-xxxxx-xxxxx.herokuapp.com request_id=ee5d9529-4778-40aa-9e35-71ea0269b839 fwd="167.89.119.77" dyno=web.1 connect=1ms service=1186ms status=200 bytes=192 protocol=https
その後、Google Voiceの番号を持ってたので、そちら宛に送るように設定した。Google VoiceはiPhoneでちゃんとプッシュ通知してくれる。。。
固定費 約250300円/月(番号維持費、ドメイン月割り、DNSホスト)、DNS queryとSMSの従量課金がどのくらいになるか~~、また後日~~
USの番号宛だとSMS1円/通、日本宛だと8円/通
https://www.twilio.com/sms/pricing/us
https://www.twilio.com/sms/pricing/jp