Azure Communication Services 新機能 Email Service をデプロイ、メール送信を Web API 化 [BUILD2022 Update] ②Azure Functions で Web API 化

Azure Communication Services は、リアルタイム コミュニケーション基盤となるサービスで、テキスト | 音声 | ビデオ によるコミュニケーションのハブとなり、接続やコントロールを行うアプリやサービスを SDK などを用いて容易に開発できます。

今回は BUILD 2022 で公開された、Azure Communication Services (以下 ACS) の Email Service (以下 ACS Email) を利用してメール送信サービスをデプロイ(作成)して、Web API でメールが送信できる仕組みを Azure Function を利用して構築してみます。

1. [ACS および ACS Mail のデプロイと設定](https://qiita.com/annie/items/9d29417426af82af70d4)
2. **ACS および ACS Mail を使ったメール送信 Web API の作成** ← イマココ

# 手順

## 0. 事前準備

### Azure サブスクリプション申し込み、ACS & ACS Mail の設定

①サービスのデプロイと設定 の手順で、ACS のデプロイと設定を行っておきます。

### メールが受信できるアカウント

ACS Email からメールを受信できるアカウントをご準備ください。(Hotmail,Gmail 他、何でもOKです)

## 2-1. ACS 経由でメール送信する仕組み

ACS Mail はクライアントライブラリーから操作します。
.NET/C# の場合 は Azure.Communication.Email というライブラリーを利用します。

https://github.com/Azure/azure-sdk-for-net/blob/Azure.Communication.Email_1.0.0-beta.1/sdk/communication/Azure.Communication.Email/README.md

NuGet (.NET/C#) はこちら。

https://www.nuget.org/packages/Azure.Communication.Email/

コードサンプルもあります。

https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.Email_1.0.0-beta.1/sdk/communication/Azure.Communication.Email/samples

使い方は、Azure.Communication.Email.EmailClient を作成し、EmailMessage をセットして送信 (SendAsync) します。(※非同期の場合。以下同様)

```SendMailSampleUsingACS.cs
using Azure.Communication.Email;
using Azure.Communication.Email.Models;

EmailClient client = new EmailClient("YOUR_CONNECTION_STRING");
EmailMessage message = new EmailMessage(
                    "YOUR_ACS_EMAIL",
                    new EmailContent("EMAIL_SUBJECT") { 
                                        PlainText = "EMAIL_PLAIN_TEXT",
                                        Html = "EMAIL_HTML_CONTENT" },
                    new EmailRecipients({"RECIPIENT_EMAIL", "RECIPIENT_NAME"});
SendEmailResult result = await client.SendAsync(message);
```

送信の戻り値 (SendMailResult) に付与される MessageId で送信ステータスを確認(GetSendStatusAsync)できます。SendStatus.OutForRelivery になったらメール送信は完了です。

```SendMailSampleUsingACS.cs
SendEmailResult result = await client.SendAsync(message);

string messageId = result.MessageId;
if (!string.IsNullOrEmpty(messageId))
{
    SendStatusResult status = await client.GetSendStatusAsync(messageId);
    if (status.Status == SendStatus.OutForDelivery)
    {
        //メール送信完了タスク
    }
}
```

## 2-2. Azure Functions で ACS Email を Web API 化

いよいよ ACS Email を Web API に実装していきます。
ACSへの接続や Email はセットしておき、Web API で送信先(メールアドレス、名前)、メールの内容を Request (POST) すると、ACS Email を通じてメールが送信されるようにします。
出来上がりはこのような感じです。

![ACSEmailSamples202206_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117583/57fcfd70-d3cc-1aa6-8c3f-4bdc76d20818.png)

### Web API が受け取る情報 (JSON) を定める

以下の項目をJSONで受け取ることにします。

- **Email**、**Name** (Email 宛先名):　一度に複数人指定できるようにします
- メールの **Subject** (件名)、**PlainContent** (本文(Text)), **HtmlContent** (本文(HTML)) 

こんな形の JSON で情報を受け取れるようにします。

```format.json
{
    Recipients: [
        { Email: "user01@example.com", Name: "User01" }, 
        { Email: "user02@example.com", Name: "User02" },
            :
    ],
    "Subject": "Hello from ACS Mail Sender",
    "PlainContent":"Hello from ACS (plain text) \n Happy Learning!",
    "HtmlCOntent":"<html><body><h4>Hello from ACS (HTML)</h4><p>Happy Learning!</p></body></html>"
}
```

受け取る JSON に合わせて、デシリアライズするクラスをこのように作成しておきます。

```SendMailFunc.cs
// POSTで受信する情報 (JSON) のデシリアライズ用クラス
public class SendMailProperties
{
    public List<Recipient> Recipients { get; set; }
    public string Subject { get; set; }
    public string PlainContent { get; set; }
    public string HtmlContent { get; set; }
}
public class Recipient
{
    public string Email { get; set; }
    public string Name { get; set; }
}
```

### Azure Functions (HTTP Trigger) で実装

Azure Function (HTTP Trigger) を作成し、POST で受信した Body を受け取ってデシリアライズします。

```SendMailFunc.cs
public static class SendMailFunc
{
    [FunctionName("SendMail")]
    public static async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger log)
    {
        log.LogInformation("C# HTTP trigger function processed a request.");
        SendMailProperties properties = await JsonSerializer.DeserializeAsync<SendMailProperties>(req.Body);
```

ローカルに保存しておいた以下の情報をセットして、

- "YOUR_ACS_CONNECTION_STRING": **ACS 接続文字列**
- "ACSMailSender@YOUR_ACS_EMAIL_DOMAIN.azurecomm.net": ACS Mail ドメインの **メール送信アドレス**

JSON から取得した情報から以下のように **EmailMessage** を作成して、**EmailClient.SendAsync** で ACS に送信します。

```SendMailFunc.cs
    EmailClient client = new EmailClient("YOUR_ACS_CONNECTION_STRING");
    string sender = "ACSMailSender@YOUR_ACS_EMAIL_DOMAIN.azurecomm.net";
    :

    EmailMessage message = new EmailMessage(
        sender,
        new EmailContent(properties.Subject) { PlainText = properties.PlainContent, Html = properties.HtmlContent },
        new EmailRecipients(properties.Recipients.Select(x => new EmailAddress(x.Email, x.Name)).ToList())
    );
    :

    SendEmailResult result = await client.SendAsync(message);
    :
```

最終的なソースコードはこのような感じになります。

https://github.com/ayako/ACSEmailSamples202206/blob/main/SendMailFunc.cs