다음을 통해 공유


WhatsApp 템플릿 메시지 보내기

이 문서에서는 고급 통신 메시지 SDK를 사용하여 WhatsApp 템플릿 메시지를 보내는 지침을 제공합니다.

템플릿 메시지를 보내야 하는 이유는 무엇인가요?

비즈니스는 사용자가 비즈니스에 메시지를 보낼 때까지만 템플릿 메시지를 보낼 수 있습니다.

비즈니스 또는 사용자가 대화 창을 시작할 수 있지만 비즈니스는 보낼 수 있는 메시지 종류가 제한됩니다. 사용자가 비즈니스에 메시지를 보낸 후에만 비즈니스는 활성 대화 중에 사용자에게 문자 또는 미디어 메시지를 보낼 수 있습니다. 24시간 대화 창이 만료되면 대화를 다시 시작해야 합니다. 대화에 대한 자세한 내용은 WhatsApp Business Platform정의를 참조하세요.

템플릿에 대한 추가 WhatsApp 요구 사항은 WhatsApp Business Platform API 참조를 참조하세요.

템플릿 선택

포함된 등록 중에 Azure Portal을 통해 WhatsApp Business 계정을 만들면 샘플 템플릿 집합을 자동으로 사용해 볼 수 있습니다. 예제에서 이러한 샘플 템플릿의 몇 가지 사용량을 참조하세요.

템플릿 만들기

고유한 템플릿을 만들려면 Meta WhatsApp Manager를 사용합니다. WhatsApp Business 계정에 대한 메시지 템플릿 만들기의 메타 비즈니스 도움말 센터의 지침을 따릅니다.

목록 템플릿

Azure Communication Service 리소스 > 템플릿으로 이동하여 Azure Portal에서 템플릿을 볼 수 있습니다.

Screenshot that shows an Azure Communication Services resource in the Azure portal, viewing the 'Templates' tab.

템플릿을 선택하면 템플릿 세부 정보를 볼 수 있습니다.
템플릿 세부 정보의 필드에는 content 매개 변수 바인딩이 포함될 수 있습니다. 매개 변수 바인딩은 다음과 같이 표시될 수 있습니다.

  • 와 같은 IMAGE값이 있는 "형식" 필드입니다.
  • 숫자를 둘러싼 이중 대괄호(예: {{1}}.) 1에서 시작된 인덱싱된 숫자는 메시지 템플릿을 만들기 위해 바인딩 값을 제공해야 하는 순서를 나타냅니다.

Screenshot that shows template details.

또는 WhatsApp Manager> 계정 도구 >메시지 템플릿에서 WhatsApp Business 계정의 모든 템플릿을 보고 편집할 수 있습니다.

프로그래밍 방식으로 템플릿을 나열하려면 채널 ID에 대한 모든 템플릿을 가져올 수 있습니다.

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

빠른 참조

매개 변수가 없는 템플릿

템플릿에서 매개 변수를 사용하지 않는 경우 값을 만들 MessageTemplate때 값이나 바인딩을 제공할 필요가 없습니다.

var messageTemplate = new MessageTemplate(templateName, templateLanguage); 

예시

본문에 텍스트 매개 변수가 있는 템플릿

숫자와 같은 {{1}}숫자를 둘러싼 이중 대괄호로 표시된 본문의 매개 변수를 정의하는 데 사용합니다MessageTemplateText. 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);

예제

헤더에 미디어가 있는 템플릿

MessageTemplateVideo사용MessageTemplateImage하거나 MessageTemplateDocument 헤더에서 미디어 매개 변수를 정의합니다.

이미지 미디어가 필요한 템플릿 정의 헤더:

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

예제

빠른 회신 단추가 있는 템플릿

빠른 회신 단추에 대한 페이로드를 정의하는 데 사용합니다 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의 설명서를 참조하세요.

예시

작업 호출 단추가 있는 템플릿

동작 호출 단추의 URL 접미사를 정의하는 데 사용합니다 MessageTemplateQuickAction .

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 Portal 임베디드 등록을 통해 만든 WhatsApp Business 계정에 사용할 수 있는 샘플 템플릿을 활용합니다.

샘플 템플릿 sample_template 사용

명명된 sample_template 샘플 템플릿은 매개 변수를 사용하지 않습니다.

Screenshot that shows template details for template named sample_template.

MessageTemplate 대상 템플릿의 이름과 언어를 참조하여 어셈블합니다.

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

var sampleTemplate = new MessageTemplate(templateName, templateLanguage); 

샘플 템플릿 sample_shipping_confirmation 사용

