共用方式為


傳送 WhatsApp 範本訊息

本文件提供使用進階通訊訊息 SDK 傳送 WhatsApp 範本訊息的指引。

為什麼我需要傳送範本訊息?

企業只能傳送範本訊息,直到使用者傳送訊息給企業為止。

企業或使用者可以起始交談視窗,但商務受限於他們可以傳送的訊息種類。 只有在使用者傳送訊息給企業之後,企業才能在作用中交談期間將文字或媒體訊息傳送給使用者。 一旦 24 小時交談視窗過期,就必須重新開始交談。 若要深入了解交談,請參閱 WhatsApp Business Platform 中的定義。

如需範本的進一步 WhatsApp 需求,請參閱 WhatsApp Business Platform API 參考:

選擇範本

如果在內嵌註冊期間透過 Azure 入口網站建立 WhatsApp Business 帳戶,系統可能會自動提供一組範例範本供您試用。請在範例中參閱一些範例範本的使用。

建立範本

若要建立您自己的範本,請使用 Meta WhatsApp Manager。 請前往 Meta Business 說明中心,遵循為 WhatsApp Business 帳戶建立訊息範本中的指示。

列出範本

您可以移至 [Azure 通訊服務資源] > [範本],在 Azure 入口網站中檢視您的範本。

顯示 Azure 入口網站 中 Azure 通訊服務 資源的螢幕快照,檢視 [範本] 索引標籤。

您可以藉由選取範本來檢視範本詳細資料。
範本詳細資料的 content 欄位可能包含參數繫結。 參數繫結可以表示為:

  • 具有值的「格式」欄位,例如 IMAGE
  • 括住數字的雙括弧,例如 {{1}}。 這些數字 (從 1 開始編製索引) 表示必須提供繫結值來建立訊息範本的順序。

顯示範本詳細數據的螢幕快照。

或者,您也可以在 [WhatsApp Manager] > [帳戶工具] > [訊息範本] 中檢視和編輯所有 WhatsApp Business 帳戶的範本。

若要以程式設計方式列出範本,您可以擷取您頻道識別碼的所有範本:

MessageTemplateClient messageTemplateClient = new MessageTemplateClient(connectionString);
Pageable<MessageTemplateItem> templates = messageTemplateClient.GetTemplates(channelRegistrationId);

快速參考

沒有參數的範本

如果範本不採用任何參數,則不需要在建立 MessageTemplate 時提供值或繫結。

var messageTemplate = new MessageTemplate(templateName, templateLanguage); 

範例

內文中具有文字參數的範本

使用 MessageTemplateText,定義內文中透過雙括弧括住數字來表示的參數,例如 {{1}}。 這些數字 (從 1 開始編製索引) 表示必須提供繫結值來建立訊息範本的順序。

範本定義內文:

{
  "type": "BODY",
  "text": "Message with two parameters: {{1}} and {{2}}"
},

訊息範本組件:

var param1 = new MessageTemplateText(name: "first", text: "First Parameter");
var param2 = new MessageTemplateText(name: "second", text: "Second Parameter");

WhatsAppMessageTemplateBindings bindings = new();
bindings.Body.Add(new(param1.Name));
bindings.Body.Add(new(param2.Name));

var messageTemplate = new MessageTemplate(templateName, templateLanguage);
messageTemplate.Bindings = bindings;
messageTemplate.Values.Add(param1);
messageTemplate.Values.Add(param2);

範例

標頭中包含媒體的範本

使用 MessageTemplateImageMessageTemplateVideoMessageTemplateDocument 定義標頭中的媒體參數。

需要影像媒體的範本定義標頭:

{
  "type": "HEADER",
  "format": "IMAGE"
},

「格式」可能需要不同的媒體類型。 在 .NET SDK 中,每個媒體類型都會使用對應的 MessageTemplateValue 類型。

格式 MessageTemplateValue 類型 檔案類型
IMAGE MessageTemplateImage png、jpg
影片 MessageTemplateVideo mp4
DOCUMENT MessageTemplateDocument PDF

若要深入了解支援的媒體類型和大小限制,請參閱 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);

範例

標頭中具有位置的範本

使用 MessageTemplateLocation 在標頭中定義location 參數。

標頭元件的範本定義,需要位置為:

{
  "type": "header",
  "parameters": [
    {
      "type": "location",
      "location": {
        "latitude": "<LATITUDE>",
        "longitude": "<LONGITUDE>",
        "name": "<NAME>",
        "address": "<ADDRESS>"
      }
    }
  ]
}

