2023年4月にAzure Communication Service(ACS)がGAとなりました
techcommunity.microsoft.com ACSはEmailをはじめとして、複数のコミュニケーションに必要なツールを統合したAPIを提供しています(SMS等)
ACSはGAしてまだ時間がたっておらず(2023年6月時点)、
機能としてはまだ出そろっていない印象なのですがAzureの機能としてメールが送れるというのはありがたく
以前まではメール送信はSendGridをはじめとしたAzureの外に存在するAPIを使用するしかなかったですが
ACSの提供によりメール送信をAzureの外で完結することができ、
請求をサブスクリプションでまとめたり
ログをApplication Insightsに統合することができそうです
実装周り
Azure
公式ドキュメントにチュートリアルが展開されており 実際にACSからメールを送信するには、Email Communication Servicesのリソースを作成する必要があるが、 以下の3つを順にやっていけばAzure側の設定は完了する(はず) ※ カスタムドメイン設定はEmail Communication Servicesの設定する過程でAzureから無料のドメインの提供があるので技術検証目的としては不要
- クイック スタート: Azure Communication Service でメール通信サービスのリソースを作成して管理する - An Azure Communication Services quickstart | Microsoft Learn
- メール通信サービスにカスタムの検証済みドメインを追加する方法 - An Azure Communication Services quick start guide | Microsoft Learn
- クイック スタート - Azure Communication Service を使用して電子メールを送信する方法 - An Azure Communication Services Quickstart | Microsoft Learn
また、有識者による記事もあるのでこれらは非常に参考になる
- Azure Communication Services Emailを使ってメール配信サービスを作る! (zenn.dev)
- Azure Communication Services を使って Azure マネージドサービスのみでメールを送信出来るようになっていたので試してみた | DevelopersIO (classmethod.jp)
Azure 設定でEmail Communication Servicesにjapanがあるが、ACSにjapanが選べないのは罠だった
(両者は同じローケーションにいる必要があるので、Asia Pacific等の両者で選べるものである必要がある)
地理的な場所が同じドメインの接続のみが許可されます。 リソースの作成時に選択された通信リソースとメール通信リソースのデータの場所が同じであることを確認してください。 検証済みメール ドメインを Azure Communication Service リソースに接続する方法 - An Azure Communication Services quick start guide | Microsoft Learn
アプリケーション
.NETで実装する場合、SDK(Azure.Communication.Email)を仕様すれば比較的に簡単に実装することができ、
EmailClientを実装してSendAsyncで投げるだけ
以下は公式からの引用
string connectionString = Environment.GetEnvironmentVariable("COMMUNICATION_SERVICES_CONNECTION_STRING"); EmailClient emailClient = new EmailClient(connectionString); EmailSendOperation emailSendOperation = await emailClient.SendAsync( Azure.WaitUntil.Completed, sender, recipient, subject, htmlContent); EmailSendResult statusMonitor = emailSendOperation.Value; string operationId = emailSendOperation.Id;
各種プロパティについて
- COMMUNICATION_SERVICES_CONNECTION_STRING
- Azure PortalのACS画面、キーの管理から取得できる接続文字列
(ここはAAD認証もできるよう)
- Azure PortalのACS画面、キーの管理から取得できる接続文字列
- SendAsyncのプロパティ
- Azure.WaitUntil
- ACSのの処理がスタートもしくは、完了まで待機する
- WaitUntil 列挙型 (Azure) - Azure for .NET Developers | Microsoft Learn
- ここで、
WaitUntil.Started
を選択した場合、EmailSendResult statusMonitor = emailSendOperation.Value;
で例がが発生するのに注意
- sender
- 送信元のメールアドレス
- ここで使用できるのはEmail Communication Servicesの
ドメインをプロビジョニングする
->MailFrom addresses
で追加したメールアドレス(標準だとDoNotReplay@<ドメイン>)
- recipient
- 送信先のメールアドレス
- 複数のメールアドレスに送信するためのメソッドがオーバーロードとして
SendAsunc
に用意されているが送信者にほかのだれに送ったのがもろばれになる(Bccに設定もできるが...)
- 複数のメールアドレスに送信するためのメソッドがオーバーロードとして
- 送信先のメールアドレス
- subject
- 件名
- htmlContent
- メール本文、htmlコンテンツ
plain_text
を使用しえてhtmlではなく、テキストの送信もできる
- Azure.WaitUntil
料金体系
Azure Communication Services の価格 | Microsoft Azure
ACSにおける料金は料金 * 転送サイズで計算しており、単純にここだけを比較するのであれば
SendGridと比較して、かなり安くすむ印象
(SendGredのfreeプランを使用していれば当然SendGridのほうが安く済むが)
例えば、0.05MBのメール(直近で受信したMicroSoftのメールがそのくらいだった)を100000件送信すると
(ACSでは100000件/月の送信は通常だとクオーターの上限に引っかかる)
おおよそ3600円となる
これをSendGridで行うと最低でもEssentials 100kを使用する必要があるので
1000円程度安くなる
SendGridはEssentials -> Pro へプランをアップグレードすると価格が大きく上がるので月のメール送信数が多いほど、 ACSのほうがコストが低くなりやすい
また、ACSは従量課金なので年を通して送信数にむらっけがある場合もここでの試算以上にコストを抑えられる可能性がある
ただし、後述するがACSはGAからまだ時間がたっていないこともあり、
手前で機能を用意する必要があったりするので、
(例えば、送信結果をログとして記録するにはEventGridからトピックを受けとって処理する機能を実装する必要がある)
実装方法によるが実際は試算よりもコストがかかる可能性がある
機能周り
料金体系でも触れたが、ACSは確かにメールを送信するためのAPIを提供しているのだが
メールを送信に付随する機能はまだ実装されていない
例えば、いわゆるサプレッションリストみたいなものは現在存在しないようだ
とはいえ、不達時のサプレッションリストへの追加はともかく
ユーザー操作による購読解除はアカウント情報との紐づけが必要なので
ある程度は自分で実装をかんがえなければならない
(このあたり、Azure AD B2Cと連携してくれないかなと思ったり)
一方で、SMTPを基としたメール配信結果の取得とユーザーエンゲージメントの取得は可能であった
ACSはEventGridの機能を利用したサービスで、配信結果やユーザーエンゲージメントはEvent Gridのイベントとして作られる
(ので、topicを購読するための何かしらがいる)
Azure Communication Services - Email イベント - Azure Event Grid | Microsoft Learn
EmailDeliveryReportReceived
メール配信レポート
重要なのはstatus
でメール配信結果はおそらくこれを参照することになる
有効なステータス定義は以下の6種類
- Delivered
- Expanded
- Bounced
- Suppressed
- FilteredSpam
- Failed
以下、MicrosoftのDocumentから配信されるJson
[{ "id": "00000000-0000-0000-0000-000000000000", "topic": "/subscriptions/{subscription-id}/resourceGroups/{group-name}/providers/microsoft.communication/communicationservices/{communication-services-resource-name}", "subject": "sender/senderid@azure.com/message/00000000-0000-0000-0000-000000000000", "data": { "sender": "senderid@azure.com", "recipient": "receiver@azure.com", "messageId": "00000000-0000-0000-0000-000000000000", "status": "Delivered", "deliveryStatusDetails": { "statusMessage": "Status Message" }, "deliveryAttemptTimeStamp": "2020-09-18T00:22:20.2855749Z", }, "eventType": "Microsoft.Communication.EmailDeliveryReportReceived", "dataVersion": "1.0", "metadataVersion": "1", "eventTime": "2020-09-18T00:22:20Z" }]
EmailEngagementTrackingReportReceived
ユーザーエンゲージメントの結果
このイベントについては詳しく調査していないが、
engagementTypeがClick
かView
をとりうるらしい
このイベントについてはとりあえず中身をうけてLog Analyticsかなんかに投げておけば、 あとから参照するのにはこまらなさそう
以下、MicrosoftのDocumentから配信されるJson
[{ "id": "00000000-0000-0000-0000-000000000000", "topic": "/subscriptions/{subscription-id}/resourceGroups/{group-name}/providers/microsoft.communication/communicationservices/{communication-services-resource-name}", "subject": "sender/senderid@azure.com/message/00000000-0000-0000-0000-000000000000", "data": { "sender": "senderid@azure.com", "messageId": "00000000-0000-0000-0000-000000000000", "userActionTimeStamp": "2022-09-06T22:34:52.1303595+00:00", "engagementContext": "", "userAgent": "", "engagementType": "view" }, "eventType": "Microsoft.Communication.EmailEngagementTrackingReportReceived", "dataVersion": "1.0", "metadataVersion": "1", "eventTime": "2022-09-06T22:34:52.1303612Z" }]
制限について
ACSのEmailサービスにはいくつか制限がつけられているようで
Azure Communication Services のサービスの制限 - An Azure Communication Services how-to document | Microsoft Learn
特にメール送信するうえで厳しいのは
送信上限の制限で、これは30件/min かつ 100件/hとなっている
このままではマーケティング目的のメール配信には到たえられないので
クオーター上限引き上げのサポートリクエストを作る必要がある
制限が厳しいのはACS側でオプトアウトのような
メール配信にかかわる機能を持たないがゆえに
Azure側でメール配信のコンプライアンス的な何かが担保できないからなのではという考察
所感
ACSのEmailサービスは既存のメール配信のSASSと比較してAzure側内で完結できるがゆえの恩恵は得られる幹事はするが
GAとなって日が浅いこともあって メール配信に付随するいくつかの機能を手前で準備しなければならない
特に、マーケティング目的での大量のメール配信時の負荷に対するもろもろに懸念が残る
大量のメール配信をしない小規模なサービスにおいて 実験的に導入するのは良いが
ある程度の規模を持つプロダクトへの導入は慎重になったほうがよいかも