Firebaseベースのファンクション(Functions)でSendGridのWebHookをサポートする
FirebaseベースのFunctionsを利用した場合の環境変数の設定方法は?
SendGridは、E-Mailの配信サービスを提供しています。通常のE-Mailに近いメッセージの配信もできますし、メルマガやニュースレーターのような同じメッセージを大量一括送信もできます。
プログラムからも利用可能なAPIもサポートしていて、WebアプリやWebサービスにE-Mailによるメッセージ送信機能を組み込んだりするのに利用できます。
SendGridがサポートしている機能の一つに、E-Mailの追跡があります。これは、発送したE-Mailが配信されたか、E-Mailが開封されたか、E-Mailのリンクがクリックされたかなどを追跡する機能です。
この機能は、SendGridが提供するWebサイトからもアクセス可能ですが、こうしたイベントが発生した場合にSendGridのサーバーが通知してくれる機能「WebHook」を利用しても追跡が可能です。
Firebaseのバックエンド機能(ファンクション:functions)と組み合わせて利用すると簡単にこの追跡機能もWebサービスやWebアプリに組み込むことができます。
SendGridのWebHookの仕組み
SendGridのWebHookはSendGrid側で設定を行う必要があります。 SendGridのWebサイトからも設定できますし、APIを利用すれば、プログラムからも設定できます。
設定は簡単で、WebHookで追跡するイベント情報をどこに送るかを指定するだけです。
実際には存在しないURLですが、
https://backend.sv-sw.com/sg/webhook
のように指定して、WebHookを有効にすれば利用できます。 ただし、SendGrid側の設定を有効にする前に、WebHookのイベント情報を受け取る側のサーバーが稼働している必要があります。
WebHookのイベントを受信するバックエンドサービス
そこで、WebHookのイベントを受信するための、バックエンドサービスをFirebaseのファンクション(functions)を利用して作ります。
これも、サーバーサイドのフレームワーク「express」を使えば簡単に実装できます。
まずは、設定したURLに情報が送られた場合の処理を行う部分です。 「CONSTANTS.API_WEBHOOK_GET」がSendGridがイベントを送るURLになります。 このURLが指定された場合に、データを
this.app.post(
CONSTANTS.API_EVENTS_ADD,
async (req: express.Request, res: express.Response) => {
await this.sendgrid.setParameter(gid);
const events: string = JSON.stringify(req.body);
const items: Array<TYPE.SgEvent> = JSON.parse(events) as Array<
TYPE.SgEvent
>;
for (const item of items) {
await this.sendgrid.addEvent(item, gid);
}
this.normalResponse(res, "Operation is successful");
}
);
イベントはFirebaseのデータベース(Cloud Firestore)に保存します。 このイベントは重複して送られることがあるので、同じイベントが存在するかを確認したうえでFirebaseのデータベースに追加します。
addEvent(event: TYPE.SgEvent, gid: string): Promise<boolean> {
return new Promise(async (resolve) => {
await this.firebaseApp
.firestore()
.collection(CONSTANTS.FB_COLLECTION_EVENTS)
.where("event", "==", event.event)
.where("sg_message_id", "==", event.sg_message_id)
.where("timestamp", "==", event.timestamp)
.get()
.then(async (querySnapshot: firebase.firestore.QuerySnapshot) => {
if (querySnapshot.size === 0) {
await this.firebaseApp
.firestore()
.collection(CONSTANTS.FB_COLLECTION_EVENTS)
.add(event)
.then(() => {
resolve(true);
});
} else {
resolve(false);
}
});
});
SendGridのイベントのWebHookの実装はこれだけです。意外に簡単ですよね!
実際にメッセージを追跡するには?
送信した個々のメッセージの追跡自体は簡単に実現できました。 実際に、送信したメッセージを追跡するには送ったメッセージと、SendGridが送ってくるイベントの情報を結びつける必要があります。
SendGridで送信できるメッセージのタイプが大きく分けると2種類あります。
これによって、メッセージを特定する方法が違ってきます。
- 通常のメッセージ
- マーケティングメッセージ(キャンペーン)
通常のメッセージ
これは、通常のE-Mailに近いメッセージです。このメッセージの控えはSendGrid側には残りません。従って、メッセージを送信する際に、メッセージのIDを取得しておく必要があります。
このメッセージのIDの取得がちょっとトリッキーです。
追跡と結びつけるのに必要な情報は「x-message-id」というタグのついているデータです。 このデータは、メッセージを送信したときのSendGridからのレスポンスに含まれています。
問題は、このデータはレスポンスの「body」ではなく、「header」から抜き出す必要があります。 あとは、このIDをメッセージの送信先や、送付時刻、件名(subject)などと一緒に保存してメッセージを特定できる形で残す必要があります。
メッセージを特定する際は、イベントのIDの先頭にこの「x-message-id」が入っているイベントがこのメッセージの追跡情報になります。
マーケティングメッセージ(キャンペーン)
こちらは簡単に追跡できます。送付したメッセージの控えもSendGrid側に保存されていますので、送付したリストからメッセージのIDを取得すれば、問題ありません。追跡イベントのにも、このIDが含まれているので、メッセージの特定は通常のメッセージより簡単にできます。
メッセージの利用の際の注意
SendGrid経由で送信されるメッセージは通常のメールサーバーを経由しません。 たとえば、あなたがすでにお持ちのE-Mailアドレスを送信者としてSendGridに登録すれば、そのアドレスでメールを送ることができます。しかし、実際のメールの送信は通常しているメールサーバーではなく、SendGridが行うため、通常のメールの送信済のリストには入りません。 必要ならば、控えを自分で残すか、自分自身にコピーを送る必要があります。(Cc/Bccの利用)
受け取り側では、送信の際に「Reply To」で返信先を指定しておけば、そのメールに返信した場合は、通常のメールサーバー経由で受け取ることができます。(受け取る際は通常の経路)
なので、メールの経路をよく理解していないと混乱することがあります。
SendGridから送ると、送信したメールの開封などを追跡できるので便利ですが、通常のメールの送信とは別系統で行われるので場合によっては注意が必要になります。
効果的な利用方法は?
通常のメッセージの場合どうしても、メッセージの追跡をしたい場合はもちろん利用価値があります。 しかし、一番効果的な利用方法は、メルマガや商品のプロモーションのキャンペーンなどを行った際に、どれくらいの人がメッセージを開封したとか、リンクのクリックをしたなどによってメッセージやキャンペーンの状況を分析する場合です。
このデータを元に、メッセージの内容やキャンペーンの改善に役立てたり、興味がありそうな利用者をフォローアップしたりするのに利用すると便利です。
まとめ
SendGridでメッセージの追跡を行うには、SendGridのWebHookの機能を利用すると簡単に実装できます。
こうした機能を組み込んで自分自身で利用するのも便利ですし、こうした機能を組み込んだWebアプリやWebサービスを開発して、必要な方に提供するというビジネスも可能です。
ビジネスを展開するうえでは、送信したメッセージに対する反応が数字で可視化できるとマーケティングに活用することができます。データに基づくマーケティング、集客を行う場合、こうした機能の実装は大きな武器になります。
FirebaseとSendGridを組み合わせればこうした機能も簡単に実装することが可能です!