しばやん雑記

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

Azure Functions で SendGrid の Dynamic Templates を使う

この間書いた SendGrid の Dynamic Templates ですが、今朝に対応した SendGrid の C# クライアントがリリースされていたので、早速 Azure Functions の SendGrid バインディングで使ってみました。

Dynamic Templates 自体については前回のエントリを参照してください。テンプレートもそのまま使います。

SendGrid C# クライアントの 9.10.0 から Dynamic Templates に対応しました。Azure Functions での SendGrid バインディングに関してはドキュメントがあるので、それを見れば簡単です。

Azure Functions v2 を使っているので、3 系のパッケージを入れる必要があります。

ちなみにこのバインディングは SendGrid C# クライアントの 9.9.0 以上を参照しているので、プロジェクト側で明示的に新しいバージョンをインストールすれば、そのバージョンが全体的に使われます。

実際に 9.10.0 をインストールすると、依存バージョンが適切に選択されていることが分かります。

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

それでは実際にコードを書いていくのですが、今回はモデル用のクラスを適当に作りました。

こまめに JsonProperty で名前を指定していますが、この辺りは Json.NET の設定で自動 camelCase が出来たはずなので、好みの問題という感じもします。

public class TemplateModel
{
    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty("message")]
    public string Message { get; set; }

    [JsonProperty("items")]
    public TemplateItemModel[] Items { get; set; }
}

public class TemplateItemModel
{
    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty("price")]
    public int Price { get; set; }
}

テンプレートは前回と同じなので、必要な構造を単純にクラスに起こしただけです。

実際にメールを送信する関数は以下になります。テンプレートから生成したら SendGridMessage を return する形で作られたので、今回はその方式で書きました。SendGrid のバインディングには何種類か送信する方法が用意されていますが、Dynamic Templates を使う場合には SendGridMessage が必要になります。

今回は簡単にするために HttpTrigger を使いましたが、テンプレートでは QueueTrigger を使う形で生成されるので、非常に Dynamic Templates と相性が良いと思います。

public static class Function1
{
    [FunctionName("Function1")]
    [return: SendGrid]
    public static SendGridMessage Run([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]
                                      HttpRequest req, ILogger log)
    {
        var model = new TemplateModel
        {
            Name = "kazuakix",
            Message = "8GB",
            Items = new[]
            {
                new TemplateItemModel { Name = "Item 1", Price = 1980 },
                new TemplateItemModel { Name = "Item 2", Price = 2980 },
                new TemplateItemModel { Name = "Item 3", Price = 3980 }
            }
        };

        var message = new SendGridMessage
        {
            From = new EmailAddress("from@example.com"),
            TemplateId = "TEMPLATE ID"
        };

        message.AddTo("to@example.com");
        message.SetTemplateData(model);

        return message;
    }
}

SendGrid のアクセスキーは AzureWebJobsSendGridApiKey という名前で App Settings に追加しておけば使われます。特に別名を付ける必要もないとおもうので、デフォルトで良いと思います。

この関数を実行すると、前回と同様にメールの文面がレンダリングされて届きます。

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

Azure Functions でメールを送信する場合にはテンプレートを用意するのが面倒かつ、RazorEngine を使った場合には新しくインスタンスが立ち上がる度にテンプレートのコンパイルが必要になるので無駄が多いです。テンプレートのコンパイルは結構なコストです。

その点、Dynamic Templates を使うと Azure Functions では Queue からデータを受け取って、SendGrid に流すという単純な処理になるのでスケーリングも行いやすくなります。

テンプレートの管理が必要無いという以外にもメリットは多いです。公式クライアントも出ましたし。