iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 10
0
Modern Web

用Vue實作一個LINE@聊天機器人後台系列 第 10

[Day10] 寫一個基本的WebHook(一):使用.NET Core MVC撰寫API

接下來為我們的Line官方帳號寫一個WebHook。
Line的WebHook的概念就是:在LINE的後台設定一個Api網址用來訂閱在Line官方帳號上面發生的事件
當事件發生的時候,這個設定的Api網址就會被呼叫
要製作一個基本的、具有回話功能的WebHook,需要經歷下面幾個步驟:

  1. 撰寫一個WebHook的Api Function,當訂閱事件發生時進行處理
  2. 建設Server環境,把程式佈版上去
  3. 申請SSL憑證,Line的相關服務幾乎都需要是https開頭的網址

本篇將會包含第一步驟的內容:

LINE WebHook事件的種類

在Line官方帳號中,會接收到的WebHook事件基本上有這一些:

  • 收到訊息的事件:Message event
    • 文字訊息:Text
    • 圖片訊息:Image
    • 影片訊息:Video
    • 聲音訊息:Audio
    • 檔案訊息:File
    • 位置訊息:Location
    • 貼圖訊息:Sticker
  • 官方帳號被加入好友事件:Follow event
  • 官方帳號被封鎖事件:Unfollow event
  • 開發者定義的回傳資料訊息事件:Postback event

一個文字訊息的Webhook物件範例

當有使用者發送訊息給你的官方帳號時,LINE會用下面這段JSON作為參數呼叫你的WebHook Api:
其中會包含一個傳送目標destination跟多個事件的集合events

{
  "destination": "你的Line官方帳號的UserId", 
  "events": [
    {
      "replyToken": "用來回覆訊息的Token",
      "type": "message",
      "timestamp": 1462629479859,
      "source": {
        "type": "user",
        "userId": "傳送訊息來的UserId"
      },
      "message": {
        "id": "訊息的代號",
        "type": "訊息的類型",
        "text": "文字訊息的內容"
      }
    }
  ]
}

建立對應格式的C#物件

目前先以接收文字訊息作為目標,建立幾個C#的Class:
可以複製上面這段JSON,至Vistual Studio中使用選擇性貼上>貼上JSON作為類別來快速產生C#物件

   public class LineEvents
    {
        public string destination { get; set; }
        public Event[] events { get; set; }
    }

    public class Event
    {
        public string replyToken { get; set; }
        public string type { get; set; }
        public long timestamp { get; set; }
        public Source source { get; set; }
        public Message message { get; set; }
    }

    public class Source
    {
        public string type { get; set; }
        public string userId { get; set; }
    }

    public class Message
    {
        public string id { get; set; }
        public string type { get; set; }
        public string text { get; set; }
    }

LINE MessageAPI

MessageAPI關於發送訊息主要分成兩大部分:

  • PushApi:主動推播訊息給官方帳號的好友,使用UserId作為發送的目標
  • ReplyApi:當發生WebHook事件時,使用Event對應到的replyToken作為發送的目標
    本篇將會用到ReplyApi的部分:

ReplyApi介紹

下面是要呼叫ReplyApi,Request所需要輸入的參數:

ReplyApiUrl:https://api.line.me/v2/bot/message/reply

請求的表頭:Request headers

欄位名稱 範例內容 說明
Content-Type application/json Body中必須是JSON格式的字串
Authorization Bearer {channel access token} channel access token是LINE官方帳號的一組認證碼,可以用來串接MessageAPI

請求的表身:Request headers

欄位名稱 型態 是否必填 範例內容 說明
replyToken 字串 "e09b7d03bc074fbd93a4941efc71f0ea" Webhook事件中會提供的token,用來回覆訊息使用。
messages 訊息物件的陣列 [{"type":"text","message","測試一下"}] 訊息物件的陣列,最多一次可以傳送五則訊息
notificationDisabled Boolean 預設值是false 設定為true時,官方帳號發出訊息時,好友將不會收到提醒

撰寫WebHook的POST API

如何查看channel access token

  • 進入到Line Developer Console

https://developers.line.biz/console/

  • 選擇Channel所屬的Provider
  • 選擇MessageAPI的Channel
  • 移至Messaging settings的區塊,即可看到channel access token
  • 如果沒有現有的channel access token,可以點擊Issue產生一個

ReplyMessage的前置準備

這邊要針對訊息事件文字訊息撰寫回應訊息(ReplyMessage)的程式

  • 建立一個文字訊息的類別TextMessage:
    public class TextMessage
    {
        public string type { get {return "text";} }
        public string text { get; set; }
    }
  • 建立一個回應訊息的類別ReplyMessageModel:
public class ReplyMessageModel
    {
        public string replyToken { get; set; }
        public bool notificationDisabled { get; set; }
        public List<object> messages { get; set; }
    }
  • 建立一個產生文字訊息物件的方法BuildTextMessage:
private TextMessage BuildTextMessage(string msg)
{
    return new TextMessage()
    {
        message = "msg"
    };
}

API的內容

  • 我們會用如下的程式先判斷事件的類別,如果是訊息事件,再判斷是哪一種類型的訊息。
  • 如果是文字訊息,要把對方傳來的話再丟回去。
 private string accesstoken = "";
 private string replyApiUrl = "";
 
 [HttpPost]
 public async Task<IActionResult> WebHook([FromBody]LineEvents request)
 {
     foreach (Event eventObj in request.events)
     {
        //判斷事件的類別
        switch (eventObj.type)
        {
            //如果是訊息事件
            case "message":
                switch (eventObj.message.type)
                {
                    //如果是文字訊息
                    case "text":
                    //todo 回傳對方傳來的訊息回去
                    break;
                }
                break;
        }
     }
            return OK();
}
  • 以下是回應訊息的語法
  • 這邊使用HttpClient物件來Call LINE的Reply API
  • 在WebHook方法中,foreach迴圈的上方加入以下語法:
//建立一個HttpClient物件,用來發出請求
HttpClient client = new HttpClient();
//填入token
client.DefaultRequestHeaders.Add("Authorization", $"Bearer{accesstoken}");
//設定Body的型態
client.DefaultRequestHeaders
      .Accept
      .Add(new MediaTypeWithQualityHeaderValue("application/json"));
//設定請求的body的Url&請求類型
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, replyApiUrl);
  • 在WebHook方法中,todo 回傳對方傳來的訊息回去處加入以下語法:
TextMessage content = BuildTextMessage($"我收到了:{eventObj.message.text}");
//建立回傳訊息的物件
ReplyMessageModel reply = new ReplyMessageModel()
{
    replyToken = eventObj.replyToken,
    messages = new List<object>(){
                            BuildTextMessage
    }
};
//將回傳訊息的物件放入請求的body
string param = JsonConvert.SerializeObject(reply);
request.Content = new StringContent(param,
                                    Encoding.UTF8,
                                    "application/json");
//發出請求
await client.SendAsync(request);

預期的結果

假設有人對官方帳號說話時,我們會自動回應他:我收到了:{對方說的話的內容}
例如有人說:你好,API將會自動回應他:我收到了:你好


上一篇
[Day09] 如何申請一個Line官方帳號
下一篇
[Day11] 寫一個基本的WebHook(二):架設Centos Server環境
系列文
用Vue實作一個LINE@聊天機器人後台30

尚未有邦友留言

立即登入留言