Site cover image

Site icon image rpine lab Blog

rpine labのブログです。主に技術系の記事を投稿しています。
広告

📨 Cloudflare PagesからMailChannelsでメールを送信する(2024年7月以降利用不可)

💡
MailChannelsからのアナウンスの通り、本ページで解説していた方法での無料のメール送信は2024年7月以降には利用できなくなりました。
移行先としては、PostmarkResendといった無料枠のある外部サービスが候補になります。

Cloudflare PagesやWorkersからは、SendGridなどの外部サービスを契約しなくても、Cloudflareと提携しているメール配信サービスのMailChannelsを利用することで無料でメールを送信することが可能です。

これを利用してお問い合わせページなどが作成できます。

今回はCloudflare PagesからMailChannelsのAPIを使ったメール送信方法を解説します。

MailChannelsを使うための設定

MailChannelsを使ってメールを送信するためには、送信元アドレスのドメインのDNS設定が必要です。

これはMailChannelsのDomain Lockdownという仕組みに対応するためで、次のようなレコードをDNSに追加する必要があります。

参考サイト1 (MailChannelsの記事)・参考サイト2 (Cloudflareのドキュメント)

レコード名 レコードタイプ
_mailchannels.<送信元ドメイン> TXT v=mc1 cfid=*****.pages.dev (Pages上のWorkersから利用する場合)
v=mc1 cfid=myaccount.workers.dev (Workers単体で利用する場合)
💡
引っかかったポイント1
サブドメインを送信元に使う場合は、レコード名の<送信元ドメイン>の部分にサブドメインを含めたレコード名を指定します。
例(noreply.example.comを送信元アドレスのドメインに利用):_mailchannels.noreply(.example.com)()の部分はDNS設定画面によっては省略表示
💡
引っかかったポイント2
CloudFlare Pages上で動作しているCloudflare WorkersからAPIを呼び出す場合には、MailChannelsの参考サイトのようにアカウントごとのWorkersのサブドメイン(myaccount.workers.dev)ではなく、Pagesプロジェクトのドメイン(*****.pages.dev)の方を指定する必要がありました。
何を指定すればいいか迷った場合には、複数指定可能なのでcfid=****をスペースを空けて複数書けばいいと思います。

送信元ドメイン認証関係

MailChannelsを利用したメール送信では、SPFによる送信元メールサーバの指定やDKIMによるメールの電子署名が可能です。

Gmailによるスパム判定の強化などもあるので出来れば設定した方がいいと思います。

SPF設定
レコード名 レコードタイプ
<送信元ドメイン> TXT v=spf1 include:_spf.mx.cloudflare.net include:relay.mailchannels.net -all
DKIM設定

DKIMは設定が面倒で、手元で署名用の秘密鍵を生成する必要があります。生成した秘密鍵は後程、環境変数に設定してAPIの呼び出しに利用し、公開鍵はDNSのDKIMレコードに登録する必要があります。

方法(コマンドは公式ドキュメントからコピペ)

  1. 手元のマシンのターミナルで秘密鍵を生成します。生成したprivate_key.txtは、後程Pagesの環境変数に設定してMailChannelsのAPI呼び出しの際に指定します。
    openssl genrsa 2048 | tee private_key.pem | openssl rsa -outform der | openssl base64 -A > private_key.txt
  2. DNSレコード登録用のテキストファイル(dkim_record.txt)を生成します。
    echo -n "v=DKIM1;p=" > dkim_record.txt && openssl rsa -in private_key.pem -pubout -outform der | openssl base64 -A >> dkim_record.txt
  3. 生成したdkim_record.txtの中身を使い、次のDNSレコードを追加します。
    レコード名 レコードタイプ
    mailchannels._domainkey.<送信元ドメイン>
    mailchannelsの部分はセレクタキーで、API呼び出しの際に指定します。
    TXT dkim_record.txtの中身(v=DKIM;p=から始まる)を全て貼り付け

(DMARC設定は省略)

MailChannels APIを利用したメール送信

Cloudflare Workers上からMailChannelsのAPIを呼び出すことでメールを送信することができます。

PagesのMailChannelsプラグインを利用する方法もあるのですが、色々カスタマイズがしやすい、APIを直接呼び出す方法を今回は利用します。

利用するエンドポイントは、https://api.mailchannels.net/tx/v1/sendです。API仕様はhttps://api.mailchannels.net/tx/v1/documentationにあります。

必要な設定(環境変数)

Pagesの環境変数のDKIM_PRIVATE_KEYに、上のDKIM設定で予め作成しておいたprivate_key.txtの内容をセットしてください。

メール送信関数 (TypeScript)

単純なテキストを送る場合の関数の実装コードです。API仕様等を確認しながら適宜カスタマイズしてください。

Next.js 14のServer Actionsを利用した場合で動作を確認していますが、それ以外のWorkersで動くミドルウェアやルートハンドラ等からでも使えるはずです。

async function sendMail({
  subject,
  content,
}: {
  subject: string
  content: string
}) {
  const payload = {
    personalizations: [
      {
        to: [{ name: 'NAME', email: '[email protected]' }],
        dkim_domain: 'noreply.example.com',
        dkim_selector: 'mailchannels', // DKIMのレコード名と同じセレクタを指定
        dkim_private_key: process.env.DKIM_PRIVATE_KEY,
      },
    ],
    from: {
      name: 'Contact Form',
      email: '[email protected]',
    },
    subject,
    content: [{ type: 'text/plain; charset="UTF-8"', value: content }],
  }

  // MailChannels APIを利用してメール送信
  const response = await fetch('https://api.mailchannels.net/tx/v1/send', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(payload),
  })

  if (response.status === 200 || response.status === 202) {
    return // 正常に送信できた場合
  }

  try {
    const errors = ((await response.json()) as { errors?: string[] })?.errors
    console.error({ errors })
  } catch {
	  console.error(response.statusText)
  }
}
メールの送信に失敗する場合

APIからの応答にあるエラーメッセージを確認して修正してください。

失敗していたら多分上に書いたDomain LockdownやDKIMのDNS設定辺りの修正が必要だと思います。DNSの設定の反映には時間がかかるので、変更後は時間を置いてテストする必要があります。

また、この方法だとCloudflare Workers以外の実行環境(例えばローカル環境でのデバッグ)からはメール送信できないので、テストの際はPagesのdevelop環境などで実際に実行して試す必要があります。

まとめ

今回はCloudflare PagesからMailChannelsのAPIを使ったメール送信方法を解説しました。

同じくCloudflareが提供しているBOT対策のCloudflare Turnstileを組み合わせることで、Cloudflareで全て完結する形で、いい感じにお問い合わせページ等が作れます。

参考サイト

広告