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

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

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

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

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

ライブラリはPythonのパッケージ管理ツールであるpipを利用して取得します。

pip install sendgrid

sendgrid-pythonを使った送信コードは次のとおりです。

import json
import os
from python_http_client import HTTPError
import sendgrid
from sendgrid.helpers.mail import *
from dotenv import load_dotenv

# .envファイルの読み込み
load_dotenv()

sg = sendgrid.SendGridAPIClient(api_key=os.getenv('SENDGRID_API_KEY'))

宛先 = To(email='kozotaro@example.com', name='構造太郎')
差出人 = Email(email='kozohanako@example.com',name='構造花子')
件名 = 'Pythonのライブラリを使ったメール送信'
本文_テキストパート = PlainTextContent(
    '''構造さん
      お元気ですか。'''
)
本文_HTMLパート = HtmlContent(
    '''<!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(差出人, 宛先, 件名, 本文_テキストパート, 本文_HTMLパート)

# 送信リクエストの取得
送信リクエスト = メール.get()

print('--送信リクエストを標準出力する--')
print(json.dumps(送信リクエスト, sort_keys=True, indent=4, ensure_ascii=False))

# メールの送信
try:
    レスポンス = sg.client.mail.send.post(request_body=送信リクエスト)
    print('--レスポンスを標準出力する--')
    print(レスポンス.status_code)
    print(レスポンス.body)
    print(レスポンス.headers)
except HTTPError as err:
    print(str(err))


.envファイルにはダッシュボードで作成したAPIキーを定義します。

SENDGRID_API_KEY=SG.xxxxxxxxxxxxxxxxxxxxxxxxx

送信リクエストとレスポンスを取得する部分を詳しくみていきましょう。

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

送信リクエストは次の方法で取得できます。

メール = Mail(差出人, 宛先, 件名, 本文_テキストパート, 本文_HTMLパート)

# 送信リクエストの取得
送信リクエスト = メール.get()

print('--送信リクエストを標準出力する--')
print(json.dumps(送信リクエスト, sort_keys=True, indent=4, ensure_ascii=False))

json.dumpsメソッドでJSONを整形して出力すると次のようになります。

--送信リクエストを標準出力する--
{
    "content": [
        {
            "type": "text/plain",
            "value": "構造さん\n      お元気ですか。"
        },
        {
            "type": "text/html",
            "value": "\n    <!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    "
        }
    ],
    "from": {
        "email": "kozohanako@example.com",
        "name": "構造花子"
    },
    "personalizations": [
        {
            "to": [
                {
                    "email": "kozotaro@example.com",
                    "name": "構造太郎"
                }
            ]
        }
    ],
    "subject": "Pythonのライブラリを使ったメール送信"
}


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

レスポンスの取得方法

送信リクエストに対するレスポンスは次の方法で取得します。

try:
    レスポンス = sg.client.mail.send.post(request_body=送信リクエスト)
    print('--レスポンスを標準出力する--')
    print(レスポンス.status_code)
    print(レスポンス.body)
    print(レスポンス.headers)
except HTTPError as err:
    print(str(err))

原因を特定する際、特に大事なのはステータスコードとボディの情報です。正常応答(ステータスコードが2xx系)であれば、SendGridに送信リクエストが届いています。レスポンスがエラーの場合(ステータスコードが2xx系以外)は、SendGridに送信リクエストが届いていない、もしくは受け付けられていないので、try-exceptで捕捉した例外もきっちり処理しましょう。

正常応答の場合


202
b''
Server: nginx
Date: Sun, 20 Apr 2025 15:10:08 GMT
Content-Length: 0
Connection: close
X-Message-Id: h2T8azOeQUOP93G4Td8l2w
Access-Control-Allow-Origin: https://sendgrid.api-docs.io
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Authorization, Content-Type, On-behalf-of, x-sg-elas-acl
Access-Control-Max-Age: 600
X-No-CORS-Reason: https://sendgrid.com/docs/Classroom/Basics/API/cors.html
Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Security-Policy: frame-ancestors 'none'
Cache-Control: no-cache
X-Content-Type-Options: no-sniff
Referrer-Policy: strict-origin-when-cross-origin


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


HTTP Error 400: Bad Request

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


HTTP Error 401: Unauthorized

レスポンスで「Bad Request」などのエラーが返る場合は、送信リクエストに誤りがないかどうか確認しましょう。SendGridが用意するSandboxモードを利用することで、実際にメール送信を行うことなく、リクエストが正しいかどうかの検証ができます。

# メールの作成
メール = Mail(差出人, 宛先, 件名, 本文_テキストパート, 本文_HTMLパート)

# SandBoxModeで送信リクエストを検証する
メール設定 = MailSettings()
メール設定.sandbox_mode = SandBoxMode(enable=True)
メール.mail_settings = メール設定

…

# メールの送信
try:
    レスポンス = sg.client.mail.send.post(request_body=送信リクエスト)
    print('--レスポンスを標準出力する--')
    print(レスポンス.status_code)
    print(レスポンス.body)
    print(レスポンス.headers)
except HTTPError as err:
    print(str(err))

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

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

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

アーカイブ

メールを成功の原動力に

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