Gmail のドラフト（下書き）大量一括作成スクリプトをphpで作成してみた

#背景

とある同窓会の運営を手伝っています。その会員の住所、電話番号等の情報照会のため、個別に多数のメールを送ることになりました。文面はほとんど共通、メール本文内の個人情報とメールの宛先が違うだけの大量のメール送信、ということで、Excel(CSV)形式の名簿情報からメール文面生成送信の自動化を試みることにしました。

メルマガ配信サービス、SendGrid のようなメール配送サービスを使えばすぐにできるのですが、

* 今回の会員の元データはCSV形式のファイルだが、将来はデータベースと直接連携したい
* 自分のGmailアカウントから送信したかった
* 送信する前に、それぞれにふさわしいひとことを手動で書き添えたかった
* Gmail API を使ってみたかった

このような理由から、会員情報からGmailドラフト（下書き）作成までを自動化し、その後必要ならば一言書き添えて送信ボタン押下は手動で、ということにしました。

言語は、自分が慣れているphpにしました。ここでは、Gmail APIを使ってのドラフト作成について主に書きます。CSV形式のデータ読み込み、テンプレート内の文字列置換による文面作成は、単にphp 機能の利用方法ということで特筆すべきことはないので、共有するソースコードを直接参照ください。

#phpでのGmail ドラフト(下書き)作成手順

次の手順で行いました。

1. Gmail API の開発環境構築とサンプル稼働
2. Gmail ドラフト作成のコードをサンプルに追加実装

### Gmail API 開発環境作成とサンプル稼働

公式ドキュメント"[PHP Quickstart](https://developers.google.com/gmail/api/quickstart/php)" に構築手順とサンプルの記載があります。「5分で」phpでGmail API が使えるようになる、と書いてありますので、挑戦してみてください（笑

また、"[Gmail APIの設定とサンプルプログラムを動かすまで](https://qiita.com/wtanabe/items/ead266f065bdcb14a0c6)" こちらの記事も参考になりました。やることを箇条書きにすると、以下のようになります.

