Gmail API を使ってメールを操作(後編)
こんにちは、サポート部のまさよしです。
前回の Gmail API を使ってメールを操作(前編)では PowerBuilder から Gmail API を利用して Gmail のデータ取得を行いました。今回はメール送信 / 下書き作成を行う方法についてご紹介します。
事前準備と Authorization Code の生成
今回も前回作成した Google Cloud Platform のプロジェクトを利用しますので、事前準備に関しては前回のブログを確認してくださいね。ちなみに Access Token を取得するための Authorization Code の生成に関しては前回とほぼ同様で、以下がサンプルスクリプトです。
[コード取得] ボタン Clicked イベント
// 変数宣言 String ls_id String ls_redirect String ls_scope String ls_url String ls_null // Null セット SetNull( ls_null ) // クライアント ID と Redirect URI、Scope を設定 ls_id = "生成されたクライアント ID" ls_redirect = "urn:ietf:wg:oauth:2.0:oob" ls_scope = "https://www.googleapis.com/auth/gmail.send" // 認証リクエスト用 URL 作成 ls_url = "https://accounts.google.com/o/oauth2/v2/auth?response_type=code&client_id=" + ls_id + "&redirect_uri=" + ls_redirect + "&scope=" + ls_scope // URL を引数としてブラウザーをオープン ShellExecute( 0, "open", ls_url, ls_null, ls_null, 0 ) // 終了 Return
気づいた方もいるかもしれませんが、Gmail データを取得するだけの場合と違う部分は Scope の設定です。今回はメールが送信可能な権限が必要となるので、gmail.send を指定します。なお Access Token の取得もパラメーター設定の gmail.readonly が gmail.send へ変更する以外は同じなので割愛しますね。また、他にどのような権限があるかは Gmail API の Scope を確認してください。
PowerBuilder から Gmail でメール送信
ここまではスムーズに進みましたが、メールを送信するスクリプトを作成するにあたりかなり苦労しました。Web で「Gmail API メール送信」で検索するも JAVA や Python、PHP、JavaScript、GO といった言語では便利そうなクラスや有益な情報が見つかるのですが、実際どういった JSON 形式のデータを作成すればいいのか、どうやって作成した JSON 形式のデータを Gmail API に送信するのか、送信したらしたで文字化け~どんだけ~といったように PowerBuilder を含め他言語での実装方法が皆無だったので手探り感が半端なかったです。このお題を選んだことを後悔しながらも終わってみるとさほど難しくなく、あるある経験を久しぶりに体感しました。そのサンプルスクリプトは以下のとおりです。
※余談ですが「Gmail API メール送信」をキーワードに Google 検索すると検索結果として「Gmail API を使ってメールを操作(前編)」が上位にヒットします(2021/6/1時点)。ほのかにうれしみ。
[Gmail 送信] ボタン Clicked イベント
// 変数宣言 Integer li_rtn String ls_body Blob lb_body OAuthClient loa_client OauthRequest loa_request ResourceResponse lrr_response JsonParser ljp_parser HTTPClient lnv_httpclient JsonGenerator lnv_jsongenerator Long ll_root_object string ls_raw Blob lb_data String ls_Base64Str String ls_data String ls_url // OAuthClient 作成 loa_client = CREATE OAuthClient // 1. メール送信リクエスト URL をセットする loa_request.Method = "GET" loa_request.Url = "https://gmail.googleapis.com/gmail/v1/users/me/messages/send" loa_request.SetAccessToken( is_access_token ) li_rtn = loa_client.RequestResource( loa_request, lrr_response ) IF li_rtn <> 1 THEN // 破棄 DESTROY loa_client // 終了 Return END IF // 2.HTTPClient 作成 lnv_httpclient = CREATE HTTPClient // リクエストヘッダーを設定 lnv_httpclient.SetRequestHeader( "Content-type", "application/json" ) lnv_httpclient.SetRequestHeader( "Authorization", "Bearer " + is_access_token ) lnv_httpclient.SetRequestHeader( "Accept", "application/json" ) // 3.メールデータをセット(JSON 形式)する // JsonGenerator 作成 lnv_jsongenerator = CREATE JsonGenerator //ウィンドウからメールデータを取得 ls_raw = "to:" + sle_2.text + "~r~n" ls_raw = ls_raw + "subject:" + sle_3.text + "~r~n" ls_raw = ls_raw + "MIME-Version: 1.0" + "~r~n" ls_raw = ls_raw + "Content-Type: text/plain;charset=utf-8" + "~r~n" ls_raw = ls_raw + "Content-Transfer-Encoding: utf-8" + "~r~n" ls_raw = ls_raw + "~r~n" ls_raw = ls_raw + mle_1.text //Base64 エンコーダを使用するために CoderObject オブジェクトを生成 CoderObject lnv_CoderObject lnv_CoderObject = Create CoderObject // EncodingUTF8! を指定して Blob 型に変換する lb_data = Blob(ls_raw, EncodingUTF8!) // Base64 でエンコーディングする ls_Base64Str = lnv_CoderObject.Base64Encode(lb_data) // オブジェクトのルート項目(raw)にメールデータをセットする ll_root_object = lnv_jsongenerator.CreateJsonObject() lnv_jsongenerator.AddItemString(ll_root_object , "raw", ls_Base64Str ) // 作成した JSON 形式のデータを取得 ls_data = lnv_jsongenerator.GetJsonString() // 4. メール送信リクエストを Post ls_url = "https://gmail.googleapis.com/gmail/v1/users/me/messages/send" li_rtn = lnv_httpclient.SendRequest( "POST", ls_url, ls_data ) IF li_rtn <> 1 OR lnv_httpclient.GetResponseStatusCode() <> 200 THEN // メッセージ MessageBox( "エラー", String( lnv_httpclient.GetResponseStatusCode() ), StopSign! ) END IF // 破棄 DESTROY ljp_parser DESTROY lnv_httpclient DESTROY lnv_jsongenerator // メッセージ MessageBox( "完了", "Gmail 送信が終了しました" ) return 0
ポイントとしては 3 点。まず MIME タイプのデータを生成後、Base64 にエンコーディングします。そして JSON 形式のデータとしてオブジェクトのルート項目(raw)にセットします。その後はメール送信リクエストにデータを送ることで Gmail API を利用してメール送信が行われます。
思ったよりもコーディング量は少なかったです。いまさらですが Gmail API のリファレンスページの右側に Try this API という便利なパーツがあるじゃあーりませんか。Request parameters や Request body のひな型がありぞれぞれを設定し [EXECUTE] ボタンをクリックすることで実行&結果が分かりますので、これを利用すればコーディングも捗りますよ!不覚にも今回やっと気づきました。。。
アプリケーションの実行
それでは締めに今回作成したアプリケーションを実行してみましょう。画面イメージは以下のようになっています。
最初に [コード取得] ボタンをクリックするとデフォルト設定されているブラウザーが起動し「Google にログイン(または Google アカウントの選択)」画面が表示されますので、送信する Gmail のアカウントでログインしてください。
ログインすると “(作成したプロジェクト) が Google アカウントへのアクセスをリクエストしています” と表示されます。 リクエストされた Gmail のアカウントやプロジェクトに問題がないことを確認後、[許可] ボタンをクリックします。
ログイン画面に遷移して画面上にコードが表示されるのでコピーしておきましょう。これが Authorization Code となります。PowerBuilder アプリケーションに戻って、コピーしたコードを Authorization Code のシングルラインエディットに貼り付けて [Access Token 取得] ボタンをクリックします。成功すると「Access Token を取得しました」のメッセージが表示されます。
最後に [Gmail 送信] ボタンをクリックします。成功すると Gmail の受信トレイに送信したメールが受信されます。
無事 Gmail でメール送信ができました!
補足(下書き作成)
今回メール送信について説明をしましたが、補足情報として下書き作成について説明します。メール作成は下書きも送信も同じだろうと予想しつつ、宛先が意図したメールアドレスで設定されているか本文が文字化けしていないかなどを確認できるので、まずはメールの下書きから着手するのもアリかと思います。なお、メール送信と違う部分にフォーカスを当てて説明しますね。
まず Scope の設定です。メール送信では gmail.send でしたが、下書きの場合は gmail.compose になります。gmail.compose は下書きを作成、読み取り、更新、および削除でき下書きの送信も行える権限となります。
Scope の設定
ls_scope = "https://www.googleapis.com/auth/gmail.compose"
次にメール送信リクエスト URL です。メール送信では “https://gmail.googleapis.com/gmail/v1/users/{userId}/messages/send” をセットしていましたが、下書きの場合は “https://www.googleapis.com/gmail/v1/users/{userId}/drafts/” になります。前回も説明しましたが、{userId} はアカウントの ID を指定するのですが今回は認証されたアカウントなので me を指定しています。なお、メール送信リクエストを Post する URL も同様です。
メール送信リクエスト URL の設定
loa_request.Url = "https://gmail.googleapis.com/gmail/v1/users/me/drafts/" ・ ・ ・ ls_url = "https://gmail.googleapis.com/gmail/v1/users/me/drafts/"
最後にメールデータをセットする JSON 形式です。メール送信ではオブジェクトのルート項目(raw)にセットしますが、下書きの場合はオブジェクトのルート項目(message)の下に子項目(raw)を作成してそこにメールデータをセットします。メールデータはメール送信同様 MIME タイプのデータを生成後、Base64 にエンコーディングしてくださいね。
メールデータのセット(JSON 形式)
ll_head_array = lnv_jsongenerator.AddItemObject( ll_root_object, "message" ) lnv_jsongenerator.AddItemString(ll_head_array , "raw", ls_Base64Str )
いかがでしょうか。下書きの作成もメール送信時の処理とあまり変わりませんね。是非試してみてください!
まとめ
できてしまえば Gmail のデータ取得よりも簡単に PowerBuilder からメール送信が行えました。
人間が手作業でメール作成や送信を行うと宛先のミスやファイルの添付忘れなど、どうしてもヒューマンエラーが起きてしまいます。そこで、毎月同じメール作成 / 送信作業をする必要がある場合、例えばテーブル内で送信する宛先リストや表題、本文を保存しておき、メール送信するバッチプログラムを作成してタスクスケジューラで定期的にそのバッチを実行することで、自動でメール送信することができミスを防ぎつつ毎月の作業の負担軽減も可能かと思います。
もちろん、宛先リストや表題、本文の取得先をテーブルではなく Google スプレッドシートにすることも検討できるかもしれません。PowerBuilder から Google スプレッドシートを操作したい場合は Google Sheets API を使ってスプレッドシートを操作 を参考にしてくださいね。
以上、まさよしでした。