iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 6
0
影片教學

用Django架構建置專屬的LINEBOT吧系列 第 6

[Day 6]用Django架構建置專屬的LINEBOT吧 - webhook event

在一切就序之後,
我們便可以針對LINEBOT想要做的反應進行設計,

webhook event概要

LINE那邊在收到訊息之後會將資訊以JSON格式的方式丟到webhook URL,
官方提供的範例是長這樣的

{
  "destination": "xxxxxxxxxx",
  "events": [
    {
      "replyToken": "0f3779fba3b349968c5d07db31eab56f",
      "type": "message",
      "mode": "active",
      "timestamp": 1462629479859,
      "source": {
        "type": "user",
        "userId": "U4af4980629..."
      },
      "message": {
        "id": "325708",
        "type": "text",
        "text": "Hello, world"
      }
    },
    {
      "replyToken": "8cf9239d56244f4197887e939187e19e",
      "type": "follow",
      "mode": "active",
      "timestamp": 1462629479859,
      "source": {
        "type": "user",
        "userId": "U4af4980629..."
      }
    }
  ]
}

這串落落長的JSON資料,對程式初學者來說應該是看不懂在幹嘛,
JSON格式的資料是由若干key:value所組成的資料,
並且用:隔開key跟value,然後用{}包起來,
而有趣的是,value本身也可以是以JSON或其他格式寫入的,
就例如:

{ "name":"maso",
  "sex":"boy",
  "age":"18",
  "intrest":"[coding,eating,travel,movies]",
  "body":{"height":"180cm","weight":"70kg"}
}

因此JSON格式的資料有助於以樹狀圖的方式將資料進行系統性的分類及查詢,
這個是LINE在收發資訊時主要使用的格式,

由webhook event觸發reply_message

之前有提過,
webhook就是LINE官方收到用戶的相關資訊後回傳給你的一種方式,
那當然不外乎在有人加入好友、收到訊息、退出群組或加入群組等等,
各種機器人收到的資訊都會有webhook訊息傳過來,
webhook發生時,被定義為發生一個"event(事件)",
因此今天這篇主要歸納LINEBOT開發中,有哪些會觸發webhook的事件。

首先當然就是最常見的,訊息事件(MessageEvent)
訊息事件有分為下列幾種:
1.文字訊息
2.圖片訊息
3.影片訊息
4.貼圖訊息
5.聲音訊息
6.位置訊息
7.檔案訊息(只能在群組內被觸發)

以上幾種是基本的訊息事件,在這篇先簡單介紹這幾項,
其他還有更多的事件留到之後介紹囉

首先我們如果希望能夠當LINEBOT裡面觸發以上訊息事件並做出反應時,
可以在views.py檔案中新增下列程式碼:

#views.py
#需要注意在from linebot.models import * <=原來的要改成像這樣的星號

@csrf_exempt
def callback_1654395680(request):
    if request.method == 'POST':
        #先設定一個要回傳的message空集合
        message=[]
        signature = request.META['HTTP_X_LINE_SIGNATURE']
        body = request.body.decode('utf-8')
        
        #在這裡將body寫入機器人回傳的訊息中,可以更容易看出你收到的webhook長怎樣#
        message.append(TextSendMessage(text=str(body)))

        try:
            events = parser.parse(body, signature)
        except InvalidSignatureError:
            return HttpResponseForbidden()
        except LineBotApiError:
            return HttpResponseBadRequest()

        for event in events:
            #如果事件為訊息
            if isinstance(event, MessageEvent):
                print(event.message.type)
                if event.message.type=='text':
                    message.append(TextSendMessage(text='文字訊息'))
                    line_bot_api.reply_message(event.reply_token,message)

                elif event.message.type=='image':
                    message.append(TextSendMessage(text='圖片訊息'))
                    line_bot_api.reply_message(event.reply_token,message)

                elif event.message.type=='location':
                    message.append(TextSendMessage(text='位置訊息'))
                    line_bot_api.reply_message(event.reply_token,message)

                elif event.message.type=='video':
                    message.append(TextSendMessage(text='影片訊息'))
                    line_bot_api.reply_message(event.reply_token,message)


                elif event.message.type=='sticker':
                    message.append(TextSendMessage(text='貼圖訊息'))
                    line_bot_api.reply_message(event.reply_token,message)

                elif event.message.type=='audio':
                    message.append(TextSendMessage(text='聲音訊息'))
                    line_bot_api.reply_message(event.reply_token,message)

                elif event.message.type=='file':
                    message.append(TextSendMessage(text='檔案訊息'))
                    line_bot_api.reply_message(event.reply_token,message)