1. Google アカウントの準備
2. 該当Google アカウントでGmail APIを使えるようにする
[こちら](https://console.developers.google.com/flows/enableapi?apiid=gmail)より、「プロジェクト作成」「Gmail API 有効化」「認証情報の作成とダウンロード」を行います.
3. [quickstart](https://github.com/gsuitedevs/php-samples/tree/master/gmail/quickstart)のサンプルを動かしてみる 

正しく準備できていれば、quickstart のサンプルは、該当アカウントのラベル一覧を出力してくれます。

## Gmail ドラフト作成のコードをサンプルに追加実装

さて、ここからが本番です。quickstart のサンプルコードに対し最低限の改変
を施した、Gmailドラフト作成のシンプルなコードを作成します。

準備できたquickstart のサンプルコードに対し、以下を行います。

1. スコープ設定
2. ドラフト作成のコード実装
3. 認証情報の再取得

### スコープ設定

[パーミッション権限の範囲（スコープ)](https://developers.google.com/gmail/api/auth/scopes?hl=ja)を指定する必要があります。Gmailドラフト作成には"modify" のスコープが必要になりますので、quickstart の以下の部分を変更します。

```quickstart.php
...
//$client->setScopes(Google_Service_Gmail::GMAIL_READONLY);
    $client->setScopes(Google_Service_Gmail::GMAIL_MODIFY);
....
```

###ドラフト作成のコード実装

以下のコードをquickstart に追加します。

1. MINE フォーマットのメール本体のテキスト作成
2. Gmail API でGmail メッセージ作成
3. 作成したメッセージにてドラフト作成

```php5

// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Gmail($client);

/*========= Creating MimeMessage ========*/
$email = "To: "   . "receiver@hogehoge.com"    . "\n";
$email.= "Cc: "   . "cc_receiver@hogehoge.com" . "\n";
$email.= "Subject: " . mb_encode_mimeheader("SUBJECT/タイトル", 'utf-8') . "\n";
$email.= "\n";
$bodyText = <<<EOF
"Messsage body / メール本文"
EOF;
$email.= $bodyText;

/*========= Creating Gmail Message ========*/
$message = new Google_Service_Gmail_Message();
// base64url encode the string
//   see http://en.wikipedia.org/wiki/Base64#Implementations_and_history
$email = strtr(base64_encode($email), array('+' => '-', '/' => '_'));
$message->setRaw($email);

/*========= Creating Draft ========*/
$draft = new Google_Service_Gmail_Draft();
$draft->setMessage($message);
try {
  $draft = $service->users_drafts->create('me', $draft);
  print 'Draft ID: ' . $draft->getId();
} catch (Exception $e) {
    print 'An error occurred: ' . $e->getMessage();
}
```

作成された[全ソースコード](https://github.com/rochefort8/gmail_draft_creator/blob/master/create_gmail_draft_example.php) はこちらのリンクにあります。

###認証情報の再取得

実はここ、はまりました。上記にて作成したコードを実行すると、スコープを適切に設定をしていない旨を示す「insufficientPermissions」というレスポンスが返ってきます。

quickstart 実行時にローカルに保存された認証情報は、read only のパーミッションで取得されているので、これをいったん削除し、再度再作成する必要があります。

```
$ rm -rf credentials.json 
$ php create_gmail_draft_example.php
Open the following link in your browser:
https://accounts.google.com/o/oauth2/auth?response_type=code&access_type=offline&client_id=192634225054-o67kf05ibjs92umoe52ouk8154pv6n6a.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&state&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgmail.modify&approval_prompt=auto
Enter verification code: 
```

このURL をブラウザ等で開き、再度認証コードを入力すると、新しい認証情報ファイルがローカルに作されます。

作成されたドラフトです。

<img width="750" alt="draft.png" src="https://qiita-image-store.s3.amazonaws.com/0/211499/eb709c8a-7b0b-a13a-963e-6d1f4361c983.png">

#ドラフト一括作成スクリプト

上記で説明したGmailドラフト作成のコードを関数化し、個人情報の一覧からドラフトを自動作成するスクリプトを作成しました。処理は以下のようなものです。

1. CSV スタイルの個人情報を読み込む
2. 本文テンプレート内のマクロをメールアドレス、住所、電話番号などに変換
3. 作成された本文のGmailドラフトを作成

###テンプレート
メールの本文となるテンプレートを用意します。コードで置き換える個人情報は"name", "address" といった一意の文字列にします。

```text
name 様

XXX のYYYです。ご無沙汰しておりますが、如何お過ごしでしょうか
.....
連絡先確認のご連絡です。
---------------------------
名前          : name
住所          : address
電話番号1     : phone1
電話番号2     : phone2
メールアドレス: email
---------------------------

ご確認の上、訂正があればご連絡頂けますと幸いです。
何卒よろしくお願い致します。

署名
```

###個人情報一覧
適当に加工して、CSV 形式に変換しておきます。

```csv
1,山田,太朗,ヤマダ,タロウ,男,807-1261,福岡県北九州市八幡西区木屋瀬XX-YY-ZZ,090-1xxx-yyyy,taro.yamada@hoge.com
2,田中,花子,タナカ,ハナコ,女,276-0022,千葉県八千代市上高野XXXX-YY,080-2xxx-yyyy,hanako.tanaka@hoge.it
3,佐藤,一郎,サトウ,イチロウ,男,141-6010,東京都品川区大崎ＴｈｉｎｋＰａｒｋＴｏｗｅｒ10F,090-3xxx-yyyy,ichiro.sato@hoge.fr
```

###全ソースコード
[こちら](https://github.com/rochefort8/gmail_draft_creator/blob/master/create_gmail_draft_from_csv.php)より参照ください。

### 実行
作成したツールを実行すると、名簿に登録された個々の情報ごとに、文面とメールのドラフトが順に作成されていきます。

実際の同窓生へのメールは100通余りを一気に作成しました。作成したドラフトは個人情報を含んでいるので、スクリーンショットはお見せできませんが、想像はつくでしょう。テンプレートに個人情報をちまちまとExcel ファイルからコピペして作成するのとは、言うまでもなく、雲泥の差です。

# Github リポジトリ
本文にて紹介したソースコードは、以下にて公開しています。

https://github.com/rochefort8/gmail_draft_creator

#参考文献
* [Gmail API の公式ドキュメント](https://developers.google.com/gmail/api/)
* [Gmail API PHP quickstart sample](https://github.com/gsuitedevs/php-samples/tree/master/gmail/quickstart)