2015年9月1日火曜日

FlaskとPython3からGmailでメール送信(OAuth 2.0対応)

Webアプリ経由でGmailからメールを送ることにしたが、せっかくなのOAuth 2.0に対応させることにした。

ベースのソースコード下記にあるので、2つを組み合わせてそれを動かす。

1.の方はFlaskでOAuth2.0認証して、Google Driveのファイルを取得しているので、認証後に2.のGmailから送信するように組み合わせる。
2つ合体はサクッと。。。
まぁ。動きません。

ここからは試行錯誤なので、結論を書くと、
  • Payloadの"raw"はurlsafe_b64decodeを使いましょう。
  • Python3で使う場合は、ちゃんとStrからByteに変換してからBase64変換をかけましょう。
いじょ。

適当な入力フォームから送ると、

こんな結果が帰ってきます。



ソースはこんな感じ。
※GoogleDevelopersConsoleからAPI認証用Jsonファイルをダウンロードして、作業ディレクトリに"client_secrets.json"として保存してください。
※送信元のメールアドレスは、API認証用Jsonファイルと同じカウントでないとNG。
※ソースはBitbucketにおいてありますので、自己責任で使ってください。


ここからが試行錯誤した結果。
Pythonのバージョンなのか、日本語なのか、GmailのBase64フォーマットの変換でエラー。。。

  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/base64.py", line 62, in b64encode
    encoded = binascii.b2a_base64(s)[:-1]
TypeError: 'str' does not support the buffer interface
まぁ。GoogleのサンプルがPython2系向けで、3系からByteとStrの扱いが変わったので、再度サクッと。。。

直したとこだけ。
return {'raw': base64.b64encode(message.as_string())}

return {'raw': base64.b64encode(bytes(message.as_string(), 'UTF-8')).decode()}
これで、ASCIIは送れるようになったので。

キャプチャか何か。同じ同じ

日本語を送ろうとすると。。。。こんな感じで、エラーが。
Invalid value for ByteString: Q29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PSJ1dGY・・(略)・・・

GoogleAPIを使うためにググる。
stackoverflowの
によると、"urlsafe_b64encode"を使えよとのこと。
PHPの話みたいなので、Pythonだとこれかな。

base64.urlsafe_b64encode (s)バイト文字列 s を URL-safe アルファベットを利用してエンコードします。標準 base64 アルファベットに比べて、+ の替わりに - を、/ の替わりに _ を利用します。結果は = を含みます。
直すと、無事に日本語が送れました。
なかなか、”URL Safe” Base64に気づかず、結構はまったのでメモ。