按照上列的方式設定完畢之後,
即可嘗試傳送各種訊息以確認這些訊息是否成功觸發webhook event,
在上面我也先將webhook的JSON的訊息設定直接回傳到對話框,
會比較容易看出LINE發出的webhook到底長什麼樣子了,
也可以依據想要回覆的訊息類型做分類,

非message type的event

在文字訊息處理的部分相信大家都已經比較容易上手,
因此接下來將會針對圖片、聲音、位置與影片訊息進行一些使用的介紹,
先來看還有哪些其他的webhook event囉~

除了message event以外,
在官方開放的API也包括下面的這幾種:
8.加入好友
9.封鎖好友
10.被邀請進入群組
11.被踢出群組
12.LINEBOT所在群組有人被邀請進入
13.LINEBOT所在群組有人離開
14.LINEBOT收到Postback訊息

#views.py
            elif isinstance(event, FollowEvent):
                print('加入好友')
                line_bot_api.reply_message(event.reply_token,message)

            elif isinstance(event, UnfollowEvent):
                print('取消好友')

            elif isinstance(event, JoinEvent):
                print('進入群組')
                line_bot_api.reply_message(event.reply_token,message)

            elif isinstance(event, LeaveEvent):
                print('離開群組')
                line_bot_api.reply_message(event.reply_token,message)

            elif isinstance(event, MemberJoinedEvent):
                print('有人入群')
                line_bot_api.reply_message(event.reply_token,message)

            elif isinstance(event, MemberLeftEvent):
                print('有人退群')
                line_bot_api.reply_message(event.reply_token,message)

            elif isinstance(event, PostbackEvent):
                print('PostbackEvent')

以上13種webhook event,
是最常使用的webhook事件,
因此開始進行功能新增之前,
也可以在views.py新增這些webhook event,
先作為LINEBOT的基礎架構,

由webhook中抓取指定的內容

這邊特別先說明一下,
收到從LINE傳來的webhook event之後,
如果要獲得相關資訊,只要根據webhook event的JSON資料格式,
由於JSON都是以{key:value},
舉例當文字訊息傳送時,
以下為文字訊息的event內容:

{
  "destination": "xxxxxxxxxx",
  "events": [
    {
      "replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
      "type": "message",
      "mode": "active",
      "timestamp": 1462629479859,
      "source": {
        "type": "user",
        "userId": "U4af4980629..."
      },
      "message": {
        "id": "325708",
        "type": "text",
        "text": "Hello, world! (love)",
        "emojis": [
          {
            "index": 14,
            "length": 6,
            "productId": "5ac1bfd5040ab15980c9b435",
            "emojiId": "001"
          }
        ]
      }
    }
  ]
}

以event.加上對應的key,
如:event.message.text
即可用來取得來取得文字內容,

而event.source.user_id,
即可取得傳送文字訊息的用戶ID,

常使用到的postback action中,
postback event的範例如下:

{
  "destination": "xxxxxxxxxx",
  "events": [
    {
      "replyToken": "b60d432864f44d079f6d8efe86cf404b",
      "type": "postback",
      "mode": "active",
      "source": {
        "userId": "U91eeaf62d...",
        "type": "user"
      },
      "timestamp": 1513669370317,
      "postback": {
        "data": "storeId=12345",
        "params": {
          "datetime": "2017-12-25T01:00"
        }
      }
    }
  ]
}

因此若需要取得postback傳送的資料,
則可以event.postback.data獲得,
並且同樣設定相對應的反應,
以上就是關於LINE webhook event的基本介紹囉~

====================↓2020.10.25內容更新=====================
感謝網友Jacky的提醒,

在本章節的操作時,如果有出下列問題,
https://ithelp.ithome.com.tw/upload/images/20201025/20121176o1ZPZ0M9I3.jpg

要記得把import line-bot-sdk那邊的

from line.models import MessageEvent, TextSendMessage

改成

from line.models import *

====================↑2020.10.25內容更新=====================


上一篇
[Day 5]用Django架構建置專屬的LINEBOT吧 - 資料庫後台設定
下一篇
[Day 7]用Django架構建置專屬的LINEBOT吧 - Rich Menu
系列文
用Django架構建置專屬的LINEBOT吧30

尚未有邦友留言

立即登入留言