「格式」可能需要不同的媒體類型。 在 .NET SDK 中,每個媒體類型都會使用對應的 MessageTemplateValue 類型。

屬性 描述 類型
地址 在訊息頂端的泛型對應下方,會出現在 『NAME』 值之後的位址。 字串
緯度 位置緯度。 double
經度 位置經度。 double
LOCATIONNAME 會出現在訊息頂端泛型對應正下方的文字。 字串

如需位置型範本的詳細資訊,請參閱 WhatsApp 的訊息媒體檔。

以位置為基礎的訊息模組:

 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;

範例

此螢幕快照顯示名為 sample_location_template 之範本的範本詳細數據。

具有快速回覆按鈕的範本

使用 MessageTemplateQuickAction 來定義快速回覆按鈕的承載。

MessageTemplateQuickAction 物件且具有下列三個屬性。
特別是針對快速回覆按鈕,請遵循這些指引來建立您的 MessageTemplateQuickAction 物件。

  • name
    name 會用來查閱 MessageTemplateWhatsAppBindings 中的值。
  • text
    不會使用 text 屬性。
  • payload
    如果使用者選擇按鈕,則可在訊息回覆中使用指派給按鈕的 payload

範本定義按鈕:

{
  "type": "BUTTONS",
  "buttons": [
    {
      "type": "QUICK_REPLY",
      "text": "Yes"
    },
    {
      "type": "QUICK_REPLY",
      "text": "No"
    }
  ]
}

按鈕出現在範本定義中的順序,應該符合使用 MessageTemplateWhatsAppBindings 建立繫結時定義按鈕的順序。

訊息範本組件:

var yes = new MessageTemplateQuickAction(name: "Yes", payload: "User said yes");
var no = new MessageTemplateQuickAction(name: "No", payload: "User said no");

var yesButton = new WhatsAppMessageTemplateBindingsButton(WhatsAppMessageButtonSubType.QuickReply.ToString(), yes.Name);
var noButton = new WhatsAppMessageTemplateBindingsButton(WhatsAppMessageButtonSubType.QuickReply.ToString(), no.Name);

WhatsAppMessageTemplateBindings bindings = new();
bindings.Buttons.Add(yesButton);
bindings.Buttons.Add(noButton);

var messageTemplate = new MessageTemplate(templateName, templateLanguage);
messageTemplate.Bindings = bindings;
template.Values.Add(yes);
template.Values.Add(no);

若要深入了解使用者快速回覆回應中的承載,請參閱 WhatsApp 文件的從快速回覆按鈕接收的回呼

範例

具有動作呼叫按鈕的範本

使用 MessageTemplateQuickAction 來定義動作呼叫按鈕的 URL 尾碼。

MessageTemplateQuickAction 物件且具有下列三個屬性。
特別是針對動作呼叫按鈕,請遵循這些指引來建立您的 MessageTemplateQuickAction 物件。

  • name
    name 會用來查閱 MessageTemplateWhatsAppBindings 中的值。
  • text
    text 屬性會定義附加至 URL 的文字。
  • payload
    不需要 payload 屬性。

範本定義按鈕:

{
  "type": "BUTTONS",
  "buttons": [
    {
      "type": "URL",
      "text": "Take Survey",
      "url": "https://www.example.com/{{1}}"
    }
  ]
}

按鈕出現在範本定義中的順序,應該符合使用 MessageTemplateWhatsAppBindings 建立繫結時定義按鈕的順序。

訊息範本組件:

var urlSuffix = new MessageTemplateQuickAction(name: "text", text: "url-suffix-text");

var urlButton = new WhatsAppMessageTemplateBindingsButton(WhatsAppMessageButtonSubType.Url.ToString(), urlSuffix.Name);

WhatsAppMessageTemplateBindings bindings = new();
bindings.Buttons.Add(urlButton);

var messageTemplate = new MessageTemplate(templateName, templateLanguage);
messageTemplate.Bindings = bindings;
messageTemplate.Values.Add(urlSuffix);

範例

範例

這些範例會利用範例範本,也就是是透過 Azure 入口網站內嵌註冊建立 WhatsApp Business 帳戶時提供的範本。

使用範例範本 sample_template

名為 sample_template 的範例範本不會採用任何參數。

顯示名為 sample_template 之範本詳細數據的螢幕快照。

藉參考目標範本的名稱與語言來組合 MessageTemplate

