エムスリーキャリアの医師戦略推進チームの後藤です。
医師戦略推進チームでは、医師採用担当のコンサルタントが利用するSalesforce(Sales Cloud)の開発・保守・運用を担当しています
弊社のコンサルタントが日々の活動状況を入力するのはもちろん、転職を考えている先生や医療機関の担当者様に向けてSalesforceから、さまざまなマーケティングメールを送信しています。 今回は弊社の医師向けSalesforceで、どのようにGmailガイドラインに対応したかをご紹介します。
前提
Gmailガイドライン
Gmailのガイドラインによれば、Gmailに対して1日5,000件以上送信するマーケティングメールには購読解除のリンクを含める必要があります。本文中に購読解除ページへのリンクを含めることや、ワンクリックでの購読解除では要件を満たしたことにはなりません。メールヘッダーに<list-unsubscribe>を含めることが必須の要件となります。
Sales Cloudの対応 状況
Salesforceのサポートにメールヘッダーを含めることが可能か確認したところ、Sales Cloudからメールを送信する際にメールヘッダーに任意の値を追加することはできないと回答を得ました。
また、Sales Cloudではメールヘッダーに<list-unsubscribe>を追加する予定はないとのことです。
データ構造
メール送信のための一時オブジェクトに送信情報を保存し、メールを送信する構造です。一時オブジェクトには、送信元メールアドレス、送信先メールアドレス、件名、本文を保存しています。ただし、すべての項目を保存するわけではなく、処理によっては一部の情報のみを保存しています。担当者または求職者を管理するオブジェクトには、複数選択リストで配信を停止する選択肢を管理しています。
対応前の送信方法
一時オブジェクトの作成方法にはAPEXクラス、レコードトリガーフロー、画面フロー、batchなどがあります。一時オブジェクトが作成されると、レコードトリガーフローが起動してSalesforceからメールを送信します。
対応方針
購読解除に対応するために送信数や料金を加味して検討した結果、弊社ではSendgridからメールを送信することに決定いたしました。また、機会損失を回避するために、送信するメールの種類ごとに配信を停止する選択肢を提供することとしました。
対象範囲
Salesforceから送信しているメールのうち、マーケティングメールと判断されるメールを対象とします。Googleから明確な基準がないため、あくまで社内の判断で行います。チームの判断基準としては以下のとおりです。
- 複数人に対して同時に送信する
- 求人や求職者の情報を案内している
送信処理
一時オブジェクト作成時に起動するAPEXトリガーを作成し、Sendgridにメールを送信します。 マーケティングメール以外でも一時オブジェクトを利用しているためカスタムメタデータ型で、送信の可否を管理できるように対応しました。 ヘッダーに購読解除用のリクエストURLを付与しました。URLから解除の対象者と機能を特定できるようにしました。
ハマったポイント1:非同期処理の制限を回避する必要がある
Salesforceから外部にコールアウトをするには非同期で実装する必要があります。 さらに、1トランザクションで呼び出し可能なコールアウト数は100回までとなっており、1回の送信件数が少ない処理では特に問題はありませんでしたが、batchで大量送信する機能では通常利用では実用に耐えられません。 回避方法として、レコードを100レコードごとに送信するようにしました。
ハマったポイント2:batchから非同期処理(future )を呼び出せない
非同期処理からfutureアノテーションが付いたメソッドを呼び出すことはできません。 batchも非同期処理の一種になりますので、futureメソッドを呼び出そうとすると制限エラーが返されます。 futureメソッドの代わりにqueueableを継承したクラスを定義して、Database.AllowsCalloutsを付けることで回避可能です。
購読解除
エンドユーザーが購読解除リンクを押した時に、送信時に付与した購読解除用のURLにリクエストを送信します。 リクエスト先は弊社のAWSのLamdaとなっており、種別と対象者をDynamoDBに保存します。 ETLサービスのTroccoで定期的にDynamoDBからSalesforceの購読解除用の一時オブジェクトに連携します。 購読解除用の一時オブジェクトが作成された後は、レコードトリガーフローで解除対象のオブジェクトを更新して以後メールが送信されない仕組みとなっています。
最後に
Googleから明確な基準が示されない中で、手探りながらもビジネス側の要件を満たし、かつ、送信と購読解除ともに共通処理化をすることで今後の開発負担も軽減することが可能な作りにすることができました。 また、現場の使用感を変えることなく、リリース後に問題を発生させなかった点もよかったと思っています。