LoginSignup
38
34

More than 5 years have passed since last update.

SendGrid でそれなりの量のメールを送信するメモ

Last updated at Posted at 2016-09-16

同じ文面だけど、本文に名前が入れたいといった事をすると、同じ文面のメールを送るだけのはずが人数分のメールを送る事になっちゃいます。で、それをどうにかしつつ、SendGridを使って送信するメモ。

Web API v3 使ってます。

大量配信のあれこれ

基本的に大量送信用に作られているので、本文は同じだけどユーザ毎で異なる部分をどうにかする方法のメモ書き。

sendgridの機能

大量送信などに対応するための機能がある。

  1. Personalization
    1. 送信先などに関する送るメール文面のメタ情報、recipients, subject, headers, substitutions そしてカスタムargumentsを、配列にした情報
    2. 今回はこれを利用する
  2. SMTPAPIWeb API v2Web API v3
    1. 今回は Web API v3 を使う。
    2. composer で入れちゃったのが理由。
    3. 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件だそうです。 制限事項

注意点

  1. Personalization は1回のAPIリクエストに最大1000件が限度なので、1000件以上になる場合は1000件単位で分割して送るしかない: https://sendgrid.com/docs/Classroom/Send/v3_Mail_Send/personalizations.html

Substitution を使う

今回は名前の部分が違い、他の文面で違いがないので、その部分を対応する為の機能。

例えば、メールの本文に %name% と仕込み、SendGridPersonalizationに入れてやれば都合よくSendGridが置換してくれます。

注意点

  1. %first name% など中にスペースを挟むと置換しませんので注意。
    1. SMTP-APIに書いていることなので、Web API v3も適応されるのかよくわからないけど、まぁ多分、アルファベットのみで書くのがいい感じはする。

テスト

書いたコードが正しく動くか確認したい時は、SandBoxモードを使えば、相手先に送信せずに、リクエストの正当性をチェックをしてくれます。

大雑把なコード

composer.json
{
    "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();

38
34
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
38
34