string templateName = "sample_template"; 
string templateLanguage = "en_us"; 

var sampleTemplate = new MessageTemplate(templateName, templateLanguage); 

使用範例範本 sample_shipping_confirmation

有些範本會採用參數。 只包含範本所需的參數。 不可包含不在範本中的參數。

顯示名為 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);

使用範例範本 sample_movie_ticket_confirmation

範本可能需要各種類型的參數,例如文字和影像。

此螢幕快照顯示名為 sample_movie_ticket_confirmation 之範本的範本詳細數據。

在此範例中,範本的標頭需要影像:

{
  "type": "HEADER",
  "format": "IMAGE"
},

範本的內文需要四個文字參數:

{
  "type": "BODY",
  "text": "Your ticket for *{{1}}*\n*Time* - {{2}}\n*Venue* - {{3}}\n*Seats* - {{4}}"
},

建立一個 MessageTemplateText 和四個 MessageTemplateImage 變數。 然後,以參數出現在範本內容中的順序提供參數,組合您的 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;

使用範例範本 sample_happy_hour_announcement

此範例範本會在標頭中使用影片,以及在內文中使用兩個文字參數。

此螢幕快照顯示名為 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}}"
},

建立一個 MessageTemplateText 和兩個 MessageTemplateVideo 變數。 然後,以參數出現在範本內容中的順序提供參數,組合您的 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

此範例範本會在標頭中使用文件,以及在內文中使用三個文字參數。

顯示名為 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;

使用範例範本 sample_issue_resolution

此範例範本會將兩個預先填入的回覆按鈕新增至訊息。 也會在內文中包含一個文字參數。

顯示名為 sample_issue_resolution 之範本詳細數據的螢幕快照。

在這裡,範本的內文需要一個文字參數:

{
  "type": "BODY",
  "text": "Hi {{1}}, were we able to solve the issue that you were facing?"
},

而範本包含兩個預先填入的回覆按鈕,YesNo

{
  "type": "BUTTONS",
  "buttons": [
    {
      "type": "QUICK_REPLY",
      "text": "Yes"
    },
    {
      "type": "QUICK_REPLY",
      "text": "No"
    }
  ]
}

快速回覆按鈕會定義為 MessageTemplateQuickAction 物件,並具有三個屬性:

  • name
    name 會用來查閱 MessageTemplateWhatsAppBindings 中的值。
  • text
    使用快速回覆按鈕時,不會使用 text 屬性。
  • payload
    如果使用者選擇按鈕,則可在訊息回覆中使用指派給按鈕的 payload

如需有關按鈕的詳細資訊,請參閱 WhatsApp 的按鈕參數物件文件。

建立一個 MessageTemplateQuickAction 和兩個 MessageTemplateText 變數。 然後,以參數出現在範本內容中的順序提供參數,組合您的 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;

使用範例範本 sample_purchase_feedback

此範例範本會將具有動態 URL 連結的按鈕新增至訊息。 也會在標頭中使用影像,並在內文中使用文字參數。

如果使用預先建立的範例範本 sample_purchase_feedback,您必須將其按鈕的 URL 類型從 Static 修改為 Dynamic
移至 WhatsApp 管理員中的訊息範本,並編輯 sample_purchase_feedback 的範本。 在 URL 類型的下拉式清單中,將其從 Static 變更為 Dynamic。 如有必要,請包含範例 URL。

顯示 WhatsApp 管理員中編輯 URL 類型的螢幕快照。

現在,如果您在 Azure 入口網站中檢視範本詳細資料,您會看到:此螢幕快照顯示名為 sample_purchase_feedback 之範本的範本詳細數據。

在此範例中,範本的標頭需要影像:

{
  "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}}"
    }
  ]
}

網站連結的動作呼叫按鈕會定義為 MessageTemplateQuickAction 物件,並具有三個屬性:

  • name
    name 會用來查閱 MessageTemplateWhatsAppBindings 中的值。
  • text
    使用網站連結的動作呼叫按鈕時,text 屬性會定義附加至 URL 的文字。
    在此範例中,我們的 text 值為 survey-code。 在使用者接收的訊息中,他們會看到將他們連結至 URL https://www.example.com/survey-code 的按鈕。
  • payload
    使用網站連結的動作呼叫按鈕時,不需要 payload 屬性。

如需有關按鈕的詳細資訊,請參閱 WhatsApp 的按鈕參數物件文件。

建立一個 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;

完整的程式碼範例

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");
        }
    }
}

下一步