.NET 6 と Daprを使った分散サービス開発 その9 Output Bindingでメールを送る


Output Binding (出力バインディング)を使ってメールを送る

前回は、Daprに備わっているBinding (バインディング)を用いて、RabbitMQを通じてフロントのAppからBackgroundで稼働するworker-serviceにメッセージを渡す方法などについて触れてきました。

今までの前提の上でバインディングの機能を追加しますので、このページから読まれている方は、前提として以下を読んできてください。


SMTPバインディング

今回は、SMTPのバインディングを用いてメールを送ってみようと思います。また、似たようなバインディングは Apple Push Notification Service や Twilio SendGrid , Twilio SMSなどもあり、ログイン時の多要素認証やメールでの確認など様々な方法で使えそうです。

アウトプットバインディングは、AppからDaprを通じて出力を行うバインディングになります。SMTPの場合は、メールを送るでしょうし、例えばDynamoDBやCosmosDBなどであれば、保存するでしょうし、前回取り上げたRabbitMQであれば指定されたExchangeにメッセージを送ることになります。

Dockerを使ったSMTPエミュレーターの導入

今回は、メールの送信を検証する際に便利なSMTPエミュレーターを使って検証をしたいと思います。

この手のは、いくつかありますが、今回はmailhogを使います。

docker run -d -p 8025:8025 -p 1025:1025 mailhog/mailhog

ローディングが終わったら、http://localhost:8025からmailhogを確認しましょう。SMTPポートは1025で起動しています。

image.png

componentsにファイルを追加

そろそろ、慣れてきたと思いますが、componentsフォルダに設定を追加します。
また、SMTPにはSMTP-Authに対応するオプションなど多岐にわたるオプションが用意されています。サンプルとして、公式からも以下のサンプルが提供されていますので、より詳しい設定はドキュメントや以下のYAMLなども参考にしてください。

ここでは、ローカルでデバッグする為に必要となる、最小限の設定を行います。

smtp.yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: smtp
  namespace: default
spec:
  type: bindings.smtp
  version: v1
  metadata:
  - name: host
    value: "127.0.0.1"
  - name: port
    value: "1025"

Appプロジェクトにコントローラーを追加

今回はこのコンポーネントのscopeを縛っていませんので、どのサービスからもあOutput Bindingが使えますが、Appプロジェクトにコントローラーを記述します。
AppプロジェクトのControllersフォルダにInvokeSmtpController.csという名称で追加しました。メールの送信先、送信元など追加のメタデータについてもセッティングしています。
各メタデータは本来YAMLで定義しますが、このように都度オーバーライドできます。

InvokeSmtpController.cs
using Dapr.Client;
using Microsoft.AspNetCore.Mvc;

namespace App.Controllers;

[ApiController]
[Route("[controller]")]
public class InvokeSmtpController : ControllerBase
{
    private readonly ILogger<InvokeSmtpController> _logger;

    private readonly DaprClient _daprClient;

    public InvokeSmtpController(ILogger<InvokeSmtpController> logger, DaprClient daprClient)
    {
        _logger = logger;
        _daprClient = daprClient;
    }

    [HttpGet(Name = "GetInvokeSmtpTrigger")]
    public async void GetAsync()
    {
        var body = "Hello from App via email!";
        var metadata = new Dictionary<string, string>
        {
            ["emailFrom"] = "[email protected]",
            ["emailTo"] = "[email protected]",
            ["subject"] = "Hello from App via email!"
        };

        await _daprClient.InvokeBindingAsync("smtp", "create", body, metadata);
        Console.WriteLine("Binding sent.");
    }

}

実行と確認

さっそく実行してみましょう。tye runで起動しましょう。

http://localhost:8000 のTye Dashboardから、サービス Appが起動しているエンドポイントURLのSwaggerにアクセスします。

リクエストを送信したら、Mailhogも確認してみましょう。
以下のようにメールが届いてます。