你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
使用高级消息传递发送 WhatsApp 消息
本文介绍如何使用高级通信消息 SDK 发送 WhatsApp 模板消息。
先决条件
- 使用 Azure 通信服务资源注册 WhatsApp 业务帐户。
- 创建 WhatsApp 模板消息。
- 用于接收消息的活动的 WhatsApp 电话号码。
对象模型
以下类和接口用于处理适用于 .NET 的 Azure 通信服务消息 SDK 的某些主要功能。
类名 | 说明 |
---|---|
NotificationMessagesClient |
连接到 Azure 通信服务资源。 它会发送消息。 |
MessageTemplate |
定义你为消息使用哪个模板以及模板属性的内容。 |
TemplateNotificationContent |
定义要发送的模板消息的“发送对象”和“内容”。 |
注意
有关详细信息,请参阅适用于 .NET 的 Azure SDK 参考文章:Azure.Communication.Messages 命名空间。
支持的 WhatsApp 模板类型
模板类型 | 说明 |
---|---|
基于文本的消息模板 | WhatsApp 消息模板是带有或不带参数的特定消息格式。 |
基于媒体的消息模板 | WhatsApp 消息模板,其中包含标头组件的媒体参数。 |
交互式消息模板 | 交互式消息模板通过使用组件对象包含交互式按钮来扩展可以发送给收件人的内容。 同时支持“行动号召”和“快速回复”。 |
基于位置的消息模板 | WhatsApp 消息模板,其位置参数以标头组件的经度和纬度表示。 |
通用配置
按照以下步骤将必要的代码片段添加到 Program.cs
文件的 Main 函数。
创建和管理 WhatsApp 模板消息
WhatsApp 消息模板是企业用来向选择接收通知的人员发送通知或客户关怀消息的特定消息格式。 消息可以包含约会提醒、发货信息、问题解决方案或付款更新。 在开始使用高级消息传递 SDK 发送模板化消息之前,用户需要在 WhatsApp 业务平台中创建所需的模板。
有关 WhatsApp 对于模板的要求的详细信息,请参阅 WhatsApp 业务平台 API 参考:
对客户端进行身份验证
消息 SDK 使用 NotificationMessagesClient
发送消息。
NotificationMessagesClient
方法使用从 Azure 门户中的 Azure 通信服务资源获取的连接字符串来进行身份验证。 有关连接字符串的详细信息,请参阅访问连接字符串和服务终结点 (access-your-connection-strings-and-service-endpoints)。
为简单起见,本快速入门使用连接字符串进行身份验证。 在生产环境中,我们建议使用服务主体。
从 Azure 门户中的 Azure 通信服务资源获取连接字符串。 在左侧,导航到“Keys
”选项卡。复制主键的 Connection string
字段。 连接字符串采用 endpoint=https://{your Azure Communication Services resource name}.communication.azure.com/;accesskey={secret key}
格式。
将环境变量 COMMUNICATION_SERVICES_CONNECTION_STRING
设置为连接字符串的值。
打开控制台窗口并输入以下命令:
setx COMMUNICATION_SERVICES_CONNECTION_STRING "<your connection string>"
添加环境变量后,可能需要重启任何正在运行的、需要读取环境变量的程序(包括控制台窗口)。 例如,如果使用 Visual Studio 作为编辑器,请在运行示例之前重启 Visual Studio。
有关如何为系统设置环境变量的详细信息,请按照在环境变量中存储连接字符串的步骤操作。
若要实例化 NotificationMessagesClient
,请将以下代码添加到 Main
方法:
// Retrieve connection string from environment variable
string connectionString =
Environment.GetEnvironmentVariable("COMMUNICATION_SERVICES_CONNECTION_STRING");
// Instantiate the client
var notificationMessagesClient = new NotificationMessagesClient(connectionString);
设置频道注册 ID
已在频道注册期间创建了频道注册 ID GUID。 在门户中通过 Azure 通信服务资源的“频道”选项卡可以找到它。
将它分配给名为 channelRegistrationId 的变量。
var channelRegistrationId = new Guid("<your channel registration ID GUID>");
设置收件人列表
需要提供与 WhatsApp 帐户关联的有效电话号码。 此 WhatsApp 帐户会接收本快速入门中发送的模版、文本和媒体消息。
对于此示例,可以使用个人电话号码。
收件人电话号码不能是与 WhatsApp 频道注册关联的业务电话号码(发件人 ID)。 发件人 ID 显示为发送给收件人的文本和媒体消息的发件人。
电话号码必须包括国家/地区代码。 有关电话号码格式的详细信息,请查看 WhatsApp 文档中的电话号码格式。
注意
收件人列表中当前仅支持一个电话号码。
创建如下所示的收件人列表:
var recipientList = new List<string> { "<to WhatsApp phone number>" };
示例:
// Example only
var recipientList = new List<string> { "+14255550199" };
开始在企业和 WhatsApp 用户之间发送消息
可通过下面两种方式之一发起 WhatsApp Business 帐户与 WhatsApp 用户之间的对话:
- 企业向 WhatsApp 用户发送模板消息。
- WhatsApp 用户向企业号码发送任何消息。
企业无法发起交互式对话。 企业只能在收到用户的消息后发送交互式消息。 企业只能在活动对话期间向用户发送交互式消息。 一旦 24 小时对话窗口过期,只有用户才能重新开始交互式对话。 有关对话的详细信息,请访问 WhatsApp 业务平台查看定义。
若要从个人 WhatsApp 帐户发起交互式对话,请向自己的企业号码(发送方 ID)发送消息。
设置环境
创建 .NET 项目
若要创建项目,请按照使用 Visual Studio 创建 .NET 控制台应用程序的教程进行操作。
若要编译代码,请按 Ctrl+F7。
安装包
将 Azure.Communication.Messages NuGet 包安装到你的 C# 项目。
- 打开 NuGet 包管理器:
Project
>Manage NuGet Packages...
。 - 搜索包
Azure.Communication.Messages
。 - 安装最新版本。
设置应用框架
在文本编辑器中打开 Program.cs
文件。
使用以下代码替换 Program.cs
的内容:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Azure;
using Azure.Communication.Messages;
namespace AdvancedMessagingQuickstart
{
class Program
{
public static async Task Main(string[] args)
{
Console.WriteLine("Azure Communication Services - Advanced Messages quickstart samples.");
// Quickstart code goes here
}
}
}
若要使用高级消息传递功能,请添加一个 using
指令以包含 Azure.Communication.Messages
命名空间。
using Azure.Communication.Messages;
代码示例
按照以下步骤将所需的代码片段添加到 Program.cs
文件的 Main 函数。
- 列出 Azure 门户中的 WhatsApp 模板。
- 发送不带参数的模板消息。
- 发送正文中使用文本参数的模板消息。
- 发送标头中使用媒体参数的模板消息。
- 发送标头中带有位置的模板消息。
- 发送带有快速回复按钮的模板消息。
- 发送带有动态链接的行动号召按钮的模板消息。
- 发送带有静态链接的行动号召按钮的模板消息。
在 Azure 门户中列出 WhatsApp 模板
可以通过转到“Azure 通信服务资源”>“高级消息传递”>“模板”来查看 Azure 门户中的模板。
请选择模板以了解详细信息。
模板详细信息的 content
字段可以包含参数绑定。 参数绑定可以表示为:
- 具有
IMAGE
等值的format
字段。 - 双括号括起数字,例如
{{1}}
。 该数字从 1 开始索引,表示创建消息模板时必须提供绑定值的顺序。
或者,也可以通过“WhatsApp 管理器”>“帐户工具”>“消息模板”查看和编辑所有 WhatsApp 业务帐户的模板。
若要以编程方式列出模板,则可以获取用于频道 ID 的所有模板,如下所示:
MessageTemplateClient messageTemplateClient = new MessageTemplateClient(connectionString);
Pageable<MessageTemplateItem> templates = messageTemplateClient.GetTemplates(channelRegistrationId);
发送不带参数的模板消息
如果模板不需要参数,则创建 MessageTemplate
时无需提供任何值或绑定。
var messageTemplate = new MessageTemplate(templateName, templateLanguage);
示例
sample_template
不带任何参数。
通过引用目标模板的名称和语言来组合 MessageTemplate
。
string templateName = "sample_template";
string templateLanguage = "en_us";
var sampleTemplate = new MessageTemplate(templateName, templateLanguage);
发送正文中使用文本参数的模板消息
使用 MessageTemplateText
定义正文中用双括号括起的数字(例如 {{1}}
)表示的参数。 该数字(索引从 1 开始)表示创建消息模板时必须提供绑定值的顺序。 包含模板中没有的参数是无效的。
带有两个参数的模板定义:
{
"type": "BODY",
"text": "Message with two parameters: {{1}} and {{2}}"
}
示例
sample_shipping_confirmation
模板:
在此示例中,模板的正文有一个参数:
{
"type": "BODY",
"text": "Your package has been shipped. It will be delivered in {{1}} business days."
},
参数使用 MessageTemplateValue
值和 MessageTemplateWhatsAppBindings
绑定定义。 使用值和绑定来组合 MessageTemplate
。
string templateName = "sample_shipping_confirmation";
string templateLanguage = "en_us";
var threeDays = new MessageTemplateText("threeDays", "3");
WhatsAppMessageTemplateBindings bindings = new();
bindings.Body.Add(new(threeDays.Name));
MessageTemplate shippingConfirmationTemplate = new(templateName, templateLanguage);
shippingConfirmationTemplate.Bindings = bindings;
shippingConfirmationTemplate.Values.Add(threeDays);
发送标头中带有媒体参数的模板消息
使用 MessageTemplateImage
、 MessageTemplateVideo
或 MessageTemplateDocument
在标头中定义媒体参数。
标头中带图像媒体参数的模板定义:
{
"type": "HEADER",
"format": "IMAGE"
},
format
可具有 WhatsApp 支持的不同媒体类型。 在 .NET SDK 中,每个媒体类型都使用相应的 MessageTemplateValue 类型。
Format | MessageTemplateValue 类型 | 文件类型 |
---|---|---|
IMAGE |
MessageTemplateImage |
png、jpg |
VIDEO |
MessageTemplateVideo |
mp4 |
DOCUMENT |
MessageTemplateDocument |
有关支持的媒体类型和大小限制的更多信息,请参阅 WhatsApp 的消息媒体文档。
图像媒体消息的模板程序集:
var url = new Uri("< Your media URL >");
var media = new MessageTemplateImage("image", url);
WhatsAppMessageTemplateBindings bindings = new();
bindings.Header.Add(new(media.Name));
var messageTemplate = new MessageTemplate(templateName, templateLanguage);
template.Bindings = bindings;
template.Values.Add(media);
示例
sample_movie_ticket_confirmation
模板:
在此示例中,模板的标头需要一个图像:
{
"type": "HEADER",
"format": "IMAGE"
},
模板正文需要四个文本参数:
{
"type": "BODY",
"text": "Your ticket for *{{1}}*\n*Time* - {{2}}\n*Venue* - {{3}}\n*Seats* - {{4}}"
},
创建一个 MessageTemplateImage
和四个 MessageTemplateText
变量。 然后,按照参数在模板内容中出现的顺序提供参数,组合 MessageTemplateValue
和 MessageTemplateWhatsAppBindings
的列表。
string templateName = "sample_movie_ticket_confirmation";
string templateLanguage = "en_us";
var imageUrl = new Uri("https://aka.ms/acsicon1");
var image = new MessageTemplateImage("image", imageUrl);
var title = new MessageTemplateText("title", "Contoso");
var time = new MessageTemplateText("time", "July 1st, 2023 12:30PM");
var venue = new MessageTemplateText("venue", "Southridge Video");
var seats = new MessageTemplateText("seats", "Seat 1A");
WhatsAppMessageTemplateBindings bindings = new();
bindings.Header.Add(new(image.Name));
bindings.Body.Add(new(title.Name));
bindings.Body.Add(new(time.Name));
bindings.Body.Add(new(venue.Name));
bindings.Body.Add(new(seats.Name));
MessageTemplate movieTicketConfirmationTemplate = new(templateName, templateLanguage);
movieTicketConfirmationTemplate.Values.Add(image);
movieTicketConfirmationTemplate.Values.Add(title);
movieTicketConfirmationTemplate.Values.Add(time);
movieTicketConfirmationTemplate.Values.Add(venue);
movieTicketConfirmationTemplate.Values.Add(seats);
movieTicketConfirmationTemplate.Bindings = bindings;
更多示例
发送标头中带有位置的模板消息
使用 MessageTemplateLocation
定义标头中的位置参数。
标头组件的模板定义,需要的位置为:
{
"type": "header",
"parameters": [
{
"type": "location",
"location": {
"latitude": "<LATITUDE>",
"longitude": "<LONGITUDE>",
"name": "<NAME>",
"address": "<ADDRESS>"
}
}
]
}
format
可能需要不同的媒体类型。 在 .NET SDK 中,每个媒体类型都使用相应的 MessageTemplateValue 类型。
属性 | 说明 | 类型 |
---|---|---|
ADDRESS |
地址将显示在 NAME 值之后、消息顶部通用地图下方。 |
string |
LATITUDE |
位置纬度。 | double |
LONGITUDE |
位置经度。 | double |
LOCATIONNAME |
文本将显示在紧邻消息顶部通用地图下方。 | string |
有关基于位置的模板的详细信息,请参阅 WhatsApp 的消息媒体文档。
示例
sample_movie_location
模板:
基于位置的消息模板程序集:
var location = new MessageTemplateLocation("location");
location.LocationName = "Pablo Morales";
location.Address = "1 Hacker Way, Menlo Park, CA 94025";
location.Position = new Azure.Core.GeoJson.GeoPosition(longitude: 122.148981, latitude: 37.483307);
WhatsAppMessageTemplateBindings location_bindings = new();
location_bindings.Header.Add(new(location.Name));
var messageTemplateWithLocation = new MessageTemplate(templateNameWithLocation, templateLanguage);
messageTemplateWithLocation.Values.Add(location);
messageTemplateWithLocation.Bindings = location_bindings;
发送带有快速回复按钮的模板消息
使用 MessageTemplateQuickAction
来定义快速回复按钮的有效负载并且 MessageTemplateQuickAction
对象具有以下三个属性。
属性 | 说明 | 类型 |
---|---|---|
名称 |
name 用于查找 MessageTemplateWhatsAppBindings 中的值。 |
string |
文本 | 可选的快速操作 text 。 |
string |
有效负载 | 如果用户选择按钮,则分配给该按钮的 payload 在消息回复中可用。 |
string |
带有快速回复按钮的模板定义:
{
"type": "BUTTONS",
"buttons": [
{
"type": "QUICK_REPLY",
"text": "Yes"
},
{
"type": "QUICK_REPLY",
"text": "No"
}
]
}
按钮在模板定义中出现的顺序必须与使用 MessageTemplateWhatsAppBindings
创建绑定时定义按钮的顺序匹配。
有关用户快速回复响应中有效负载的更多信息,请参阅关于接收来自快速回复按钮的回叫的 WhatsApp 文档。
示例
sample_issue_resolution
模板:
模板正文需要一个文本参数:
{
"type": "BODY",
"text": "Hi {{1}}, were we able to solve the issue that you were facing?"
},
模板包含两个预填充的回复按钮,Yes
和 No
。
{
"type": "BUTTONS",
"buttons": [
{
"type": "QUICK_REPLY",
"text": "Yes"
},
{
"type": "QUICK_REPLY",
"text": "No"
}
]
}
创建一个 MessageTemplateText
和两个 MessageTemplateQuickAction
变量。 然后,按照模板内容中参数出现的顺序提供参数,组合 MessageTemplateValue
和 MessageTemplateWhatsAppBindings
的列表。 在定义绑定的按钮时,顺序也很重要。
string templateName = "sample_issue_resolution";
string templateLanguage = "en_us";
var name = new MessageTemplateText(name: "name", text: "Kat");
var yes = new MessageTemplateQuickAction(name: "Yes"){ Payload = "Kat said yes" };
var no = new MessageTemplateQuickAction(name: "No") { Payload = "Kat said no" };
WhatsAppMessageTemplateBindings bindings = new();
bindings.Body.Add(new(name.Name));
bindings.Buttons.Add(new(WhatsAppMessageButtonSubType.QuickReply.ToString(), yes.Name));
bindings.Buttons.Add(new(WhatsAppMessageButtonSubType.QuickReply.ToString(), no.Name));
MessageTemplate issueResolutionTemplate = new(templateName, templateLanguage);
issueResolutionTemplate.Values.Add(name);
issueResolutionTemplate.Values.Add(yes);
issueResolutionTemplate.Values.Add(no);
issueResolutionTemplate.Bindings = bindings;
发送带有动态链接的行动号召按钮的模板消息
使用 MessageTemplateQuickAction
来定义行动号召按钮的 URL 后缀并且 MessageTemplateQuickAction
对象具有以下两个属性。
属性 | 说明 | 类型 |
---|---|---|
名称 |
name 用于查找 MessageTemplateWhatsAppBindings 中的值。 |
string |
文本 | 附加到 URL 的 text 。 |
string |
模板定义按钮:
{
"type": "BUTTONS",
"buttons": [
{
"type": "URL",
"text": "Take Survey",
"url": "https://www.example.com/{{1}}"
}
]
}
按钮在模板定义中出现的顺序必须与使用 MessageTemplateWhatsAppBindings
创建绑定时定义按钮的顺序匹配。
示例
sample_purchase_feedback
模板:
此示例模板向消息添加一个带有动态 URL 链接的按钮。 它还在标头中使用一个图像,在正文中使用一个文本参数。
在此示例中,模板的标头需要一个图像:
{
"type": "HEADER",
"format": "IMAGE"
},
模板正文需要一个文本参数:
{
"type": "BODY",
"text": "Thank you for purchasing {{1}}! We value your feedback and would like to learn more about your experience."
},
该模板包含带有一个参数的动态 URL 按钮:
{
"type": "BUTTONS",
"buttons": [
{
"type": "URL",
"text": "Take Survey",
"url": "https://www.example.com/{{1}}"
}
]
}
创建一个 MessageTemplateImage
、一个 MessageTemplateText
和一个 MessageTemplateQuickAction
变量。 然后,按照模板内容中参数出现的顺序提供参数,组合 MessageTemplateValue
和 MessageTemplateWhatsAppBindings
的列表。 在定义绑定的按钮时,顺序也很重要。
string templateName = "sample_purchase_feedback";
string templateLanguage = "en_us";
var imageUrl = new Uri("https://aka.ms/acsicon1");
var image = new MessageTemplateImage(name: "image", uri: imageUrl);
var product = new MessageTemplateText(name: "product", text: "coffee");
var urlSuffix = new MessageTemplateQuickAction(name: "text") { Text = "survey-code" };
WhatsAppMessageTemplateBindings bindings = new();
bindings.Header.Add(new(image.Name));
bindings.Body.Add(new(product.Name));
bindings.Buttons.Add(new(WhatsAppMessageButtonSubType.Url.ToString(), urlSuffix.Name));
MessageTemplate purchaseFeedbackTemplate = new("sample_purchase_feedback", "en_us");
purchaseFeedbackTemplate.Values.Add(image);
purchaseFeedbackTemplate.Values.Add(product);
purchaseFeedbackTemplate.Values.Add(urlSuffix);
purchaseFeedbackTemplate.Bindings = bindings;
发送带有静态链接的行动号召按钮的模板消息
对于静态链接,无需包含 MessageTemplateQuickAction
模型,因为 WhatsApp 模板具有静态 CallToAction
链接,无需用户输入。
模板定义按钮:
{
"type": "BUTTONS",
"buttons": [
{
"type": "URL",
"text": "Take Survey",
"url": "https://www.example.com/{{1}}"
}
]
}
示例
purchase_feedback_static
模板:
此示例模板向消息添加了一个带有动态 URL 链接的按钮。 它还在标头中使用一个图像,在正文中使用一个文本参数。
在此示例中,模板的标头需要一个图像:
{
"type": "HEADER",
"format": "IMAGE"
},
模板正文需要一个文本参数:
{
"type": "BODY",
"text": "Hello {{1}}, \nHope you are great day!.\n Please click on given link to explore about our program.."
},
该模板包含带有一个参数的动态 URL 按钮:
{
"type": "BUTTONS",
"buttons": [
{
"type": "URL",
"text": "Take Survey",
"url": "https://www.example.com/"
}
]
}
创建一个 MessageTemplateImage
,一个 MessageTemplateText
。 然后,按照模板内容中参数出现的顺序提供参数,组合 MessageTemplateValue
和 MessageTemplateWhatsAppBindings
的列表。 在定义绑定的按钮时,顺序也很重要。
// Send sample template sample_template
string templateNameWithcta = "purchase_feedback_static";
var bodyParam1 = new MessageTemplateText(name: "customer", text: "Joe");
var image = new MessageTemplateImage("image", new Uri("https://aka.ms/acsicon1"));
WhatsAppMessageTemplateBindings cta_bindings = new();
cta_bindings.Body.Add(new(bodyParam1.Name));
cta_bindings.Header.Add(new(image.Name));
var messageTemplateWithcta = new MessageTemplate(templateNameWithcta, templateLanguage);
messageTemplateWithcta.Values.Add(bodyParam1);
messageTemplateWithcta.Values.Add(image);
messageTemplateWithcta.Bindings = cta_bindings;
TemplateNotificationContent templateContent4 =
new TemplateNotificationContent(channelRegistrationId, recipientList, messageTemplateWithcta);
Response<SendMessageResult> sendTemplateMessageResult4 =
notificationMessagesClient.Send(templateContent4);
运行代码
构建程序并运行。
若要向 WhatsApp 用户发送文本或媒体消息,WhatsApp Business 帐户和 WhatsApp 用户之间必须有活动的会话。
如果你没有活动的对话,出于本示例的目的,你可以在发送模板消息和发送文本消息之间添加等待时间。 增加这一延迟后,你就有足够的时间来在用户的 WhatsApp 帐户上回复企业。 作为参考,给定的示例在发送下一条消息之前会提示用户手动输入。 有关详细信息,请参阅示例代码的完整示例。 如果成功,你会在用户的 WhatsApp 帐户上收到三条消息。
构建程序并运行。
dotnet build
dotnet run
完整代码示例
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Azure;
using Azure.Communication.Messages;
using Azure.Communication.Messages.Models.Channels;
namespace SendTemplateMessages
{
class Program
{
public static async Task Main(string[] args)
{
Console.WriteLine("Azure Communication Services - Send WhatsApp Template Messages\n");
string connectionString = Environment.GetEnvironmentVariable("COMMUNICATION_SERVICES_CONNECTION_STRING");
NotificationMessagesClient notificationMessagesClient = new NotificationMessagesClient(connectionString);
var channelRegistrationId = new Guid("<Your Channel ID>");
var recipientList = new List<string> { "<Recipient's WhatsApp Phone Number>" };
// List out available templates for a channel ID
MessageTemplateClient messageTemplateClient = new MessageTemplateClient(connectionString);
Pageable<MessageTemplateItem> templates = messageTemplateClient.GetTemplates(channelRegistrationId);
foreach (WhatsAppMessageTemplateItem template in templates)
{
Console.WriteLine("Name: {0}\tLanguage: {1}\tStatus: {2}\tContent: {3}\n",
template.Name, template.Language, template.Status, template.Content);
}
// Send Sample Template sample_template
MessageTemplate sampleTemplate = AssembleSampleTemplate();
var sampleTemplateContent = new TemplateNotificationContent(channelRegistrationId, recipientList, sampleTemplate);
var result = await notificationMessagesClient.SendAsync(sampleTemplateContent);
PrintResponse(result);
// Send sample template sample_shipping_confirmation
MessageTemplate shippingConfirmationTemplate = AssembleSampleShippingConfirmation();
var shippingConfirmationTemplateContent = new TemplateNotificationContent(channelRegistrationId, recipientList, shippingConfirmationTemplate);
result = await notificationMessagesClient.SendAsync(shippingConfirmationTemplateContent);
PrintResponse(result);
// Send sample template sample_movie_ticket_confirmation
MessageTemplate movieTicketConfirmationTemplate = AssembleSampleMovieTicketConfirmation();
var movieTicketConfirmationTemplateContent = new TemplateNotificationContent(channelRegistrationId, recipientList, movieTicketConfirmationTemplate);
result = await notificationMessagesClient.SendAsync(movieTicketConfirmationTemplateContent);
PrintResponse(result);
// Send sample template sample_happy_hour_announcement
MessageTemplate happyHourTemplate = AssembleSampleHappyHourAnnouncement();
var happyHourTemplateContent = new TemplateNotificationContent(channelRegistrationId, recipientList, happyHourTemplate);
result = await notificationMessagesClient.SendAsync(happyHourTemplateContent);
PrintResponse(result);
// Send sample template sample_flight_confirmation
MessageTemplate flightConfirmationTemplate = AssembleSampleFlightConfirmation();
var flightConfirmationTemplateContent = new TemplateNotificationContent(channelRegistrationId, recipientList, flightConfirmationTemplate);
result = await notificationMessagesClient.SendAsync(flightConfirmationTemplateContent);
PrintResponse(result);
// Send sample template sample_issue_resolution
MessageTemplate issueResolutionTemplate = AssembleSampleIssueResolution();
var issueResolutionTemplateContent = new TemplateNotificationContent(channelRegistrationId, recipientList, issueResolutionTemplate);
result = await notificationMessagesClient.SendAsync(issueResolutionTemplateContent);
PrintResponse(result);
// Send sample template sample_purchase_feedback
MessageTemplate purchaseFeedbackTemplate = AssembleSamplePurchaseFeedback();
var purchaseFeedbackTemplateContent = new TemplateNotificationContent(channelRegistrationId, recipientList, purchaseFeedbackTemplate);
result = await notificationMessagesClient.SendAsync(purchaseFeedbackTemplateContent);
PrintResponse(result);
Console.WriteLine("Press any key to exit.");
Console.ReadKey(true);
}
public static MessageTemplate AssembleSampleTemplate()
{
string templateName = "sample_template";
string templateLanguage = "en_us";
return new MessageTemplate(templateName, templateLanguage);
}
public static MessageTemplate AssembleSampleShippingConfirmation()
{
string templateName = "sample_shipping_confirmation";
string templateLanguage = "en_us";
var threeDays = new MessageTemplateText("threeDays", "3");
WhatsAppMessageTemplateBindings bindings = new();
bindings.Body.Add(new(threeDays.Name));
MessageTemplate shippingConfirmationTemplate = new(templateName, templateLanguage);
shippingConfirmationTemplate.Bindings = bindings;
shippingConfirmationTemplate.Values.Add(threeDays);
return shippingConfirmationTemplate;
}
public static MessageTemplate AssembleSampleMovieTicketConfirmation()
{
string templateName = "sample_movie_ticket_confirmation";
string templateLanguage = "en_us";
var imageUrl = new Uri("https://aka.ms/acsicon1");
var image = new MessageTemplateImage("image", imageUrl);
var title = new MessageTemplateText("title", "Contoso");
var time = new MessageTemplateText("time", "July 1st, 2023 12:30PM");
var venue = new MessageTemplateText("venue", "Southridge Video");
var seats = new MessageTemplateText("seats", "Seat 1A");
WhatsAppMessageTemplateBindings bindings = new();
bindings.Header.Add(new(image.Name));
bindings.Body.Add(new(title.Name));
bindings.Body.Add(new(time.Name));
bindings.Body.Add(new(venue.Name));
bindings.Body.Add(new(seats.Name));
MessageTemplate movieTicketConfirmationTemplate = new(templateName, templateLanguage);
movieTicketConfirmationTemplate.Values.Add(image);
movieTicketConfirmationTemplate.Values.Add(title);
movieTicketConfirmationTemplate.Values.Add(time);
movieTicketConfirmationTemplate.Values.Add(venue);
movieTicketConfirmationTemplate.Values.Add(seats);
movieTicketConfirmationTemplate.Bindings = bindings;
return movieTicketConfirmationTemplate;
}
public static MessageTemplate AssembleSampleHappyHourAnnouncement()
{
string templateName = "sample_happy_hour_announcement";
string templateLanguage = "en_us";
var videoUrl = new Uri("< Your .mp4 Video URL >");
var video = new MessageTemplateVideo("video", videoUrl);
var venue = new MessageTemplateText("venue", "Fourth Coffee");
var time = new MessageTemplateText("time", "Today 2-4PM");
WhatsAppMessageTemplateBindings bindings = new();
bindings.Header.Add(new(video.Name));
bindings.Body.Add(new(venue.Name));
bindings.Body.Add(new(time.Name));
MessageTemplate happyHourAnnouncementTemplate = new(templateName, templateLanguage);
happyHourAnnouncementTemplate.Values.Add(venue);
happyHourAnnouncementTemplate.Values.Add(time);
happyHourAnnouncementTemplate.Values.Add(video);
happyHourAnnouncementTemplate.Bindings = bindings;
return happyHourAnnouncementTemplate;
}
public static MessageTemplate AssembleSampleFlightConfirmation()
{
string templateName = "sample_flight_confirmation";
string templateLanguage = "en_us";
var documentUrl = new Uri("< Your .pdf document URL >");
var document = new MessageTemplateDocument("document", documentUrl);
var firstName = new MessageTemplateText("firstName", "Kat");
var lastName = new MessageTemplateText("lastName", "Larssen");
var date = new MessageTemplateText("date", "July 1st, 2023");
WhatsAppMessageTemplateBindings bindings = new();
bindings.Header.Add(new(document.Name));
bindings.Body.Add(new(firstName.Name));
bindings.Body.Add(new(lastName.Name));
bindings.Body.Add(new(date.Name));
MessageTemplate flightConfirmationTemplate = new(templateName, templateLanguage);
flightConfirmationTemplate.Values.Add(document);
flightConfirmationTemplate.Values.Add(firstName);
flightConfirmationTemplate.Values.Add(lastName);
flightConfirmationTemplate.Values.Add(date);
flightConfirmationTemplate.Bindings = bindings;
return flightConfirmationTemplate;
}
public static MessageTemplate AssembleSampleIssueResolution()
{
string templateName = "sample_issue_resolution";
string templateLanguage = "en_us";
var name = new MessageTemplateText(name: "name", text: "Kat");
var yes = new MessageTemplateQuickAction(name: "Yes"){ Payload = "Kat said yes" };
var no = new MessageTemplateQuickAction(name: "No") { Payload = "Kat said no" };
WhatsAppMessageTemplateBindings bindings = new();
bindings.Body.Add(new(name.Name));
bindings.Buttons.Add(new(WhatsAppMessageButtonSubType.QuickReply.ToString(), yes.Name));
bindings.Buttons.Add(new(WhatsAppMessageButtonSubType.QuickReply.ToString(), no.Name));
MessageTemplate issueResolutionTemplate = new(templateName, templateLanguage);
issueResolutionTemplate.Values.Add(name);
issueResolutionTemplate.Values.Add(yes);
issueResolutionTemplate.Values.Add(no);
issueResolutionTemplate.Bindings = bindings;
return issueResolutionTemplate;
}
public static MessageTemplate AssembleSamplePurchaseFeedback()
{
string templateName = "sample_purchase_feedback";
string templateLanguage = "en_us";
var imageUrl = new Uri("https://aka.ms/acsicon1");
var image = new MessageTemplateImage(name: "image", uri: imageUrl);
var product = new MessageTemplateText(name: "product", text: "coffee");
var urlSuffix = new MessageTemplateQuickAction(name: "text") { Text = "survey-code"};
WhatsAppMessageTemplateBindings bindings = new();
bindings.Header.Add(new(image.Name));
bindings.Body.Add(new(product.Name));
bindings.Buttons.Add(new(WhatsAppMessageButtonSubType.Url.ToString(), urlSuffix.Name));
MessageTemplate purchaseFeedbackTemplate = new(templateName, templateLanguage);
purchaseFeedbackTemplate.Values.Add(image);
purchaseFeedbackTemplate.Values.Add(product);
purchaseFeedbackTemplate.Values.Add(urlSuffix);
purchaseFeedbackTemplate.Bindings = bindings;
return purchaseFeedbackTemplate;
}
public static void PrintResponse(Response<SendMessageResult> response)
{
Console.WriteLine($"Response: {response.GetRawResponse().Status} " +
$"({response.GetRawResponse().ReasonPhrase})");
Console.WriteLine($"Date: " +
$"{response.GetRawResponse().Headers.First(header => header.Name == "Date").Value}");
Console.WriteLine($"ClientRequestId: {response.GetRawResponse().ClientRequestId}");
Console.WriteLine($"MS-CV: " +
$"{response.GetRawResponse().Headers.First(header => header.Name == "MS-CV").Value}");
foreach (var receipts in response.Value.Receipts)
{
Console.WriteLine($"MessageId: {receipts.MessageId}");
}
Console.WriteLine($"\n");
}
}
}
更多示例
这些示例使用了通过 Azure 门户嵌入式注册创建的 WhatsApp 业务帐户可用的示例模板。
使用示例模板 sample_happy_hour_announcement
此示例模板在标头中使用一个视频,在正文中使用两个文本参数。
模板的标头需要一个视频:
{
"type": "HEADER",
"format": "VIDEO"
},
该视频必须是一个托管 mp4 视频的 URL。
有关支持的媒体类型和大小限制的更多信息,请参阅 WhatsApp 的消息媒体文档。
模板正文需要两个文本参数:
{
"type": "BODY",
"text": "Happy hour is here! 🍺😀🍸\nPlease be merry and enjoy the day. 🎉\nVenue: {{1}}\nTime: {{2}}"
},
创建一个 MessageTemplateVideo
和两个 MessageTemplateText
变量。 然后,按照模板内容中参数出现的顺序提供参数,组合 MessageTemplateValue
和 MessageTemplateWhatsAppBindings
的列表。
string templateName = "sample_happy_hour_announcement";
string templateLanguage = "en_us";
var videoUrl = new Uri("< Your .mp4 Video URL >");
var video = new MessageTemplateVideo("video", videoUrl);
var venue = new MessageTemplateText("venue", "Fourth Coffee");
var time = new MessageTemplateText("time", "Today 2-4PM");
WhatsAppMessageTemplateBindings bindings = new();
bindings.Header.Add(new(video.Name));
bindings.Body.Add(new(venue.Name));
bindings.Body.Add(new(time.Name));
MessageTemplate happyHourAnnouncementTemplate = new(templateName, templateLanguage);
happyHourAnnouncementTemplate.Values.Add(venue);
happyHourAnnouncementTemplate.Values.Add(time);
happyHourAnnouncementTemplate.Values.Add(video);
happyHourAnnouncementTemplate.Bindings = bindings;
使用示例模板 sample_flight_confirmation
此示例模板在标头中使用一个文档,在正文中使用三个文本参数。
模板的标头需要一个文档:
{
"type": "HEADER",
"format": "DOCUMENT"
},
该文档必须是一个托管 pdf 文档的 URL。
有关支持的媒体类型和大小限制的更多信息,请参阅 WhatsApp 的消息媒体文档。
模板正文需要三个文本参数:
{
"type": "BODY",
"text": "This is your flight confirmation for {{1}}-{{2}} on {{3}}."
},
创建一个 MessageTemplateDocument
和三个 MessageTemplateText
变量。 然后,按照模板内容中参数出现的顺序提供参数,组合 MessageTemplateValue
和 MessageTemplateWhatsAppBindings
的列表。
string templateName = "sample_flight_confirmation";
string templateLanguage = "en_us";
var documentUrl = new Uri("< Your .pdf document URL >");
var document = new MessageTemplateDocument("document", documentUrl);
var firstName = new MessageTemplateText("firstName", "Kat");
var lastName = new MessageTemplateText("lastName", "Larssen");
var date = new MessageTemplateText("date", "July 1st, 2023");
WhatsAppMessageTemplateBindings bindings = new();
bindings.Header.Add(new(document.Name));
bindings.Body.Add(new(firstName.Name));
bindings.Body.Add(new(lastName.Name));
bindings.Body.Add(new(date.Name));
MessageTemplate flightConfirmationTemplate = new(templateName, templateLanguage);
flightConfirmationTemplate.Values.Add(document);
flightConfirmationTemplate.Values.Add(firstName);
flightConfirmationTemplate.Values.Add(lastName);
flightConfirmationTemplate.Values.Add(date);
flightConfirmationTemplate.Bindings = bindings;
先决条件
- 使用 Azure 通信服务资源注册 WhatsApp 业务帐户。
- 创建 WhatsApp 模板消息。
- 用于接收消息的活动的 WhatsApp 电话号码。
对象模型
以下类和接口用于处理适用于 Java 的 Azure 通信服务消息 SDK 的某些主要功能。
类名 | 说明 |
---|---|
NotificationMessagesClient |
连接到 Azure 通信服务资源。 它会发送消息。 |
MessageTemplate |
定义你为消息使用哪个模板以及模板属性的内容。 |
TemplateNotificationContent |
定义要发送的模板消息的“发送对象”和“内容”。 |
注意
有关详细信息,请参阅 com.azure.communication.messages 包中适用于 Java 的 Azure SDK 参考内容。
支持的 WhatsApp 模板类型
模板类型 | 说明 |
---|---|
基于文本的消息模板 | WhatsApp 消息模板是带有或不带参数的特定消息格式。 |
基于媒体的消息模板 | WhatsApp 消息模板,其中包含标头组件的媒体参数。 |
交互式消息模板 | 交互式消息模板通过使用组件对象包含交互式按钮来扩展可以发送给收件人的内容。 同时支持“行动号召”和“快速回复”。 |
基于位置的消息模板 | WhatsApp 消息模板,其位置参数以标头组件的经度和纬度表示。 |
通用配置
按照以下步骤将必要的代码片段添加到 App.java
文件的 Main 函数。
创建和管理 WhatsApp 模板消息
WhatsApp 消息模板是企业用来向选择接收通知的人员发送通知或客户关怀消息的特定消息格式。 消息可以包含约会提醒、发货信息、问题解决方案或付款更新。 在开始使用高级消息传递 SDK 发送模板化消息之前,用户需要在 WhatsApp 业务平台中创建所需的模板。
有关 WhatsApp 对于模板的要求的详细信息,请参阅 WhatsApp 业务平台 API 参考:
开始在企业和 WhatsApp 用户之间发送消息
可通过下面两种方式之一发起 WhatsApp Business 帐户与 WhatsApp 用户之间的对话:
- 企业向 WhatsApp 用户发送模板消息。
- WhatsApp 用户向企业号码发送任何消息。
无论对话是如何启动的,在用户向企业发送消息之前,企业只能发送模板消息。只有在用户向企业发送消息后,企业才能在活动对话期间向用户发送文本或媒体消息。 24 小时对话窗口到期后,必须重新发起对话。 若要了解有关对话的详细信息,请访问 WhatsApp Business 平台查看定义。
对客户端进行身份验证
可使用几个不同的选项对消息客户端进行身份验证:
若要对客户端进行身份验证,请使用连接字符串实例化 NotificationMessagesClient
或 MessageTemplateClient
。 还可以使用任何实现 com.azure.core.http.HttpClient
接口的自定义 HTTP 客户端来初始化此客户端。
为简单起见,本快速入门使用连接字符串进行身份验证。 在生产环境中,我们建议使用服务主体。
从 Azure 门户中的 Azure 通信服务资源获取连接字符串。 在左侧,导航到“Keys
”选项卡。复制 Primary key
的 Connection string
字段。 连接字符串采用 endpoint=https://{your Azure Communication Services resource name}.communication.azure.com/;accesskey={secret key}
格式。
将环境变量 COMMUNICATION_SERVICES_CONNECTION_STRING
设置为连接字符串的值。
打开控制台窗口并输入以下命令:
setx COMMUNICATION_SERVICES_CONNECTION_STRING "<your connection string>"
有关如何为系统设置环境变量的详细信息,请按照在环境变量中存储连接字符串的步骤操作。
若要实例化 NotificationMessagesClient,请将以下代码添加到 main
方法:
// You can get your connection string from your resource in the Azure portal.
String connectionString = System.getenv("COMMUNICATION_SERVICES_CONNECTION_STRING");
NotificationMessagesClient notificationClient = new NotificationMessagesClientBuilder()
.connectionString(connectionString)
.buildClient();
设置频道注册 ID
频道注册 ID GUID 是在频道注册期间创建的。 可在门户中,访问 Azure 通信服务资源的“频道”选项卡来查找它。
将它分配给名为 channelRegistrationId 的变量。
String channelRegistrationId = "<your channel registration id GUID>";
设置收件人列表
你需要提供一个与 WhatsApp 帐户关联的真实电话号码。 此 WhatsApp 帐户接收本快速入门中发送的文本和媒体消息。 在本快速入门中,此电话号码可能是你的个人电话号码。
收件人电话号码不能是与 WhatsApp 频道注册关联的业务电话号码(发件人 ID)。 发件人 ID 显示为发送给收件人的文本和媒体消息的发件人。
电话号码应包括国家/地区代码。 有关电话号码格式的详细信息,请查看 WhatsApp 文档中的电话号码格式。
注意
收件人列表中当前仅支持一个电话号码。
创建如下所示的收件人列表:
List<String> recipientList = new ArrayList<>();
recipientList.add("<to WhatsApp phone number>");
示例:
// Example only
List<String> recipientList = new ArrayList<>();
recipientList.add("+14255550199");
设置环境
若要设置用于发送消息的环境,请完成以下部分中所述的步骤。
先决条件
- 注册到 Azure 通信服务资源的 WhatsApp Business 帐户。
- 用于接收消息的活动的 WhatsApp 电话号码。
- Java 开发工具包 (JDK) 版本 8 或更高版本。
- Apache Maven。
创建新的 Java 应用程序
打开终端或命令窗口,并导航到要在其中创建 Java 应用程序的目录。 运行以下命令,从 maven-archetype-quickstart
模板生成 Java 项目。
mvn archetype:generate -DgroupId="com.communication.quickstart" -DartifactId="communication-quickstart" -DarchetypeArtifactId="maven-archetype-quickstart" -DarchetypeVersion="1.4" -DinteractiveMode="false"
generate
目标将创建一个名称与 artifactId
值相同的目录。 在此目录下,src/main/java
目录包含项目源代码,src/test/java
目录包含测试源,pom.xml
文件是该项目的项目对象模型 (POM)。
安装包
在文本编辑器中打开 pom.xml 文件pom.xml
。 将以下依赖项元素添加到依赖项组。
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-communication-messages</artifactId>
</dependency>
设置应用框架
在文本编辑器中打开 /src/main/java/com/communication/quickstart/App.java
,添加 import 指令并删除 System.out.println("Hello world!");
语句:
package com.communication.quickstart;
import com.azure.communication.messages.*;
import com.azure.communication.messages.models.*;
import java.util.ArrayList;
import java.util.List;
public class App
{
public static void main( String[] args )
{
// Quickstart code goes here.
}
}
代码示例
按照以下步骤将所需的代码片段添加到 App.java
文件的 Main 函数。
- 在 Azure 门户中列出 WhatsApp 模板。
- 发送正文中带有文本参数的模板消息。
- 发送标头中带有媒体参数的模板消息。
- 发送带有快速回复按钮的模板消息。
- 发送带有行动号召按钮和动态链接的模板消息。
在 Azure 门户中列出 WhatsApp 模板
若要在 Azure 门户中查看模板,请转到“Azure 通信服务资源”>“高级消息传递”>“模板”。
选择一个模板以查看模板详细信息。
模板详细信息的“内容”字段可以包含参数绑定。 参数绑定可以表示为:
- 具有
IMAGE
等值的"format"
字段。 - 双括号括起数字,例如
{{1}}
。 该数字(索引从 1 开始)表示创建消息模板时必须提供绑定值的顺序。
或者,也可以通过“WhatsApp 管理器”>“帐户工具”>“消息模板”查看和编辑所有 WhatsApp 业务帐户的模板。
若要以编程方式列出模板,则可以使用以下代码获取频道 ID 的所有模板:
public static void getMessageTemplateWithConnectionString() {
MessageTemplateClient templateClient =
new MessageTemplateClientBuilder()
.connectionString(connectionString)
.buildClient();
PagedIterable<MessageTemplateItem> response = templateClient.listTemplates(channelRegistrationId);
response.stream().forEach(t -> {
WhatsAppMessageTemplateItem template = (WhatsAppMessageTemplateItem) t ;
System.out.println("===============================");
System.out.println("Template Name :: "+template.getName());
System.out.println("Template Language :: "+template.getLanguage());
System.out.println("Template Status :: "+template.getStatus());
System.out.println("Template Content :: "+template.getContent());
System.out.println("===============================");
});
}
发送正文中带有文本参数的模板消息
如果模板不带任何参数,则在创建 MessageTemplate
时无需提供值或绑定。
/*
* This sample shows how to send template message with below details
* Name: sample_shipping_confirmation, Language: en_US
* [
{
"type": "BODY",
"text": "Your package has been shipped. It will be delivered in {{1}} business days."
},
{
"type": "FOOTER",
"text": "This message is from an unverified business."
}
]
* */
private static void sendTemplateMessage() {
//Update Template Name and language according your template associate to your channel.
MessageTemplate template = new MessageTemplate("sample_shipping_confirmation", "en_US");
//Update template parameter type and value
List<MessageTemplateValue> messageTemplateValues = new ArrayList<>();
messageTemplateValues.add(new MessageTemplateText("Days", "5"));
template.setValues(messageTemplateValues);
//Update template parameter binding
List<WhatsAppMessageTemplateBindingsComponent> components = new ArrayList<>();
components.add(new WhatsAppMessageTemplateBindingsComponent("Days"));
MessageTemplateBindings bindings =new WhatsAppMessageTemplateBindings()
.setBody(components);
template.setBindings(bindings);
NotificationMessagesClient client = createClientWithTokenCredential();
SendMessageResult result = client.send(
new TemplateNotificationContent(CHANNEL_ID, recipients, template));
result.getReceipts().forEach(r -> System.out.println("Message sent to:"+r.getTo() + " and message id:"+ r.getMessageId()));
}
发送标头中带有媒体参数的模板消息
使用 MessageTemplateImage
、 MessageTemplateVideo
或 MessageTemplateDocument
在标头中定义媒体参数。
标头中带有图像媒体参数的模板定义:
{
"type": "HEADER",
"format": "VIDEO"
},
"format"
可以是 WhatsApp 支持的四种不同媒体类型之一。 在 .NET SDK 中,每个媒体类型都使用相应的 MessageTemplateValue
类型。
Format | MessageTemplateValue 类型 | 文件类型 |
---|---|---|
IMAGE | MessageTemplateImage |
png、jpg |
视频 | MessageTemplateVideo |
mp4 |
DOCUMENT | MessageTemplateDocument |
有关支持的媒体类型和大小限制的更多信息,请参阅 WhatsApp 的消息媒体文档。
示例
sample_happy_hour_announcement
模板:
在这里,模板的标头需要一个视频:
{
"type": "HEADER",
"format": "VIDEO"
},
视频必须是一个托管 mp4 视频的 URL。
有关支持的媒体类型和大小限制的更多信息,请参阅 WhatsApp 的消息媒体文档。
模板正文需要两个文本参数:
{
"type": "BODY",
"text": "Happy hour is here! 🍺😀🍸\nPlease be merry and enjoy the day. 🎉\nVenue: {{1}}\nTime: {{2}}"
},
创建一个 MessageTemplateVideo
和四个 MessageTemplateText
变量。 然后,按照参数在模板内容中出现的顺序提供参数,组合 MessageTemplateValue
和 MessageTemplateWhatsAppBindings
的列表。
/*
* This sample shows how to send template message with below details
* Name: sample_happy_hour_announcement, Language: en_US
* [
{
"type": "HEADER",
"format": "VIDEO"
},
{
"type": "BODY",
"text": "Happy hour is here! 🍺😀🍸\nPlease be merry and enjoy the day. 🎉\nVenue: {{1}}\nTime: {{2}}"
},
{
"type": "FOOTER",
"text": "This message is from an unverified business."
}
]
* */
private static void sendTemplateMessageWithVideo() {
//Update Template Name and language according your template associate to your channel.
MessageTemplate template = new MessageTemplate("sample_happy_hour_announcement", "en_US");
//Add template parameter type with value in a list
List<MessageTemplateValue> messageTemplateValues = new ArrayList<>();
messageTemplateValues.add(new MessageTemplateVideo("HeaderVideo", "https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4"));
messageTemplateValues.add(new MessageTemplateText("VenueInfoInBody", "Starbucks"));
messageTemplateValues.add(new MessageTemplateText("TimeInfoInBody", "Today 2-4PM"));
// Add parameter binding for template header in a list
List<WhatsAppMessageTemplateBindingsComponent> templateHeaderBindings = new ArrayList<>();
templateHeaderBindings.add(new WhatsAppMessageTemplateBindingsComponent("HeaderVideo"));
// Add parameter binding for template body in a list
List<WhatsAppMessageTemplateBindingsComponent> templateBodyBindings = new ArrayList<>();
templateBodyBindings.add(new WhatsAppMessageTemplateBindingsComponent("VenueInfoInBody"));
templateBodyBindings.add(new WhatsAppMessageTemplateBindingsComponent("TimeInfoInBody"));
MessageTemplateBindings templateBindings = new WhatsAppMessageTemplateBindings()
.setHeaderProperty(templateHeaderBindings) // Set the parameter binding for template header
.setBody(templateBodyBindings); // Set the parameter binding for template body
template
.setBindings(templateBindings)
.setValues(messageTemplateValues);
NotificationMessagesClient client = createClientWithConnectionString();
SendMessageResult result = client.send(
new TemplateNotificationContent(CHANNEL_ID, recipients, template));
result.getReceipts().forEach(r -> System.out.println("Message sent to:"+r.getTo() + " and message id:"+ r.getMessageId()));
}
发送带有快速回复按钮的模板消息
使用 MessageTemplateQuickAction
来定义快速回复按钮的有效负载并且 MessageTemplateQuickAction
对象具有以下三个属性。
属性 | 说明 | 类型 |
---|---|---|
名称 |
name 用于查找 MessageTemplateWhatsAppBindings 中的值。 |
string |
文本 | 可选的快速操作 text 。 |
string |
有效负载 | 如果用户选择按钮,则分配给该按钮的 payload 在消息回复中可用。 |
string |
带有快速回复按钮的模板定义:
{
"type": "BUTTONS",
"buttons": [
{
"type": "QUICK_REPLY",
"text": "Yes"
},
{
"type": "QUICK_REPLY",
"text": "No"
}
]
}
按钮在模板定义中出现的顺序必须与使用 MessageTemplateWhatsAppBindings
创建绑定时定义按钮的顺序匹配。
有关用户快速回复响应中有效负载的更多信息,请参阅关于接收来自快速回复按钮的回叫的 WhatsApp 文档。
示例
sample_issue_resolution
模板:
模板正文需要一个文本参数:
/*
* This sample shows how to send template message with below details
* Name: sample_issue_resolution, Language: en_US
* [
{
"type": "BODY",
"text": "Hi {{1}}, were we able to solve the issue that you were facing?"
},
{
"type": "FOOTER",
"text": "This message is from an unverified business."
},
{
"type": "BUTTONS",
"buttons": [
{
"type": "QUICK_REPLY",
"text": "Yes"
},
{
"type": "QUICK_REPLY",
"text": "No"
}
]
}
]
* */
private static void sendTextTemplateMessageWithQuickReply() {
//Add template parameter type with value in a list
List<MessageTemplateValue> messageTemplateValues = new ArrayList<>();
messageTemplateValues.add(new MessageTemplateText("Name", "Arif"));
messageTemplateValues.add(new MessageTemplateQuickAction("Yes").setPayload("Yes"));
messageTemplateValues.add(new MessageTemplateQuickAction("No").setPayload("No"));
// Add parameter binding for template body in a list
List<WhatsAppMessageTemplateBindingsComponent> templateBodyBindings = new ArrayList<>();
templateBodyBindings.add(new WhatsAppMessageTemplateBindingsComponent("Name"));
// Add parameter binding for template buttons in a list
List<WhatsAppMessageTemplateBindingsButton> templateButtonBindings = new ArrayList<>();
templateButtonBindings.add( new WhatsAppMessageTemplateBindingsButton(WhatsAppMessageButtonSubType.QUICK_REPLY, "Yes"));
templateButtonBindings.add( new WhatsAppMessageTemplateBindingsButton(WhatsAppMessageButtonSubType.QUICK_REPLY, "No"));
MessageTemplateBindings templateBindings = new WhatsAppMessageTemplateBindings()
.setBody(templateBodyBindings) // Set the parameter binding for template body
.setButtons(templateButtonBindings); // Set the parameter binding for template buttons
MessageTemplate messageTemplate = new MessageTemplate("sample_issue_resolution", "en_US")
.setBindings(templateBindings)
.setValues(messageTemplateValues);
NotificationMessagesClient client = createClientWithConnectionString();
SendMessageResult result = client.send(
new TemplateNotificationContent(CHANNEL_ID, recipients, messageTemplate));
result.getReceipts().forEach(r -> System.out.println("Message sent to:"+r.getTo() + " and message id:"+ r.getMessageId()));
}
发送带有行动号召按钮和动态链接的模板消息
使用 MessageTemplateQuickAction
来定义行动号召按钮的 URL 后缀并且 MessageTemplateQuickAction
对象具有以下两个属性。
属性 | 说明 | 类型 |
---|---|---|
名称 |
name 用于查找 MessageTemplateWhatsAppBindings 中的值。 |
string |
文本 | 追加到 URL 的text 。 |
string |
模板定义按钮:
{
"type": "BUTTONS",
"buttons": [
{
"type": "URL",
"text": "Take Survey",
"url": "https://www.example.com/{{1}}"
}
]
}
按钮在模板定义中出现的顺序必须与使用 MessageTemplateWhatsAppBindings
创建绑定时定义按钮的顺序匹配。
示例
sample_purchase_feedback
模板:
此示例模板向消息添加一个带有动态 URL 链接的按钮。 它还在标头中使用一个图像,在正文中使用一个文本参数。
在此示例中,模板的标头需要一个图像:
{
"type": "HEADER",
"format": "IMAGE"
},
模板正文需要一个文本参数:
{
"type": "BODY",
"text": "Thank you for purchasing {{1}}! We value your feedback and would like to learn more about your experience."
},
该模板包含带有一个参数的动态 URL 按钮:
{
"type": "BUTTONS",
"buttons": [
{
"type": "URL",
"text": "Take Survey",
"url": "https://www.example.com/{{1}}"
}
]
}
创建一个 MessageTemplateImage
、一个 MessageTemplateText
和一个 MessageTemplateQuickAction
变量。 然后,按照参数在模板内容中出现的顺序提供参数,组合 MessageTemplateValue
和 MessageTemplateWhatsAppBindings
的列表。 在定义绑定的按钮时,顺序也很重要。
/*
* This sample shows how to send template message with below details
* Name: sample_purchase_feedback, Language: en_US
* [
{
"type": "HEADER",
"format": "IMAGE"
},
{
"type": "BODY",
"text": "Thank you for purchasing {{1}}! We value your feedback and would like to learn more about your experience."
},
{
"type": "FOOTER",
"text": "This message is from an unverified business."
},
{
"type": "BUTTONS",
"buttons": [
{
"type": "URL",
"text": "Take Survey",
"url": "https://www.example.com/"
}
]
}
]
* */
private static void sendTemplateMessageWithImage() {
//Update Template Name and language according your template associate to your channel.
MessageTemplate template = new MessageTemplate("sample_purchase_feedback", "en_US");
//Add template parameter type with value in a list
List<MessageTemplateValue> messageTemplateValues = new ArrayList<>();
messageTemplateValues.add(new MessageTemplateImage("HeaderImage", "https://upload.wikimedia.org/wikipedia/commons/3/30/Building92microsoft.jpg"));
messageTemplateValues.add(new MessageTemplateText("ProductInfoInBody", "Microsoft Office"));
// Add parameter binding for template header in a list
List<WhatsAppMessageTemplateBindingsComponent> templateHeaderBindings = new ArrayList<>();
templateHeaderBindings.add(new WhatsAppMessageTemplateBindingsComponent("HeaderImage"));
// Add parameter binding for template body in a list
List<WhatsAppMessageTemplateBindingsComponent> templateBodyBindings = new ArrayList<>();
templateBodyBindings.add(new WhatsAppMessageTemplateBindingsComponent("ProductInfoInBody"));
MessageTemplateBindings templateBindings = new WhatsAppMessageTemplateBindings()
.setHeaderProperty(templateHeaderBindings) // Set the parameter binding for template header
.setBody(templateBodyBindings); // Set the parameter binding for template body
template
.setBindings(templateBindings)
.setValues(messageTemplateValues);
NotificationMessagesClient client = createClientWithConnectionString();
SendMessageResult result = client.send(
new TemplateNotificationContent(CHANNEL_ID, recipients, template));
result.getReceipts().forEach(r -> System.out.println("Message sent to:"+r.getTo() + " and message id:"+ r.getMessageId()));
}
运行代码
打开包含
pom.xml
文件的目录,并使用mvn
命令编译该项目。mvn compile
通过执行以下
mvn
命令运行应用。mvn exec:java -D"exec.mainClass"="com.communication.quickstart.App" -D"exec.cleanupDaemonThreads"="false"
完整示例代码
在 GitHub 上查找此快速入门的最终代码。
先决条件
- 使用 Azure 通信服务资源注册 WhatsApp 业务帐户。
- 创建 WhatsApp 模板消息。
- 用于接收消息的活动的 WhatsApp 电话号码。
- Node.js 活动 LTS 版本和维护 LTS 版本(建议使用 8.11.1 和 10.14.1)。
-
Node.js 活动 LTS 和维护 LTS 版本(建议使用 8.11.1 和 10.14.1)
- 在终端或命令窗口中,运行
node --version
以查看是否安装了 Node.js
- 在终端或命令窗口中,运行
对象模型
以下类和接口用于处理适用于 Javascript 的 Azure 通信服务消息 SDK 的某些主要功能。
类名 | 说明 |
---|---|
NotificationMessagesClient |
连接到 Azure 通信服务资源。 它会发送消息。 |
MessageTemplate |
定义你为消息使用哪个模板以及模板属性的内容。 |
TemplateNotificationContent |
定义要发送的模板消息的“发送对象”和“内容”。 |
注意
有关详细信息,请参阅适用于 JavaScript 的 Azure SDK 参考文章 @azure-rest/communication-messages 包
支持的 WhatsApp 模板类型
模板类型 | 说明 |
---|---|
基于文本的消息模板 | WhatsApp 消息模板是带有或不带参数的特定消息格式。 |
基于媒体的消息模板 | WhatsApp 消息模板,其中包含标头组件的媒体参数。 |
交互式消息模板 | 交互式消息模板通过使用组件对象包含交互式按钮来扩展可以发送给收件人的内容。 同时支持“行动号召”和“快速回复”。 |
基于位置的消息模板 | WhatsApp 消息模板,其位置参数以标头组件的经度和纬度表示。 |
通用配置
按照以下步骤将必要的代码片段添加到 send-messages.js
文件的 Main 函数。
创建和管理 WhatsApp 模板消息
WhatsApp 消息模板是企业用来向选择接收通知的人员发送通知或客户关怀消息的特定消息格式。 消息可以包含约会提醒、发货信息、问题解决方案或付款更新。 在开始使用高级消息传递 SDK 发送模板化消息之前,用户需要在 WhatsApp 业务平台中创建所需的模板。
有关 WhatsApp 对于模板的要求的详细信息,请参阅 WhatsApp 业务平台 API 参考:
开始在企业和 WhatsApp 用户之间发送消息
可通过下面两种方式之一发起 WhatsApp Business 帐户与 WhatsApp 用户之间的对话:
- 企业向 WhatsApp 用户发送模板消息。
- WhatsApp 用户向企业号码发送任何消息。
无论对话是如何启动的,在用户向企业发送消息之前,企业只能发送模板消息。只有在用户向企业发送消息后,企业才能在活动对话期间向用户发送文本或媒体消息。 24 小时对话窗口到期后,必须重新发起对话。 若要了解有关对话的详细信息,请访问 WhatsApp Business 平台查看定义。
对客户端进行身份验证
以下代码使用 dotenv 包从名为 COMMUNICATION_SERVICES_CONNECTION_STRING
的环境变量中检索资源的连接字符串。
为简单起见,本快速入门使用连接字符串进行身份验证。 在生产环境中,我们建议使用服务主体。
从 Azure 门户中的 Azure 通信服务资源获取连接字符串。 在左侧,导航到“Keys
”选项卡。复制 Primary key
的 Connection string
字段。 连接字符串采用 endpoint=https://{your Azure Communication Services resource name}.communication.azure.com/;accesskey={secret key}
格式。
将环境变量 COMMUNICATION_SERVICES_CONNECTION_STRING
设置为连接字符串的值。
打开控制台窗口并输入以下命令:
setx COMMUNICATION_SERVICES_CONNECTION_STRING "<your connection string>"
有关如何为系统设置环境变量的详细信息,请按照在环境变量中存储连接字符串的步骤操作。
若要实例化 NotificationClient,请将以下代码添加到 Main
方法:
const NotificationClient = require("@azure-rest/communication-messages").default;
// Set Connection string
const connectionString = process.env["COMMUNICATION_SERVICES_CONNECTION_STRING"];
// Instantiate the client
const client = NotificationClient(connectionString);
设置频道注册 ID
频道注册 ID GUID 是在频道注册期间创建的。 可在门户中,访问 Azure 通信服务资源的“频道”选项卡来查找它。
将它分配给名为 channelRegistrationId 的变量。
const channelRegistrationId = "<your channel registration id GUID>";
设置收件人列表
你需要提供一个与 WhatsApp 帐户关联的真实电话号码。 此 WhatsApp 帐户会接收本快速入门中发送的模版、文本和媒体消息。 在本快速入门中,此电话号码可能是你的个人电话号码。
收件人电话号码不能是与 WhatsApp 频道注册关联的业务电话号码(发件人 ID)。 发件人 ID 显示为发送给收件人的文本和媒体消息的发件人。
电话号码应包括国家/地区代码。 有关电话号码格式的详细信息,请查看 WhatsApp 文档中的电话号码格式。
注意
收件人列表中当前仅支持一个电话号码。
创建如下所示的收件人列表:
const recipientList = ["<to WhatsApp phone number>"];
示例:
// Example only
const recipientList = ["+14255550199"];
设置
若要设置用于发送消息的环境,请完成以下部分中所述的步骤。
创建新的 Node.js 应用程序
为应用创建一个新目录,并在终端或命令窗口中打开该目录。
运行以下命令。
mkdir advance-messages-quickstart && cd advance-messages-quickstart
运行以下命令以使用默认设置创建
package.json
文件。npm init -y
使用文本编辑器在项目根目录中创建名为“
send-messages.js
”的文件。将以下代码片段添加到文件
send-messages.js
中。async function main() { // Quickstart code goes here. } main().catch((error) => { console.error("Encountered an error while sending message: ", error); process.exit(1); });
完成以下部分,将此示例的源代码添加到你创建的 send-messages.js
文件中。
安装包
使用 npm install
命令安装适用于 JavaScript 的 Azure 通信服务高级消息传送 SDK。
npm install @azure-rest/communication-messages --save
--save
选项将该库作为 package.json 文件中的依赖项列出。
代码示例
按照以下步骤将所需的代码片段添加到 send-messages.js
文件的 Main 函数。
在 Azure 门户中列出 WhatsApp 模板
若要在 Azure 门户中查看模板,请转到“Azure 通信服务资源”>“高级消息传递”>“模板”。
选择一个模板以查看模板详细信息。
模板详细信息的“内容”字段可以包含参数绑定。 参数绑定可以表示为:
- 具有
IMAGE
等值的"format"
字段。 - 双括号括起数字,例如
{{1}}
。 该数字(索引从 1 开始)表示创建消息模板时必须提供绑定值的顺序。
或者,也可以通过“WhatsApp 管理器”>“帐户工具”>“消息模板”查看和编辑所有 WhatsApp 业务帐户的模板。
若要以编程方式列出模板,则可以使用以下代码获取频道 ID 的所有模板:
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
/**
* @summary Get Template list for a channel
*/
const MessageTemplateClient = require("@azure-rest/communication-messages").default,
{ isUnexpected } = require("@azure-rest/communication-messages");
// Load the .env file if it exists
require("dotenv").config();
async function main() {
const connectionString = process.env.COMMUNICATION_LIVETEST_STATIC_CONNECTION_STRING || "";
const client = MessageTemplateClient(connectionString);
console.log("Fetch Templates...");
const response = await client
.path("/messages/channels/{channelId}/templates", process.env.CHANNEl_ID || "")
.get({
queryParameters: { maxPageSize: 2 },
});
if (isUnexpected(response)) {
throw new Error("Failed to get template for the channel.");
}
// The paginate helper creates a paged async iterator using metadata from the first page.
const items = paginate(client, response);
// We get an PageableAsyncIterator so we need to do `for await`.
for await (const item of items) {
console.log(JSON.stringify(item, null, 2));
}
}
main().catch((error) => {
console.error("Encountered an error while sending message: ", error);
throw error;
});
发送正文中带有文本参数的模板消息
sample_shipping_confirmation
模板:
在此示例中,模板的正文有一个参数:
{
"type": "BODY",
"text": "Your package has been shipped. It will be delivered in {{1}} business days."
},
参数使用 values
值和 bindings
绑定定义。 使用值和绑定来组合 template
对象。
/*
* This sample shows how to send template message with below details
* Name: sample_shipping_confirmation, Language: en_US
* [
{
"type": "BODY",
"text": "Your package has been shipped. It will be delivered in {{1}} business days."
},
{
"type": "FOOTER",
"text": "This message is from an unverified business."
}
]
* */
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
/**
* @summary Use AAD token credentials when sending a whatsapp template message.
*/
const { isNode } = require("@azure/core-util");
const { ClientSecretCredential, DefaultAzureCredential } = require("@azure/identity");
const NotificationClient = require("@azure-rest/communication-messages").default,
{ isUnexpected } = require("@azure-rest/communication-messages");
// Load the .env file if it exists
require("dotenv").config();
async function main() {
// You will need to set this environment variable or edit the following values
const endpoint = process.env.ACS_URL || "";
// Azure AD Credential information is required to run this sample:
if (
!process.env.AZURE_TENANT_ID ||
!process.env.AZURE_CLIENT_ID ||
!process.env.AZURE_CLIENT_SECRET
) {
console.error(
"Azure AD authentication information not provided, but it is required to run this sample. Exiting.",
);
return;
}
// get credentials
const credential = isNode
? new DefaultAzureCredential()
: new ClientSecretCredential(
process.env.AZURE_TENANT_ID,
process.env.AZURE_CLIENT_ID,
process.env.AZURE_CLIENT_SECRET,
);
const client = NotificationClient(endpoint, credential);
const DaysTemplateValue = {
kind: "text",
name: "Days",
text: "5",
};
const templateBindings = {
kind: "whatsApp",
body: [
{
refValue: "Days",
},
],
};
const template = {
name: "sample_shipping_confirmation",
language: "en_US",
bindings: templateBindings,
values: [DaysTemplateValue],
};
const result = await client.path("/messages/notifications:send").post({
contentType: "application/json",
body: {
channelRegistrationId: process.env.CHANNEL_ID || "",
to: [process.env.RECIPIENT_PHONE_NUMBER || ""],
kind: "template",
template: template,
},
});
console.log("Response: " + JSON.stringify(result, null, 2));
if (isUnexpected(result)) {
throw new Error("Failed to send message");
}
const response = result;
response.body.receipts.forEach((receipt) => {
console.log("Message sent to:" + receipt.to + " with message id:" + receipt.messageId);
});
}
main().catch((error) => {
console.error("Encountered an error while sending message: ", error);
throw error;
});
module.exports = { main };
运行代码
使用 node 命令运行添加到 send-messages.js 文件中的代码。
node ./send-messages.js
完整示例代码
在 GitHub 上查找此示例的最终代码。
先决条件
- 使用 Azure 通信服务资源注册 WhatsApp 业务帐户。
- 创建 WhatsApp 模板消息。
- 用于接收消息的活动的 WhatsApp 电话号码。
对象模型
以下类和接口用于处理适用于 Python 的 Azure 通信服务消息 SDK 的某些主要功能。
类名 | 说明 |
---|---|
NotificationMessagesClient |
连接到 Azure 通信服务资源。 它会发送消息。 |
MessageTemplate |
定义你为消息使用哪个模板以及模板属性的内容。 |
TemplateNotificationContent |
定义要发送的模板消息的“发送对象”和“内容”。 |
注意
有关详细信息,请参阅适用于 Python 的 Azure SDK 参考文章消息包。
支持的 WhatsApp 模板类型
模板类型 | 说明 |
---|---|
基于文本的消息模板 | WhatsApp 消息模板是带有或不带参数的特定消息格式。 |
基于媒体的消息模板 | WhatsApp 消息模板,其中包含标头组件的媒体参数。 |
交互式消息模板 | 交互式消息模板通过使用组件对象包含交互式按钮来扩展可以发送给收件人的内容。 同时支持“行动号召”和“快速回复”。 |
基于位置的消息模板 | WhatsApp 消息模板,其位置参数以标头组件的经度和纬度表示。 |
通用配置
按照以下步骤将必要的代码片段添加到 messages-quickstart.py
python 程序。
创建和管理 WhatsApp 模板消息
WhatsApp 消息模板是企业用来向选择接收通知的人员发送通知或客户关怀消息的特定消息格式。 消息可以包含约会提醒、发货信息、问题解决方案或付款更新。 在开始使用高级消息传递 SDK 发送模板化消息之前,用户需要在 WhatsApp 业务平台中创建所需的模板。
有关 WhatsApp 对于模板的要求的详细信息,请参阅 WhatsApp 业务平台 API 参考:
对客户端进行身份验证
发送的消息是使用 NotificationMessagesClient 完成的。 NotificationMessagesClient 使用从 Microsoft Azure 门户中的 Azure 通信服务资源获取的连接字符串进行身份验证。 有关连接字符串的详细信息,请参阅访问连接字符串和服务终结点。
从 Microsoft Azure 门户获取 Azure 通信资源连接字符串,如屏幕截图中所示。 在左侧,导航到“Keys
”选项卡。复制主键的 Connection string
字段。 连接字符串采用 endpoint=https://{your Azure Communication Services resource name}.communication.azure.com/;accesskey={secret key}
格式。
将环境变量 COMMUNICATION_SERVICES_CONNECTION_STRING
设置为连接字符串的值。
打开控制台窗口并输入以下命令:
setx COMMUNICATION_SERVICES_CONNECTION_STRING "<your connection string>"
添加环境变量后,可能需要重启任何正在运行的、需要读取环境变量的程序(包括控制台窗口)。 例如,如果使用 Visual Studio 作为编辑器,请在运行示例之前重启 Visual Studio。
有关如何为系统设置环境变量的详细信息,请按照在环境变量中存储连接字符串的步骤操作。
# Get a connection string to our Azure Communication Services resource.
connection_string = os.getenv("COMMUNICATION_SERVICES_CONNECTION_STRING")
def send_template_message(self):
from azure.communication.messages import NotificationMessagesClient
# Create NotificationMessagesClient Client
messaging_client = NotificationMessagesClient.from_connection_string(self.connection_string)
设置频道注册 ID
已在频道注册期间创建了频道注册 ID GUID。 在门户中通过 Azure 通信服务资源的“频道”选项卡可以找到它。
将它分配给名为 channelRegistrationId 的变量。
channelRegistrationId = os.getenv("WHATSAPP_CHANNEL_ID_GUID")
设置收件人列表
需要提供与 WhatsApp 帐户关联的有效电话号码。 此 WhatsApp 帐户会接收本快速入门中发送的模版、文本和媒体消息。
对于此示例,可以使用个人电话号码。
收件人电话号码不能是与 WhatsApp 频道注册关联的业务电话号码(发件人 ID)。 发件人 ID 显示为发送给收件人的文本和媒体消息的发件人。
电话号码必须包括国家/地区代码。 有关电话号码格式的详细信息,请查看 WhatsApp 文档中的电话号码格式。
注意
收件人列表中当前仅支持一个电话号码。
设置如下所示的收件人列表:
phone_number = os.getenv("RECIPIENT_WHATSAPP_PHONE_NUMBER")
用例:
# Example only
to=[self.phone_number],
开始在企业和 WhatsApp 用户之间发送消息
可通过下面两种方式之一发起 WhatsApp Business 帐户与 WhatsApp 用户之间的对话:
- 企业向 WhatsApp 用户发送模板消息。
- WhatsApp 用户向企业号码发送任何消息。
企业无法发起交互式对话。 企业只能在收到用户的消息后发送交互式消息。 企业只能在活动对话期间向用户发送交互式消息。 一旦 24 小时对话窗口过期,只有用户才能重新开始交互式对话。 有关对话的详细信息,请访问 WhatsApp 业务平台查看定义。
若要从个人 WhatsApp 帐户发起交互式对话,请向自己的企业号码(发送方 ID)发送消息。
设置环境
创建新的 Python 应用程序
在终端或控制台窗口中,为应用程序创建一个新文件夹并打开它。
mkdir messages-quickstart && cd messages-quickstart
安装包
使用适用于 Python 1.1.0 或更高版本的 Azure 通信消息客户端库。
从控制台提示中运行以下命令:
pip install azure-communication-messages
对于“交互消息、反应和贴纸功能”,请使用以下 Beta 版本:
pip install azure-communication-messages==1.2.0b1
设置应用框架
创建一个名为 messages-quickstart.py
的新文件并添加基本程序结构。
type nul > messages-quickstart.py
基本程序结构
import os
class MessagesQuickstart(object):
print("Azure Communication Services - Advanced Messages SDK Quickstart")
if __name__ == '__main__':
messages = MessagesQuickstart()
基本程序结构
import os
class MessagesQuickstart(object):
print("Azure Communication Services - Advanced Messages SDK Quickstart")
if __name__ == '__main__':
messages = MessagesQuickstart()
代码示例
按照以下步骤将必要的代码片段添加到 messages-quickstart.py
python 程序。
- 列出 Azure 门户中的 WhatsApp 模板。
- 发送不带参数的模板消息。
- 发送正文中使用文本参数的模板消息。
- 发送标头中使用媒体参数的模板消息。
- 发送标头中带有位置的模板消息。
- 发送带有快速回复按钮的模板消息。
- 发送带有动态链接的行动号召按钮的模板消息。
在 Azure 门户中列出 WhatsApp 模板
可以通过转到“Azure 通信服务资源”>“高级消息传递”>“模板”来查看 Azure 门户中的模板。
选择模板以查看模板详细信息。
模板详细信息的 content
字段可以包含参数绑定。 参数绑定可以表示为:
- 具有
IMAGE
等值的format
字段。 - 双括号括起数字,例如
{{1}}
。 该数字(索引从 1 开始)表示创建消息模板时必须提供绑定值的顺序。
或者,可以在“WhatsApp 管理器>帐户工具>消息模板”中查看和编辑所有 WhatsApp Business 帐户的模板。
若要以编程方式列出模板,则可以获取用于频道 ID 的所有模板,如下所示:
def get_templates_list(self):
from azure.communication.messages import MessageTemplateClient
message_template_client = MessageTemplateClient.from_connection_string(self.connection_string)
# calling send() with whatsapp message details
template_list = message_template_client.list_templates(self.channel_id)
count_templates = len(list(template_list))
print("Successfully retrieved {} templates from channel_id {}.".format(count_templates, self.channel_id))
发送不带参数的模板消息
如果模板不需要参数,则在创建 MessageTemplate
时无需提供值或绑定。
示例
sample_template
没有参数。
通过引用目标模板的名称和语言来组合 MessageTemplate
。
input_template: MessageTemplate = MessageTemplate(name="gathering_invitation", language="ca") # Name of the WhatsApp Template
发送正文中带有文本参数的模板消息
使用 MessageTemplateText
定义正文中用双括号括起的数字(例如 {{1}}
)表示的参数。 该数字(索引从 1 开始)表示创建消息模板时必须提供绑定值的顺序。 尝试包含模板中不存在的参数是无效的。
带有两个参数的模板定义:
{
"type": "BODY",
"text": "Message with two parameters: {{1}} and {{2}}"
}
示例
sample_shipping_confirmation
模板:
在此示例中,模板的正文有一个参数:
{
"type": "BODY",
"text": "Your package has been shipped. It will be delivered in {{1}} business days."
},
使用 MessageTemplateValue
值和 MessageTemplateWhatsAppBindings
绑定来定义参数。 使用值和绑定来组合 MessageTemplate
。
# Setting template options
templateName = "sample_shipping_confirmation"
templateLanguage = "en_us"
shippingConfirmationTemplate: MessageTemplate = MessageTemplate(name=templateName, language=templateLanguage )
threeDays = MessageTemplateText(name="threeDays", text="3")
bindings = WhatsAppMessageTemplateBindings(body=[WhatsAppMessageTemplateBindingsComponent(ref_value=threeDays.name)])
shippingConfirmationTemplate.bindings = bindings
shippingConfirmationTemplate.template_values=[threeDays]
template_options = TemplateNotificationContent(
channel_registration_id=self.channel_id, to=[self.phone_number], template=shippingConfirmationTemplate
)
发送标头中带有媒体参数的模板消息
使用 MessageTemplateImage
、 MessageTemplateVideo
或 MessageTemplateDocument
在标头中定义媒体参数。
标头中带图像媒体参数的模板定义:
{
"type": "HEADER",
"format": "IMAGE"
},
format
可具有 WhatsApp 支持的不同媒体类型。 在 .NET SDK 中,每个媒体类型都使用相应的 MessageTemplateValue
类型。
Format | MessageTemplateValue 类型 | 文件类型 |
---|---|---|
IMAGE | MessageTemplateImage |
png、jpg |
视频 | MessageTemplateVideo |
mp4 |
DOCUMENT | MessageTemplateDocument |
有关支持的媒体类型和大小限制的更多信息,请参阅 WhatsApp 的消息媒体文档。
示例
sample_movie_ticket_confirmation
模板:
在此示例中,模板的标头需要一个图像:
{
"type": "HEADER",
"format": "IMAGE"
},
模板正文需要四个文本参数:
{
"type": "BODY",
"text": "Your ticket for *{{1}}*\n*Time* - {{2}}\n*Venue* - {{3}}\n*Seats* - {{4}}"
},
创建一个 MessageTemplateImage
和四个 MessageTemplateText
变量。 然后,按照模板内容中参数出现的顺序提供参数,组合 MessageTemplateValue
和 MessageTemplateWhatsAppBindings
的列表。
# Setting template options
templateName = "sample_movie_ticket_confirmation"
templateLanguage = "en_us"
imageUrl = "https://aka.ms/acsicon1"
sample_movie_ticket_confirmation: MessageTemplate = MessageTemplate(name=templateName, language=templateLanguage )
image = MessageTemplateImage(name="image", url=imageUrl)
title = MessageTemplateText(name="title", text="Contoso")
time = MessageTemplateText(name="time", text="July 1st, 2023 12:30PM")
venue = MessageTemplateText(name="venue", text="Southridge Video")
seats = MessageTemplateText(name="seats", text="Seat 1A")
bindings = WhatsAppMessageTemplateBindings(header=[WhatsAppMessageTemplateBindingsComponent(ref_value=image.name)],
body=[WhatsAppMessageTemplateBindingsComponent(ref_value=title.name),
WhatsAppMessageTemplateBindingsComponent(ref_value=time.name),
WhatsAppMessageTemplateBindingsComponent(ref_value=venue.name),
WhatsAppMessageTemplateBindingsComponent(ref_value=seats.name)])
sample_movie_ticket_confirmation.bindings = bindings
sample_movie_ticket_confirmation.template_values=[image,title,time,venue,seats]
template_options = TemplateNotificationContent(
channel_registration_id=self.channel_id, to=[self.phone_number], template=sample_movie_ticket_confirmation)
发送带有快速回复按钮的模板消息
使用 MessageTemplateQuickAction
来定义快速回复按钮的有效负载并且 MessageTemplateQuickAction
对象具有以下三个属性。
属性 | 说明 | 类型 |
---|---|---|
名称 | 用于查找 MessageTemplateWhatsAppBindings 中的值的 name 。 |
string |
文本 | 可选的快速操作 text 。 |
string |
有效负载 | 如果用户选择按钮,则分配给该按钮的 payload 在消息回复中可用。 |
string |
带有快速回复按钮的模板定义:
{
"type": "BUTTONS",
"buttons": [
{
"type": "QUICK_REPLY",
"text": "Yes"
},
{
"type": "QUICK_REPLY",
"text": "No"
}
]
}
按钮在模板定义中出现的顺序必须与使用 MessageTemplateWhatsAppBindings
创建绑定时定义按钮的顺序匹配。
有关用户快速回复响应中有效负载的更多信息,请参阅关于接收来自快速回复按钮的回叫的 WhatsApp 文档。
示例
sample_issue_resolution
模板:
模板正文需要一个文本参数:
{
"type": "BODY",
"text": "Hi {{1}}, were we able to solve the issue that you were facing?"
},
模板包含两个预填充的回复按钮,Yes
和 No
。
{
"type": "BUTTONS",
"buttons": [
{
"type": "QUICK_REPLY",
"text": "Yes"
},
{
"type": "QUICK_REPLY",
"text": "No"
}
]
}
创建一个 MessageTemplateText
和两个 MessageTemplateQuickAction
变量。 然后,按照模板内容中参数出现的顺序提供参数,组合 MessageTemplateValue
和 MessageTemplateWhatsAppBindings
的列表。 在定义绑定按钮时,顺序也很重要。
# Setting template options
templateName = "sample_issue_resolution"
templateLanguage = "en_us"
shippingConfirmationTemplate: MessageTemplate = MessageTemplate(name=templateName, language=templateLanguage )
name = MessageTemplateText(name="first", text="Joe")
yes = MessageTemplateQuickAction(name="Yes", payload="Joe said yes")
no = MessageTemplateQuickAction(name="No", payload = "Joe said no")
bindings = WhatsAppMessageTemplateBindings(body=[WhatsAppMessageTemplateBindingsComponent(ref_value=name.name)])
bindings.buttons = [WhatsAppMessageTemplateBindingsButton(sub_type=WhatsAppMessageButtonSubType.QUICK_REPLY, ref_value=yes.name),
WhatsAppMessageTemplateBindingsButton(sub_type=WhatsAppMessageButtonSubType.QUICK_REPLY, ref_value=no.name)]
shippingConfirmationTemplate.bindings = bindings
shippingConfirmationTemplate.template_values=[name,yes,no]
template_options = TemplateNotificationContent(
channel_registration_id=self.channel_id, to=[self.phone_number], template=shippingConfirmationTemplate
)
发送标头中带有位置的模板消息
使用 MessageTemplateLocation
定义标头中的位置参数。
标头组件的模板定义,需要的位置为:
{
"type": "header",
"parameters": [
{
"type": "location",
"location": {
"latitude": "<LATITUDE>",
"longitude": "<LONGITUDE>",
"name": "<NAME>",
"address": "<ADDRESS>"
}
}
]
}
format
可能需要不同的媒体类型。 在 .NET SDK 中,每个媒体类型都使用相应的 MessageTemplateValue
类型。
属性 | 说明 | 类型 |
---|---|---|
ADDRESS |
地址将显示在 NAME 值之后、消息顶部通用地图下方。 |
string |
LATITUDE |
位置纬度。 | double |
LONGITUDE |
位置经度。 | double |
LOCATIONNAME |
文本将显示在紧邻消息顶部通用地图下方。 | string |
有关基于位置的模板的详细信息,请参阅 WhatsApp 的消息媒体文档。
示例
sample_movie_location
模板:
基于位置的消息模板程序集:
# Setting template options
templateName = "sample_movie_location"
templateLanguage = "en_us"
sample_movie_location: MessageTemplate = MessageTemplate(name=templateName, language=templateLanguage )
name = MessageTemplateText(name="first", text="Joe")
location = MessageTemplateLocation(name="location", location_name="Pablo Morales",
address="1 Hacker Way, Menlo Park, CA 94025",
latitude=37.483307,longitude=122.148981)
bindings = WhatsAppMessageTemplateBindings(body=[WhatsAppMessageTemplateBindingsComponent(ref_value=name.name)],
header=[WhatsAppMessageTemplateBindingsComponent(ref_value=location.name)])
sample_movie_location.bindings = bindings
sample_movie_location.template_values=[name,location]
template_options = TemplateNotificationContent(
channel_registration_id=self.channel_id, to=[self.phone_number], template=sample_movie_location)
发送带有动态链接的行动号召按钮的模板消息
使用 MessageTemplateQuickAction
来定义行动号召按钮的 URL 后缀并且 MessageTemplateQuickAction
对象具有以下两个属性。
属性 | 说明 | 类型 |
---|---|---|
名称 |
name 用于查找 MessageTemplateWhatsAppBindings 中的值。 |
string |
文本 | 追加到 URL 的text 。 |
string |
模板定义按钮:
{
"type": "BUTTONS",
"buttons": [
{
"type": "URL",
"text": "Take Survey",
"url": "https://www.example.com/{{1}}"
}
]
}
按钮在模板定义中出现的顺序必须与使用 MessageTemplateWhatsAppBindings
创建绑定时定义按钮的顺序匹配。
示例
sample_purchase_feedback
模板:
此示例模板向消息添加一个带有动态 URL 链接的按钮。 它还在标头中使用一个图像,在正文中使用一个文本参数。 创建用于 View website
操作类型且带有 Dynamic
URL 类型的行动号召按钮模板。
在此示例中,模板的标头需要一个图像:
{
"type": "HEADER",
"format": "IMAGE"
},
模板正文需要一个文本参数:
{
"type": "BODY",
"text": "Thank you for purchasing {{1}}! We value your feedback and would like to learn more about your experience."
},
该模板包含带有一个参数的动态 URL 按钮:
{
"type": "BUTTONS",
"buttons": [
{
"type": "URL",
"text": "Take Survey",
"url": "https://www.example.com/{{1}}"
}
]
}
创建一个 MessageTemplateImage
、一个 MessageTemplateText
和一个 MessageTemplateQuickAction
变量。 然后,按照模板内容中参数出现的顺序提供参数,组合 MessageTemplateValue
和 MessageTemplateWhatsAppBindings
的列表。 在定义绑定的按钮时,顺序也很重要。
# Setting template options
templateName = "sample_purchase_feedback"
templateLanguage = "en_us"
imageUrl = "https://aka.ms/acsicon1"
sample_purchase_feedback: MessageTemplate = MessageTemplate(name=templateName, language=templateLanguage )
name = MessageTemplateText(name="first", text="Joe")
image = MessageTemplateImage(name="image", url=imageUrl)
uri_to_click = MessageTemplateQuickAction(name="url", text="questions")
bindings = WhatsAppMessageTemplateBindings(body=[WhatsAppMessageTemplateBindingsComponent(ref_value=name.name)],
header=[WhatsAppMessageTemplateBindingsComponent(ref_value=image.name)],
buttons=[WhatsAppMessageTemplateBindingsButton(sub_type=WhatsAppMessageButtonSubType.URL,
ref_value=uri_to_click.name)])
sample_purchase_feedback.bindings = bindings
sample_purchase_feedback.template_values=[name, image, uri_to_click]
template_options = TemplateNotificationContent(
channel_registration_id=self.channel_id, to=[self.phone_number], template=sample_purchase_feedback)
完整示例
import os
import sys
sys.path.append("..")
class SendWhatsAppTemplateMessageSample(object):
connection_string = os.getenv("COMMUNICATION_SAMPLES_CONNECTION_STRING")
phone_number = os.getenv("RECIPIENT_PHONE_NUMBER")
channel_id = os.getenv("WHATSAPP_CHANNEL_ID")
def send_template_message_without_parameters(self):
from azure.communication.messages import NotificationMessagesClient
from azure.communication.messages.models import ( TemplateNotificationContent , MessageTemplate )
# client creation
messaging_client = NotificationMessagesClient.from_connection_string(self.connection_string)
input_template: MessageTemplate = MessageTemplate(
name="<<TEMPLATE_NAME>>",
language="<<LANGUAGE>>")
template_options = TemplateNotificationContent(
channel_registration_id=self.channelRegistrationId,
to=[self.phone_number],
template=input_template
)
# calling send() with WhatsApp template details.
message_responses = messaging_client.send(template_options)
response = message_responses.receipts[0]
if (response is not None):
print("WhatsApp Templated Message with message id {} was successfully sent to {}"
.format(response.message_id, response.to))
else:
print("Message failed to send")
def send_template_message_with_parameters(self):
from azure.communication.messages import NotificationMessagesClient
from azure.communication.messages.models import (TemplateNotificationContent, MessageTemplate,
MessageTemplateText, WhatsAppMessageTemplateBindings, WhatsAppMessageTemplateBindingsComponent)
messaging_client = NotificationMessagesClient.from_connection_string(self.connection_string)
# Setting template options
templateName = "sample_shipping_confirmation"
templateLanguage = "en_us"
shippingConfirmationTemplate: MessageTemplate = MessageTemplate(name=templateName, language=templateLanguage )
threeDays = MessageTemplateText(name="threeDays", text="3")
bindings = WhatsAppMessageTemplateBindings(body=[WhatsAppMessageTemplateBindingsComponent(ref_value=threeDays.name)])
shippingConfirmationTemplate.bindings = bindings
shippingConfirmationTemplate.template_values=[threeDays]
template_options = TemplateNotificationContent(
channel_registration_id=self.channel_id, to=[self.phone_number], template=shippingConfirmationTemplate
)
# calling send() with whatsapp message details
message_responses = messaging_client.send(template_options)
response = message_responses.receipts[0]
print("WhatsApp text parameters Templated Message with message id {} was successfully sent to {}"
.format(response.message_id, response.to))
def send_template_message_with_media(self):
from azure.communication.messages import NotificationMessagesClient
from azure.communication.messages.models import (TemplateNotificationContent, MessageTemplate,
MessageTemplateText, WhatsAppMessageTemplateBindings, WhatsAppMessageTemplateBindingsComponent,
MessageTemplateImage)
messaging_client = NotificationMessagesClient.from_connection_string(self.connection_string)
# Setting template options
templateName = "sample_movie_ticket_confirmation"
templateLanguage = "en_us"
imageUrl = "https://aka.ms/acsicon1"
sample_movie_ticket_confirmation: MessageTemplate = MessageTemplate(name=templateName, language=templateLanguage )
image = MessageTemplateImage(name="image", url=imageUrl)
title = MessageTemplateText(name="title", text="Contoso")
time = MessageTemplateText(name="time", text="July 1st, 2023 12:30PM")
venue = MessageTemplateText(name="venue", text="Southridge Video")
seats = MessageTemplateText(name="seats", text="Seat 1A")
bindings = WhatsAppMessageTemplateBindings(header=[WhatsAppMessageTemplateBindingsComponent(ref_value=image.name)],
body=[WhatsAppMessageTemplateBindingsComponent(ref_value=title.name),
WhatsAppMessageTemplateBindingsComponent(ref_value=time.name),
WhatsAppMessageTemplateBindingsComponent(ref_value=venue.name),
WhatsAppMessageTemplateBindingsComponent(ref_value=seats.name)])
sample_movie_ticket_confirmation.bindings = bindings
sample_movie_ticket_confirmation.template_values=[image,title,time,venue,seats]
template_options = TemplateNotificationContent(
channel_registration_id=self.channel_id, to=[self.phone_number], template=sample_movie_ticket_confirmation)
# calling send() with whatsapp message details
message_responses = messaging_client.send(template_options)
response = message_responses.receipts[0]
print("WhatsApp media parameters in templated message header with message id {} was successfully sent to {}"
.format(response.message_id, response.to))
def send_template_message_with_buttons(self):
from azure.communication.messages import NotificationMessagesClient
from azure.communication.messages.models import (TemplateNotificationContent, MessageTemplate,
MessageTemplateText, WhatsAppMessageTemplateBindings, WhatsAppMessageTemplateBindingsComponent,
MessageTemplateQuickAction, WhatsAppMessageTemplateBindingsButton, WhatsAppMessageButtonSubType)
messaging_client = NotificationMessagesClient.from_connection_string(self.connection_string)
# Setting template options
templateName = "sample_issue_resolution"
templateLanguage = "en_us"
shippingConfirmationTemplate: MessageTemplate = MessageTemplate(name=templateName, language=templateLanguage )
name = MessageTemplateText(name="first", text="Joe")
yes = MessageTemplateQuickAction(name="Yes", payload="Joe said yes")
no = MessageTemplateQuickAction(name="No", payload = "Joe said no")
bindings = WhatsAppMessageTemplateBindings(body=[WhatsAppMessageTemplateBindingsComponent(ref_value=name.name)])
bindings.buttons = [WhatsAppMessageTemplateBindingsButton(sub_type=WhatsAppMessageButtonSubType.QUICK_REPLY, ref_value=yes.name),
WhatsAppMessageTemplateBindingsButton(sub_type=WhatsAppMessageButtonSubType.QUICK_REPLY, ref_value=no.name)]
shippingConfirmationTemplate.bindings = bindings
shippingConfirmationTemplate.template_values=[name,yes,no]
template_options = TemplateNotificationContent(
channel_registration_id=self.channel_id, to=[self.phone_number], template=shippingConfirmationTemplate
)
# calling send() with whatsapp message details
message_responses = messaging_client.send(template_options)
response = message_responses.receipts[0]
print("WhatsApp Quick Button Templated Message with message id {} was successfully sent to {}"
.format(response.message_id, response.to))
def send_template_message_with_location(self):
from azure.communication.messages import NotificationMessagesClient
from azure.communication.messages.models import (TemplateNotificationContent, MessageTemplate,
MessageTemplateText, WhatsAppMessageTemplateBindings, WhatsAppMessageTemplateBindingsComponent,
MessageTemplateLocation)
messaging_client = NotificationMessagesClient.from_connection_string(self.connection_string)
# Setting template options
templateName = "sample_movie_location"
templateLanguage = "en_us"
sample_movie_location: MessageTemplate = MessageTemplate(name=templateName, language=templateLanguage )
name = MessageTemplateText(name="first", text="Joe")
location = MessageTemplateLocation(name="location", location_name="Pablo Morales",
address="1 Hacker Way, Menlo Park, CA 94025",
latitude=37.483307,longitude=122.148981)
bindings = WhatsAppMessageTemplateBindings(body=[WhatsAppMessageTemplateBindingsComponent(ref_value=name.name)],
header=[WhatsAppMessageTemplateBindingsComponent(ref_value=location.name)])
sample_movie_location.bindings = bindings
sample_movie_location.template_values=[name,location]
template_options = TemplateNotificationContent(
channel_registration_id=self.channel_id, to=[self.phone_number], template=sample_movie_location)
# calling send() with whatsapp message details
message_responses = messaging_client.send(template_options)
response = message_responses.receipts[0]
print("WhatsApp Location Templated Message with message id {} was successfully sent to {}"
.format(response.message_id, response.to))
def send_template_message_with_call_to_action(self):
from azure.communication.messages import NotificationMessagesClient
from azure.communication.messages.models import (TemplateNotificationContent, MessageTemplate,
MessageTemplateText, WhatsAppMessageTemplateBindings, WhatsAppMessageTemplateBindingsComponent,
MessageTemplateQuickAction, MessageTemplateImage, WhatsAppMessageTemplateBindingsButton,
WhatsAppMessageButtonSubType)
messaging_client = NotificationMessagesClient.from_connection_string(self.connection_string)
# Setting template options
templateName = "sample_purchase_feedback"
templateLanguage = "en_us"
imageUrl = "https://aka.ms/acsicon1"
sample_purchase_feedback: MessageTemplate = MessageTemplate(name=templateName, language=templateLanguage )
name = MessageTemplateText(name="first", text="Joe")
image = MessageTemplateImage(name="image", url=imageUrl)
uri_to_click = MessageTemplateQuickAction(name="url", text="questions")
bindings = WhatsAppMessageTemplateBindings(body=[WhatsAppMessageTemplateBindingsComponent(ref_value=name.name)],
header=[WhatsAppMessageTemplateBindingsComponent(ref_value=image.name)],
buttons=[WhatsAppMessageTemplateBindingsButton(sub_type=WhatsAppMessageButtonSubType.URL,
ref_value=uri_to_click.name)])
sample_purchase_feedback.bindings = bindings
sample_purchase_feedback.template_values=[name, image, uri_to_click]
template_options = TemplateNotificationContent(
channel_registration_id=self.channel_id, to=[self.phone_number], template=sample_purchase_feedback)
# calling send() with whatsapp message details
message_responses = messaging_client.send(template_options)
response = message_responses.receipts[0]
print("WhatsApp Call To Action Templated Message with message id {} was successfully sent to {}"
.format(response.message_id, response.to))
if __name__ == "__main__":
sample = SendWhatsAppTemplateMessageSample()
sample.send_template_message_without_parameters()
sample.send_template_message_with_parameters()
sample.send_template_message_with_buttons()
sample.send_template_message_with_location()
sample.send_template_message_with_call_to_action()
运行代码
若要运行代码,请确保你位于 messages-quickstart.py
文件所在的目录中。
python messages-quickstart.py
Azure Communication Services - Advanced Messages Quickstart
WhatsApp Templated Message with message id <<GUID>> was successfully sent to <<ToRecipient>>