Twilio SendGridライブラリで送信リクエストとレスポンスを取得する方法 ~Java編~

Twilio SendGridライブラリで送信リクエストとレスポンスを取得する方法 ~Java編~

メール送信リクエストを実行したのに、ActivityEvent Webhookにイベントが記録されていない!という経験はありませんか?イベントが発生しない主な原因として、Twilio SendGridに送信リクエストが届いていない可能性が考えられます。問題が発生した際に原因をしっかり特定できるよう、実際に送ったJSON形式の送信リクエストとそのHTTPレスポンスを必ずログに出力しましょう。

SMTPやWeb APIで送信する場合は、TelnetやcURLなどのツールによって簡単に送信リクエストとレスポンスが取得できるので、チュートリアルをお試しください。今回のブログでは、Java向けのSendGridライブラリ(以降、sendgrid-javaと表記)における取得方法を紹介します。

sendgrid-javaを使った送信処理のサンプルコード

sendgrid-javaでは、送信に関する処理をRequestクラスが行い、レスポンスはResponseクラスに格納します。送信処理のサンプルコードは次のとおりです。

package org.example;

import com.sendgrid.*;
import com.sendgrid.helpers.mail.Mail;
import com.sendgrid.helpers.mail.objects.Content;
import com.sendgrid.helpers.mail.objects.Email;

import io.github.cdimascio.dotenv.Dotenv;

public class Javaのライブラリを使ったメール送信 {
    public static void main(String... args) throws Exception{
        //環境変数の読み込み準備
        Dotenv dotenv = Dotenv.load();

        //宛先
        Email 宛先 = new Email(
            "kozotaro@example.com",
            "構造太郎"
        );

        //差出人
        Email 差出人 = new Email(
            "kozohanako@example.com",
            "構造花子");

        //本文
        Content 本文 = new Content();
       
        //本文:テキストパート
        本文.setType("text/plain");
        本文.setValue("""
            構造さん
            お元気ですか。
        """);

        //本文:HTMLパート
        本文.setType("text/html");
        本文.setValue("""
            <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
            <html xmlns="http://www.w3.org/1999/xhtml">
            <head>
                <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
                <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1">
            </head>
            <body>
                <p>構造さん</p>
                <p>お元気ですか。</p>
            </body>
        """);

        //メールの作成
        Mail メール = new Mail(差出人, "Javaのライブラリを使ったメール送信", 宛先, 本文);

        SendGrid sg = new SendGrid(dotenv.get("SG_API_KEY"));
        Request 送信リクエスト = new Request();
   
        送信リクエスト.setMethod(com.sendgrid.Method.POST);
        送信リクエスト.setEndpoint("mail/send");
        送信リクエスト.setBody(メール.build());

        System.out.println("--送信リクエストを標準出力する--");
        System.out.println(メール.build());

        Response レスポンスデータ = sg.api(送信リクエスト);

        System.out.println("---レスポンスを標準出力する----");
        System.out.println(レスポンスデータ.getStatusCode());
        System.out.println("---------------------------");
        System.out.println(レスポンスデータ.getHeaders());
        System.out.println("---------------------------");
        System.out.println(レスポンスデータ.getBody());
    }
}

送信リクエストとレスポンスを取得する部分を紹介します。

送信リクエストの取得方法

送信リクエストはMailクラスのbuildメソッドの戻り値で取得できます。戻り値を標準出力してみましょう。

Mail メール = new Mail(差出人, "メールヘルパークラスを使う", 宛先, 本文);
..
System.out.println(メール.build());

結果は次のとおりです。

{"from":{"name":"構造花子","email":"kozohanako@example.com"},"subject":"メールヘルパークラスを使う","personalizations":[{"to":[{"name":"構造太郎","email":"kozotaro@example.com"}]}],"content":[{"type":"text/html","value":"    <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n    <html xmlns=\"http://www.w3.org/1999/xhtml\">\n    <head>\n        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n    </head>\n    <body>\n        <p>構造さん</p>\n        <p>お元気ですか。</p>\n    </body>\n"}]}

JSON形式に整形すると次のような形になります。

{
  "from": {
    "name": "構造花子",
    "email": "kozohanako@example.com"
  },
  "subject": "メールヘルパークラスを使う",
  "personalizations": [
    {
      "to": [
        {
          "name": "構造太郎",
          "email": "kozotaro@example.com"
        }
      ]
    }
  ],
  "content": [
    {
      "type": "text/html",
      "value": "    <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n    <html xmlns=\"http://www.w3.org/1999/xhtml\">\n    <head>\n        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n    </head>\n    <body>\n        <p>構造さん</p>\n        <p>お元気ですか。</p>\n    </body>\n"
    }
  ]
}