일부 템플릿은 매개 변수를 사용합니다. 템플릿에 필요한 매개 변수만 포함합니다. 템플릿에 없는 매개 변수를 포함하는 것은 유효하지 않습니다.

Screenshot that shows template details for template named sample_shipping_confirmation.

이 샘플에서 템플릿 본문에는 하나의 매개 변수가 있습니다.

{
  "type": "BODY",
  "text": "Your package has been shipped. It will be delivered in {{1}} business days."
},

매개 변수는 값 및 MessageTemplateWhatsAppBindings 바인딩으로 MessageTemplateValue 정의됩니다. 값 및 바인딩을 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 사용

템플릿에는 텍스트 및 이미지와 같은 다양한 유형의 매개 변수가 필요할 수 있습니다.

Screenshot that shows template details for template named sample_movie_ticket_confirmation.

이 샘플에서 템플릿의 헤더에는 이미지가 필요합니다.

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

템플릿 본문에는 다음 네 개의 텍스트 매개 변수가 필요합니다.

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

변수 1 MessageTemplateImage 개와 4개를 MessageTemplateText 만듭니다. 그런 다음 매개 변수가 템플릿 콘텐츠에 표시되는 순서대로 매개 변수를 제공하여 목록과 MessageTemplateWhatsAppBindings 사용자의 목록을 MessageTemplateValue 어셈블합니다.

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 사용

이 샘플 템플릿은 머리글의 비디오와 본문에 있는 두 개의 텍스트 매개 변수를 사용합니다.

Screenshot that shows template details for template named 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}}"
},

변수 1 MessageTemplateVideo 개와 2 MessageTemplateText 개를 만듭니다. 그런 다음 매개 변수가 템플릿 콘텐츠에 표시되는 순서대로 매개 변수를 제공하여 목록과 MessageTemplateWhatsAppBindings 사용자의 목록을 MessageTemplateValue 어셈블합니다.

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 사용

이 샘플 템플릿은 머리글의 문서와 본문에 세 개의 텍스트 매개 변수를 사용합니다.

Screenshot that shows template details for template named sample_flight_confirmation.

여기서 서식 파일의 머리글에는 다음 문서가 필요합니다.

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

문서는 호스팅된 pdf 문서의 URL이어야 합니다. 지원되는 미디어 유형 및 크기 제한에 대한 자세한 내용은 메시지 미디어에 대한 WhatsApp의 설명서를 참조하세요.

템플릿 본문에는 다음 세 가지 텍스트 매개 변수가 필요합니다.

{
  "type": "BODY",
  "text": "This is your flight confirmation for {{1}}-{{2}} on {{3}}."
},

변수 1 MessageTemplateDocument 개와 3개를 MessageTemplateText 만듭니다. 그런 다음 매개 변수가 템플릿 콘텐츠에 표시되는 순서대로 매개 변수를 제공하여 목록과 MessageTemplateWhatsAppBindings 사용자의 목록을 MessageTemplateValue 어셈블합니다.

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 사용

이 샘플 템플릿은 미리 채워진 두 개의 회신 단추를 메시지에 추가합니다. 본문에 하나의 텍스트 매개 변수도 포함됩니다.

Screenshot that shows template details for template named 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의 설명서를 참조하세요.

변수 1 MessageTemplateText 개와 2 MessageTemplateQuickAction 개를 만듭니다. 그런 다음 매개 변수가 템플릿 콘텐츠에 표시되는 순서대로 매개 변수를 제공하여 목록과 MessageTemplateWhatsAppBindings 사용자의 목록을 MessageTemplateValue 어셈블합니다. 바인딩 단추를 정의할 때도 순서가 중요합니다.

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 형식을 .로 StaticDynamic수정해야 합니다.
WhatsApp 관리자에서 메시지 템플릿으로 이동하여 에 대한 sample_purchase_feedback템플릿을 편집합니다. URL 형식에 대한 드롭다운에서 URL 형식을 Dynamic.로 Static 변경합니다. 필요한 경우 샘플 URL을 포함합니다.

Screenshot that shows editing URL Type in the WhatsApp manager.

이제 Azure Portal에서 템플릿 세부 정보를 보면 다음이 표시됩니다. Screenshot that shows template details for template named 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 만듭니다. 그런 다음 매개 변수가 템플릿 콘텐츠에 표시되는 순서대로 매개 변수를 제공하여 목록과 MessageTemplateWhatsAppBindings 사용자의 목록을 MessageTemplateValue 어셈블합니다. 바인딩 단추를 정의할 때도 순서가 중요합니다.

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

다음 단계