しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

SendGrid の SMTP API を SmtpClient で使ってみる

SendGrid にはメール送信のために SMTP と REST の API が用意されてますが、SMTP 上に独自の機能を追加するために X-SMTPAPI というヘッダーが追加されています。

SMTP API についてですが、Parse API の時と同じように公式のドキュメントが良く出来ています。

SMTP API, Advanced Email Features - SendGrid Documentation | SendGrid

分かりやすく日本語でまとめると以下のような感じだと思います。

  • 最大 1000 アドレスへの一括配信
  • タグを使った置換、セクション
    • 一括配信時、アドレスごとに埋め込む内容を変えたりできる
  • メールのカテゴライズ
    • SendGrid の統計ページでグラフ化出来る
  • メールへのユニークな ID 付加
    • Event API やアクティビティから確認が出来る
  • フィルタ設定
    • クリック、開封追跡などのオンオフを行える

で、この SMTP API をどのように使うかですが、一番簡単な方法は SendGrid が公式で用意している C# クライアントを使うことです。

NuGet Gallery | SendGrid 6.1.0

sendgrid/sendgrid-csharp · GitHub

これを使うと、先程挙げた機能をメソッド呼び出すだけで使えるので非常に楽です。SendGrid のみを使う場合には、このクライアントを使っておけば問題ないと思います。

しかし、既に SmtpClient を使ってメール送信を実装している場合は SendGrid のクライアントへ修正するのは大変ですし、ぶっちゃけ API がイケてないというか、使い勝手があんまりよくないので標準の SmtpClient で使ってみました。

まずは接続情報の設定です。これは Web.config に以下のように書くだけです。

<system.net>
  <mailSettings>
    <smtp>
      <network host="smtp.sendgrid.net" port="587" userName="USERNAME" password="PASSWORD" enableSsl="true" />
    </smtp>
  </mailSettings>
</system.net>

SendGrid のクライアントだと接続情報を外部に出すのめんどくさいんですよね。標準の SmtpClient なら Web.config に書くだけなので、Web 発行時に本番用の情報に入れ替えたりできて便利です。

そして SMTP API を使う方法は MailMessage の Headers コレクションに X-Smtpapi というキーを追加する形になります。簡単なサンプルコードを置いておきます。

// MailMessage を作成しておく
var mailMessage = new MailMessage();

// X-Smtpapi の値は JSON
mailMessage.Headers.Add("X-Smtpapi", "{ \"to\":[ \"foo@example.jp\", \"bar@example.jp\" ] }");

// SMTP で送信する
var smtpClient = new SmtpClient();

await smtpClient.SendMailAsyc(mailMessage);

こんな感じに JSON を毎回書くのはあり得ないので、実際には拡張メソッドなどを用意しておいた方が良いでしょうね。

public static class SendGridExtensions
{
    public static void AddTo(this MailMessage message, params string[] to)
    {
        var value = JsonConvert.SerializeObject(new { to });

        message.Headers.Add("X-Smtpapi", value);
    }
}

このような拡張メソッドを用意しておけば、実際に使う場合は以下のような感じで、シンプルに書けますね。

// MailMessage を作成しておく
var mailMessage = new MailMessage();

// 拡張メソッドを呼び出す
mailMessage.AddTo("foo@example.jp", "bar@example.jp");

// SMTP で送信する
var smtpClient = new SmtpClient();

await smtpClient.SendMailAsyc(mailMessage);

SendGrid の SMTP API はいろいろと機能があるので、もうちょっと調べていきたいと思います。