この2月から、Gmailに大量のメールを配信するメール送信者は、受信者が簡単に配信停止できるようにしなければならなくなりました。いわゆるワンクリック解除と呼ばれているものです。
原文は下記のようになっています。
重要: Gmail では 2024 年 2 月以降、Gmail アカウントに 1 日あたり 5,000 件以上のメールを送信する送信者に対し、1. 送信メールを認証すること、2. 未承諾のメールまたは迷惑メールを送信しないようにすること、3. 受信者がメールの配信登録を容易に解除できるようにすること、の 3 つが義務付けられます。
この記事では、上記3の「受信者がメールの配信登録を容易に解除できるようにすること」についてメール配信サービスSendGrid APIを使用した対応例を紹介します。
配信メールのワンクリック解除を受信者に提供するためには、2つのメールヘッダーに対応する必要があります。List-Unsubscribe
ヘッダーとList-Unsubscribe-Post
ヘッダーです。
このうちList-Unsubscribe-Post
ヘッダーには固定の値List-Unsubscribe=One-Click
を設定します。List-Unsubscribe
ヘッダーの値にはPOSTリクエストを送るURLを設定します。
メールにこれらのヘッダーを設定することで、Gmail側では下記のように「メーリングリストの登録解除」というリンクが表示されるようになります。受信者がリンクをクリックするとList-Unsubscribe
ヘッダーに設定されたURLにPOSTリクエストが送られるというわけです。
ただし、2つのヘッダーを設定したからといって必ずしもリンクが表示されるわけではないようです。SendGridのドキュメントでは下記のように説明されています。
配信停止用リンクが表示されるのはレピュテーションの高い送信者が送った場合のみですが、全ての送信者がList-Unsubscribeを利用するよう推奨しています。
小規模サービスではレピュテーションが低いことが考えられるため「メーリングリストの登録解除」リンクが表示されない可能性があります。実際に、私が個人で運営しているサービスでもリンクは表示されませんでした。
SendGrid APIクライアントを使ってList-Unsubscribe
ヘッダーとList-Unsubscribe-Post
ヘッダーを付加する例と、POSTリクエストを受けるWebエンドポイントの実装例を紹介します。例としてNode.jsを使用します。
SendGrid APIのNode.jsクライアントを使って、メールにカスタムヘッダーとしてList-Unsubscribe
ヘッダーとList-Unsubscribe-Post
ヘッダーを付加する例を見てみましょう。
下記はダイナミックテンプレートを使用している例です。ダイナミックテンプレートを利用していない場合はsubject
など追加する必要があることにご注意ください。
const sendgrid = require('@sendgrid/mail');
sendgrid.setApiKey(process.env.SENDGRID_API_KEY);
const hash = 'abc...';
const unsubscribeURL = new URL(`/unsubscribe/${hash}`, 'https://example.com');
const message = {
to: toEmail,
from: {
name: name,
email: fromEmail,
},
templateId,
headers: {
'List-Unsubscribe-Post': 'List-Unsubscribe=One-Click',
'List-Unsubscribe': `<${unsubscribeURL.toString()}>`,
},
};
await sendgrid.send({
...message,
dynamicTemplateData: {
hash,
},
});
配信停止用のWebエンドポイントは https://example.com/unsubscribe/<hash>
としています。
hash
はユーザーごとに違った値を生成しデータベース等に保存しておきます。配信停止処理の際にhash
を元にユーザーを検索するからです。
メールのフッター部分に「配信停止」リンクを付加することが一般的であるため、hash
パラメータをダイナミックテンプレートにも渡しています。テンプレート側ではURLの一部を{{hash}}
のようにしておくことで、渡ってきたhash
パラメータで置き換えることができます。
Gmailの「メーリングリストの登録解除」リンクが押されるとList-Unsubscribe
ヘッダーで指定したURLに対して下記のようなPOSTリクエストが送られます。
POST /unsubscribe/abc... HTTP/1.1
Host: solarmora.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 26
List-Unsubscribe=One-Click
Webエンドポイント側では、このPOSTリクエストをもとにメール配信停止の処理を行います。
Webエンドポイントではhash
パラメータを元にユーザーを検索し、通知を送らないようにデータを更新にします。
Gmailの「メーリングリストの登録解除」リンクが押されたときはPOSTリクエストが送られるのに対して、メールのフッター部分に設置した「配信停止」リンクではGETリクエストによる遷移となります。
後者ではPOSTリクエストを送るためのフォームを表示し、POSTリクエストのエンドポイントは前者と後者で共通化してしまうと良いでしょう。下記はPOSTリクエストを処理するエンドポイントの実装例です。
const user = await getUserByHash(hash)
if (!user) {
throw new Error('invalid hash')
}
if (request.method === 'POST') {
await turnNotificationOff(user.id)
if (Astro.request.headers.get('List-Unsubscribe-Post')) {
return new Response(null, { status: 200 })
}
}
// Return HTML with the form
Gmailの「メーリングリストの登録解除」リンクが押された場合にはList-Unsubscribe-Post
ヘッダーがあるため単純に200 OKをレスポンスします。そうでない場合は、ユーザーがブラウザで遷移しフォームからPOSTリクエストを送ってきたと考えることができるので、配信停止完了を示すHTMLをレスポンスすると良いでしょう。
以上です。この記事では、Gmailの送信者ガイドラインのうち「受信者がメールの配信登録を容易に解除できるようにすること」についてメール配信サービスSendGrid APIを使用した対応例を紹介しました。
コメントを送る
コメントはブログオーナーのみ閲覧できます