大量メール配信を行った際に、その中には数通のエラーメールが入っているものでしょう。効率的なメール配信のためには、そうしたエラーになるメールアドレスは除外していく必要があります。あまりエラーが多いと、サーバ側にスパムメールだと判定される可能性もあるでしょう。
Customers Mail CloudではWebhookを使ってメール配信結果を取得できる仕組みがあります。今回はこれを使って、配信結果をGoogleスプレッドシート内に蓄積してみたいと思います。
Webhook APIについて
Webhookは一般的なWeb APIと異なり、クラウドサービス側からユーザの指定したURLを呼び出す仕組みです。Web APIはユーザ側からのアクションが必要になるので、情報を更新するためには定期的にアクセスしなければなりません。配信中はいいですが、何も配信していない時にもWeb API呼び出しが発生するため、サーバ側の負荷も大きくなります。
Webhookを使うと、サーバ側から呼ばれるので、何もイベントが起きていなければ負荷も発生しません。そしてメール配信中だけ結果が送られてくるので、それを処理すればいいだけです。
Webhook APIの設定
Webhook APIはAPI設定で、イベントの設定でURL指定します。バージョンは、今回のコードの場合はversion 2を指定します。
コードについて
今回はデータをGoogleスプレッドシート内に蓄積しています。GoogleスプレッドシートからGoogle Apps Scriptを作成し、Webアプリケーションとして公開します。
WebhookではPOSTメソッドを使って呼び出されるので、doPost(Google Apps Script用のPOSTメソッド呼び出し時にコールされる関数)を定義します。リクエスト後に何らかのデータを返す必要がありますが、今回は空のJSONオブジェクトとしています。
function doPost(e) { // 処理を書く部分 const output = ContentService.createTextOutput(); output.setMimeType(ContentService.MimeType.JSON); output.setContent(JSON.stringify({})); return output; }
では実際の処理(上記 処理を書く部分
以下の内容)です。まずGoogleスプレッドシートオブジェクトを用意します。 row
は一番下の行に1を加えることで、データを書き込む位置を指定しています。
const spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); const sheet = spreadsheet.getSheetByName('Errors'); const row = sheet.getLastRow() + 1; let index = row;
次にWebhookで送られてくるデータを取得します。
const params = JSON.parse(e.postData.contents); const ary = params.event[params.event_type];
結果はこの ary
の中に配列で入っています。それらを順番に書き出していきます。
for (let options of ary) { sheet.getRange(row, 1).setValue(params.event_type); sheet.getRange(row, 2).setValue(params.server_composition); sheet.getRange(row, 3).setValue(options.status); sheet.getRange(index, 4).setValue(options.reason); sheet.getRange(index, 5).setValue(options.sourceIp); sheet.getRange(index, 6).setValue(options.returnPath); sheet.getRange(index, 7).setValue(options.created); sheet.getRange(index, 8).setValue(options.subject); sheet.getRange(index, 9).setValue(options.apiData); sheet.getRange(index, 10).setValue(options.messageId); sheet.getRange(index, 11).setValue(options.from); sheet.getRange(index, 12).setValue(options.to); sheet.getRange(index, 13).setValue(options.senderIp); index++; }
実際のデータ構造は 共通仕様 | Customers Mail Cloud を参照してください。
コード全体
全体のコードは次のようになります。
function doPost(e) { const params = JSON.parse(e.postData.contents); const spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); const sheet = spreadsheet.getSheetByName('Errors'); const row = sheet.getLastRow() + 1; let index = row; const ary = params.event[params.event_type]; for (let options of ary) { sheet.getRange(row, 1).setValue(params.event_type); sheet.getRange(row, 2).setValue(params.server_composition); sheet.getRange(row, 3).setValue(options.status); sheet.getRange(index, 4).setValue(options.reason); sheet.getRange(index, 5).setValue(options.sourceIp); sheet.getRange(index, 6).setValue(options.returnPath); sheet.getRange(index, 7).setValue(options.created); sheet.getRange(index, 8).setValue(options.subject); sheet.getRange(index, 9).setValue(options.apiData); sheet.getRange(index, 10).setValue(options.messageId); sheet.getRange(index, 11).setValue(options.from); sheet.getRange(index, 12).setValue(options.to); sheet.getRange(index, 13).setValue(options.senderIp); index++; } const output = ContentService.createTextOutput(); output.setMimeType(ContentService.MimeType.JSON); output.setContent(JSON.stringify({})); return output; }
注意点
Google Apps Scriptではレスポンスが遅いのか(または別な理由なのか)、データが3回送られてきました。本来であれば、データをチェックしてユニークかどうか調べる方がいいでしょう。とはいえ、まずは蓄積が大事なので、データに書き出しておくことで再利用性も高まるはずです。
まとめ
Webhook APIを使えば自社サーバと連携したり、データベースの値を更新するといった仕組みが簡単に作れます。もしそういった仕組みを作るリソースがない場合でも、まずはGoogleスプレッドシートに蓄積しておくことで、エラーになったメールアドレスをメンテナンスするのが簡単にできるようになるでしょう。
ぜひ大量メール配信の際にはCustomers Mail Cloudをご利用ください!