第12 屆iT邦幫忙鐵人賽系列文章 (Day9)

這篇會開始進入一些較複雜的訊息格式,我們要來做一個婚紗輪播,讓各種參加喜宴的朋友瀏覽,今天先來看成果

Template message

在 Line 的 Template 有分為四種,可以用來引導使用者做下一步的動作

Template Message 發送的結構如下

本次要用 ImageCarousel 來實作

擴充 LineReplyMessageUtility.cs

我們在發送的 class 的擴充

    public async Task ReplyTemplateMessageAsync(string replyToken, ImageCarouselTemplate template)
    {
     using (var httpClient = new HttpClient())
     {
      using (var request = new HttpRequestMessage(new HttpMethod("POST"), $"{lineMessageApiBaseUrl}"))
      {
       request.Headers.TryAddWithoutValidation("Authorization", $"Bearer {accessToken}");

    LineMessageReq req = new LineMessageReq();
       req.ReplyToken = replyToken;

    req.Messages.Add(new TemplateMessageBase()
       {
        Template = template
       });

    var postJson = JsonConvert.SerializeObject(req, new JsonSerializerSettings
       {
        NullValueHandling = NullValueHandling.Ignore,
        ContractResolver = new DefaultContractResolver
        {
         NamingStrategy = new CamelCaseNamingStrategy()
        },
        Formatting = Formatting.Indented
       });

    request.Content = new StringContent(postJson);
       request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
       var response = await httpClient.SendAsync(request);
       var result = await response.Content.ReadAsStringAsync();
      }
     }
    }

TemplateMessageBase.cs 定義一個 ITemplate 來用來接受上面四種訊息的格式,要特別注意 TemplateMessage 尚未支援桌面版的 Line,故可以加一些提示文字

    public class TemplateMessageBase : IMessage

    {

    public LineMessageType Type => LineMessageType.template;

    public string AltText => "此訊息不支援桌面版的Line";

    public ITemplate Template { get; set; }

    }

定義 ImageCarouselTemplate 來實作 ITemplate

一樣看文件將 JSON 轉成 Class

    public class ImageCarouselTemplate : ITemplate

    {

    public string Type => "image_carousel";

    public List<ColumnAction> Columns { get; set; }

    }

ColumnAction.cs

    public class ColumnAction

    {

    public string ImageUrl { get; set; }

    public IAction Action { get; set; }

    }

IAction 是什麼呢? 又是一個介面

看到我們又定義一個介面,代表又是包含多種實作了,在文章一開始有提到,做 chatbot 引導很重要,在 Line 裡面可以設計一些按鈕,來做一些操作,目前類型共提供 7 種,但本系列文就不一一寫文章介紹 Action 了,相信大家也很會看文件轉 C# 了,遇到功能需要時再來實作

  • Postback action:觸發回傳Api事件,這也會是特別的一個 WebHook 事件,同時可以帶一些參數,蠻實用的,我們後幾篇文章再來詳細介紹這個
  • Message action:引導使用者輸入設定的文字
  • URI action:網址類型,點擊了會在 Line 開啟所設定的 URL,甚至類型是 tel:{photo number} 也行,會直接引導撥打電話,line:// 開頭會引導開啟 Line 的 Liff App (我們之後文章就會實作到啦~)
  • Datetime picker action:日期選擇器,讓使用者直接選一個日期與時間
  • Camera action:開啟相機
  • Camera roll action:開啟相簿
  • Location action:偵測目前使用者的位置,並讓他們設定實際位置並回傳

以本章需求為例,我們希望可以點擊婚紗的圖片原始檔,我們繼承 IAction 實作一個 UriAction

    public class UriAction : IAction

    {

    /// <param name="uri">網址</param>

    /// <param name="label">顯示文字</param>

    public UriAction(string uri, string label)

    {

    Uri = uri;

    Label = label;

    }

    public string Uri { get; set; }

    public ActionType Type => ActionType.uri;

    public string Label { get; set; }

    }

實作婚紗輪播 Intent

    public class PhotoCarousel : IReplyIntent

    {

    private readonly LineReplyMessageUtility lineMessageUtility;

    private readonly LineProfileUtility lineProfileUtility;

    public PhotoCarousel(LineReplyMessageUtility _lineMessageUtility, LineProfileUtility _lineProfileUtility)

    {

    lineMessageUtility = _lineMessageUtility;

    lineProfileUtility = _lineProfileUtility;

    }

    public async Task ReplyAsync(string replyToken)

    {

    var imageCarouselTemplate = new ImageCarouselTemplate();

    var columns = new List<ColumnAction>();

    var photos = new List<string>()

    {

    "https://imgur.com/ZChLjeG.jpg",

    "https://imgur.com/uElHkw8.jpg",

    "https://imgur.com/fbQ5gu4.jpg",

    "https://imgur.com/9Gwzi36.jpg",

    "https://imgur.com/Y7uBXxb.jpg",

    "https://imgur.com/XaCigCi.jpg",

    "https://imgur.com/dDcoMPI.jpg",

    "https://imgur.com/vn6ZK6f.jpg"

    };

    // 隨機取得三筆

    var selected = photos.OrderBy(x => new Random().Next()).Take(3);

    foreach (var photo in selected)

    {

    columns.Add(new ColumnAction()

    {

    ImageUrl = photo,

    Action = new UriAction(photo, "Learn more")

    });

    }

    imageCarouselTemplate.Columns = columns;

    await lineMessageUtility.ReplyTemplateMessageAsync(replyToken, imageCarouselTemplate);

    }

    }

LineBotApp.cs

有啥限制嗎?

  • ImageCarouselTemplate 在傳送的時候最多只能傳10張照片
  • URL 最大 1000 字元
  • 一定要是 HTTPS 且加密規範 TLS 1.2 以上
  • 檔案大小上限 200 MB
  • 圖片需為 JPEG or PNG

懶人包,本次學到了什麼?