続いて、レスポンスを取得する方法について紹介します。

レスポンスの取得方法

送信リクエストに対するレスポンスはapiメソッドの戻り値で取得します。Response型のオブジェクトにステータスコードやヘッダ、ボディなど、詳細な情報が入っています。

Response レスポンスデータ = sg.api(送信リクエスト);
System.out.println(レスポンスデータ.getStatusCode());
System.out.println("---------------------------");
System.out.println(レスポンスデータ.getHeaders());
System.out.println("---------------------------");
System.out.println(レスポンスデータ.getBody());

原因を特定する際、特に大事なのはステータスコードとボディの情報です。正常応答(ステータスコードが2xx系)であれば、SendGridに送信リクエストが届いています。レスポンスがエラーの場合(ステータスコードが2xx系以外)は、SendGridに送信リクエストが届いていない、もしくは受け付けられていないので、bodyの「errors」で示されたメッセージをもとに原因を確認しましょう。

正常応答の場合



202
---------------------------
{Server=nginx, Access-Control-Allow-Origin=https://sendgrid.api-docs.io, Access-Control-Allow-Methods=POST, X-Content-Type-Options=no-sniff, Connection=keep-alive, X-No-CORS-Reason=https://sendgrid.com/docs/Classroom/Basics/API/cors.html, Date=Thu, 13 Mar 2025 00:04:51 GMT, Access-Control-Allow-Headers=Authorization, Content-Type, On-behalf-of, x-sg-elas-acl, Referrer-Policy=strict-origin-when-cross-origin, Strict-Transport-Security=max-age=31536000; includeSubDomains, Cache-Control=no-cache, Content-Security-Policy=frame-ancestors 'none', X-Message-Id=8ogG3b7bQBixnNLE2qGXIA, Content-Length=0, Access-Control-Max-Age=600}
---------------------------


エラ-の場合(正しくないメールアドレス形式を指定した場合)



400
---------------------------
{Server=nginx, Access-Control-Allow-Origin=https://sendgrid.api-docs.io, Access-Control-Allow-Methods=POST, X-Content-Type-Options=no-sniff, Connection=keep-alive, X-No-CORS-Reason=https://sendgrid.com/docs/Classroom/Basics/API/cors.html, Date=Mon, 17 Mar 2025 04:31:28 GMT, Access-Control-Allow-Headers=Authorization, Content-Type, On-behalf-of, x-sg-elas-acl, Referrer-Policy=strict-origin-when-cross-origin, Strict-Transport-Security=max-age=31536000; includeSubDomains, Cache-Control=no-cache, Content-Security-Policy=frame-ancestors 'none', Content-Length=204, Access-Control-Max-Age=600, Content-Type=application/json}
---------------------------
{"errors":[{"message":"Does not contain a valid address.","field":"personalizations.0.to.0.email","help":"http://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/errors.html#message.personalizations.to"}]}


エラ-の場合(無効な認証情報が指定された場合)



401
---------------------------
{Server=nginx, Access-Control-Allow-Origin=https://sendgrid.api-docs.io, Access-Control-Allow-Methods=POST, X-Content-Type-Options=no-sniff, Connection=keep-alive, X-No-CORS-Reason=https://sendgrid.com/docs/Classroom/Basics/API/cors.html, Date=Mon, 17 Mar 2025 04:40:15 GMT, Access-Control-Allow-Headers=Authorization, Content-Type, On-behalf-of, x-sg-elas-acl, Referrer-Policy=strict-origin-when-cross-origin, Strict-Transport-Security=max-age=31536000; includeSubDomains, Cache-Control=no-cache, Content-Security-Policy=frame-ancestors 'none', Content-Length=116, Access-Control-Max-Age=600, Content-Type=application/json}
---------------------------
{"errors":[{"message":"The provided authorization grant is invalid, expired, or revoked","field":null,"help":null}]}


レスポンスで「Bad Request」などのエラーが返る場合は、送信リクエストに誤りがないかどうか確認しましょう。また、リクエストは正常に受け付けられたがメールへの差し込みがうまくいかない、指定したテンプレートが反映されないなど、お困りの場合は、弊社サポートチームがフォローいたします。送信リクエストとレスポンス、受信メールを添えてお問い合わせください。

コードの再確認をしましょう

SendGridでは送信後の状況をActivityやEvent Webhookで確認できるため、その手前の送信リクエストやレスポンスのログ出力を忘れがちです。今回のブログをきっかけに、しっかりログ出力できているかご自身のコードをもう一度見直してみてください。

アーカイブ

メールを成功の原動力に

開発者にもマーケターにも信頼されているメールサービスを利用して、
時間の節約、スケーラビリティ、メール配信に関する専門知識を手に入れましょう。