同じ文面だけど、本文に名前が入れたいといった事をすると、同じ文面のメールを送るだけのはずが人数分のメールを送る事になっちゃいます。で、それをどうにかしつつ、SendGridを使って送信するメモ。
Web API v3 使ってます。
大量配信のあれこれ
基本的に大量送信用に作られているので、本文は同じだけどユーザ毎で異なる部分をどうにかする方法のメモ書き。
sendgridの機能
大量送信などに対応するための機能がある。
- Personalization
2. 送信先などに関する送るメール文面のメタ情報、recipients, subject, headers, substitutions そしてカスタムargumentsを、配列にした情報
3. 今回はこれを利用する -
SMTPAPI
とWeb API v2
とWeb API v3
5. 今回はWeb API v3
を使う。
6. composer で入れちゃったのが理由。
7. SendGrid側でUTF-8処理のバグがあったっぽいけど、多分もう大丈夫じゃない。わからないけど。
Personalization 機能
see: https://sendgrid.com/docs/Classroom/Send/v3_Mail_Send/personalizations.html
何か Web API v3 からの機能っぽい。
今回は to
,subject
,substitutions
を使う。他にもcustom_args
,send_at
,headers
,cc
,bcc
が指定できる。
to
も複数指定できるので、同じ文面の場合はto
にメールアドレスをひたすら追加して送る形になる。
1回のAPI Call につき
to
,bcc
,cc
の最大件数ってあるのかしら…?
指定可能な宛先数は1000件以内です。これには、to, cc, bccパラメータで指定したものを含み、personalizations配列を超えてカウントされます
、と書かれているので、一度に送れる送り先は1000件だそうです。 制限事項
注意点
-
Personalization
は1回のAPIリクエストに最大1000件が限度なので、1000件以上になる場合は1000件単位で分割して送るしかない: https://sendgrid.com/docs/Classroom/Send/v3_Mail_Send/personalizations.html
Substitution を使う
今回は名前の部分が違い、他の文面で違いがないので、その部分を対応する為の機能。
例えば、メールの本文に %name%
と仕込み、SendGrid
の Personalization
に入れてやれば都合よくSendGrid
が置換してくれます。
注意点
-
%first name%
など中にスペースを挟むと置換しませんので注意。
2. SMTP-APIに書いていることなので、Web API v3
も適応されるのかよくわからないけど、まぁ多分、アルファベットのみで書くのがいい感じはする。
テスト
書いたコードが正しく動くか確認したい時は、SandBox
モードを使えば、相手先に送信せずに、リクエストの正当性をチェックをしてくれます。
大雑把なコード
{
"name": "test/sendgrid_test_php",
"require": {
"sendgrid/sendgrid": "^5.0",
"vlucas/phpdotenv": "^2.4"
}
}
API_KEY=...
<?php
require __DIR__ . '/vendor/autoload.php';
use SendGrid\Email;
use SendGrid\Mail;
use SendGrid\Content;
use SendGrid\Personalization;
use SendGrid\MailSettings;
use SendGrid\SandBoxMode;
function helloEmail()
{
$from = new Email("Example Hosting Service", "info@example.com");
$mail = new Mail();
$mail->setFrom($from);
// メッセージ作成. textメールとhtmlメールを送信をする
$content = new Content("text/plain",
"some text here\n%name%様 御中\n\nこれは%name%様宛に送信しています。");
$mail->addContent($content);
$content = new Content("text/html",
"<html><body>some text here<br/>%name%御中<br /><br />これは%name%様宛に送信しています。</body></html>");
$mail->addContent($content);
// 宛先一覧
$name_list = [
[ "人名漢字", "A1@example.com" ],
[ "Aさん", "B1@example.com" ],
[ "Bさん", "C1@example.com" ],
];
foreach($name_list as $names){
$personalization = new Personalization();
$email = new Email($names[0], $names[1]);
$personalization->addTo($email);
$personalization->setSubject("Hello World from the SendGrid PHP Library %name% 様宛");
// ここで追加したHeaderは、ユーザ側まで行く
$personalization->addHeader("X-Test", "test");
$personalization->addHeader("X-Mock", "true");
// 本文とSubjectの「%name%」をSendGrid側で置換させる
$personalization->addSubstitution("%name%", $names[0]);
$mail->addPersonalization($personalization);
}
// カテゴリー名はアルファベットのみ
$mail->addCategory("test_sending");
echo json_encode($mail, JSON_PRETTY_PRINT), "\n";
return $mail;
}
$dotenv = new Dotenv\Dotenv(__DIR__);
$dotenv->load();
$apiKey = getenv('API_KEY');
$sg = new \SendGrid($apiKey);
$mail = helloEmail();
$mail_settings = new MailSettings();
// サンドボックスモードにする事で、送信しないが、リクエストの正当性を確認する
$sandbox_mode = new SandBoxMode();
$sandbox_mode->setEnable(true);
$mail_settings->setSandboxMode($sandbox_mode);
$mail->setMailSettings($mail_settings);
$response = $sg->client->mail()->send()->post($mail);
echo $response->statusCode();
echo $response->body();
echo $response->headers();