しばやん雑記

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

SendGrid の新しい Dynamic Templates が非常に強力だった

メール送信で SendGrid を使っていて、地味に不便だったのがメールのテンプレート周りでした。

SendGrid 自体に Template Engine 機能はありましたが、基本的には文字列の置換しか出来なかったので、項目の出し分けはテンプレートを分けるか、予めブロック自体を置換対象にしておく必要がありました。

なので、仕方なく C# の場合は RazorEngine などでレンダリングした結果を API で送信することも多かったのですが、最近追加された Dynamic Templates を使うことで不要になりそうです。

基本的な流れは Template Engine と変わらないですが、テンプレートに Handlebars.js 記法が使えるようになったので、送信時に追加したデータから自由にメールをレンダリング出来るようになりました。最高。

Dynamic Templates のリリースに伴い、これまでの Template Engine は Lagacy Template になったようです。一応、前に Template Engine については書いてました。

機能としては Dynamic Templates の方が圧倒的に優れているので、乗り換えた方が良いと思います。これまでの傾向からするに、Legacy Templates 機能はクローズのアナウンスが出てきそうですし。

とりあえず実際に試しますが、まずはドキュメントを確認しておきます。送信時に投げる JSON に新しく dynamic_template_data が追加され、そのオブジェクトがテンプレート内で参照できるものになります。

How to send an email with Dynamic Transactional Templates | SendGrid Documentation

テンプレート内で使える Handlebars.js 記法についてもドキュメントが用意されています。全ての記法に対応しているわけではないみたいなので、その辺りだけ注意が必要そうです。

Using Handlebars | SendGrid Documentation

管理画面にあるエディターを使うと、テンプレートとテストデータを指定してプレビューが行えるので楽です。テンプレートのエラー時には分かりやすく表示をしてくれないので、はまることが多かったです。

サイドにある Settings からは件名の設定も行え、そこでも Handlebars.js 記法が使えました。

f:id:shiba-yan:20180909163627p:plain

テンプレートを保存したら、ID をメモして送信用のデータを組み立てるだけですが、まだ SendGrid 公式の C# クライアントでは Dynamic Templates に対応していないので手動で組み立てました。

既に PR はマージされているので、近日中にリリースされるのではないかと。

とりあえずサンプルなので匿名クラスで一気に必要なデータを作りました。実際に組み込む場合には dynamic_template_data の中身をどう組み立てるかが肝になるでしょう。

とはいえ、一般的にはテンプレート単位でメール用のモデルクラスを用意することになるとは思います。

var obj = new
{
    from = new
    {
        email = "from@example.com"
    },
    personalizations = new[]
    {
        new
        {
            to = new[]
            {
                new
                {
                    email = "to@example.com"
                }
            },
            dynamic_template_data = new
            {
                name = "buchizo",
                message = "test message",
                items = new[]
                {
                    new { name = "item 1", price = 1980 },
                    new { name = "item 2", price = 2980 },
                    new { name = "item 3", price = 4980 }
                }
            }
        }
    },
    template_id = "TEMPLATE ID"
};

var content = new StringContent(JsonConvert.SerializeObject(obj), Encoding.UTF8, "application/json");

var httpClient = new HttpClient();

httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "API KEY");

await httpClient.PostAsync("https://api.sendgrid.com/v3/mail/send", content);

このサンプルを実行すると、ちゃんとレンダリングされた形でメールが届きました。

f:id:shiba-yan:20180909165140p:plain

実装が分散しがちなメールのテンプレートを SendGrid 側に預けつつ、レンダリングまで任せることが出来るのは非常に便利です。独自の記法ではないこともメリットになりそうです。

メールの送信に必要なものが HTML などを含まない、純粋なデータのみになるのもメリットの一つです。

キューを挟んで送信する場合などでは、1 メッセージ当たりのサイズ制限があるので、大きな HTML を含む場合には注意が必要かつ、無駄な容量となってしまいますが、Dynamic Templates を使うことで解消します。

Enqueue / Dequeue の時もサイズが小さい方が良いのは明らかでしょう。

データのみなのでテンプレートに問題があった場合にも、簡単に修正が出来るので積極的に使っていきたい機能です。とりあえずは既存の Template Engine を Dynamic Templates に置き換えていこうかと。