LINEのWebhookを受信するのに、困ったことがありました。
きっと他にも同じようなことがあると思ったので、残しておきます。
Webhookの受け取り
LINEのWebhook
LINEのWebhookでは以下のようなイベントが取得できます。
- 公式アカウントでメッセージ受信
- 公式アカウントへの送信取り消し
- 公式アカウントのフォロー
- 公式アカウントのフォロー解除
- 公式アカウントのグループトークへの参加
- 公式アカウントをグループトークから削除された/退出した
- 公式アカウントがメンバーになっているグループトークに参加があった
- 公式アカウントがメンバーになっているグループトークからユーザーが退出した
- ポストバックアクション実行
- 動画視聴完了
今回は以下のようにイベントを検知して実装する想定でした。
- ユーザー追加された際に、Bubbleのfriendテーブルへユーザーデータを追加する
- ブロックされた際に、friendテーブルのステータスを「ブロック中」にする
- 公式アカウントへメッセージが送信された時、管理者にお知らせを送信する
つまり「フォロー」「フォロー解除」「メッセージ受信」のイベントを使う想定でした。
Webhook受信の設定を行う
さてここで、BubbleでWebhookを受信するには、APIワークフローを作成します。
LINEからこのURLを呼び出すので「Expose as a public API workflow」にチェックを入れてください。
また、認証を挟むことができないので「This workflow can be run without authentication」にもチェックを入れました。

パラメータを自動設定するには、Parameter definitionを「Detect request data」にし、「Detect Data」をクリックします。

初期化用のURLが表示されるので、コピーします。

WebhookのURLにこれを設定します。
LINEの場合は、LINE DevelopersからMessaging APIチャネルを作成し、Messaging API設定のWebhook設定でURLを設定します。
初期化が完了したら、URLの「/initialize」を削除してください。

設定後に、LINEから公式アカウントにメッセージ送信すると、Webhookで上記URLを呼びだします。
検証時はinitializeのURLがポップアップで表示された状態でAPI呼び出しをしてください。
LINE Webhookの検証ボタンをクリックしても疎通確認ができます。

疎通確認した場合は、以下のような内容になり、イベントのパラメータが取得できません。

公式LINEアカウントへメッセージ送信した場合、以下のようになります。

具体的なJSONはこんな感じです。
{
"destination": "Ub579f20cc182ef34f3d7561a69b4d092",
"events": [
{
"type": "message",
"message": {
"type": "text",
"id": "555105225971597519",
"quoteToken": "KKScIFz8eHH7Wj3pPCTO6wUTn8qQnL46QSTnKuplmIqyErapHdeqEHCj4gie7rVzCf7wIP77_Z_gw4coDVVHrZwrB79dda7plA4I4xn_ihodD5nT1TBx6Iu895MJPLYVCaEJB84T09vTLx7ghyKb0w",
"text": "テスト"
},
"webhookEventId": "01JQY9PY7WAJQJ2E23KE5GDJHB",
"deliveryContext": {
"isRedelivery": false
},
"timestamp": 1743699802236,
"source": {
"type": "user",
"userId": "xxxxxxxxxxxxxxxxxxxxx"
},
"replyToken": "ff37ea54c35b4a68aec1b21c74d5ca82",
"mode": "active"
}
]
}
さて、このJSONの中身と「フォロー」「フォロー解除」イベントを見比べてください。
上記には、以下のパラメータが含まれていないですよね。
"follow": {
"isUnblocked": false
}

このままじゃ、フォロー時のWebhookで「follow.isUnblocked」が使えないじゃん!!
1つのURLで異なるレスポンスをパラメータとして設定したい
ということで考えた結果、Postmanから初期化を行うことにしました。
Postman、便利です。テスト実行によく利用します。
ということで、Postmanで以下のように設定しました。
POST、initializeのURL
リクエストBodyに、全イベントのパラメータを設定(重複は削除)。

設定したパラメータはこんな感じ。
{
"destination": "xxxxxxxxxx",
"events": [
{
"type": "message",
"message": {
"type": "text",
"id": "14353798921116",
"quoteToken": "q3Plxr4AgKd...",
"text": "Hello, world",
"duration": 60000,
"contentProvider": {
"type": "line",
"originalContentUrl": "",
"previewImageUrl": ""
},
"imageSet": {
"id": "E005D41A7288F41B65593ED38FF6E9834B046AB36A37921A56BC236F13A91855",
"index": 1,
"total": 2
},
"emojis": [
{
"index": 29,
"length": 6,
"productId": "5ac1bfd5040ab15980c9b435",
"emojiId": "001"
}
],
"mention": {
"mentionees": [
{
"index": 5,
"length": 8,
"userId": "U49585cd0d5...",
"type": "user",
"isSelf": false,
"quotedMessageId": ""
}
]
}
},
"timestamp": 1625665242211,
"source": {
"type": "user",
"groupId": "Ca56f94637c...",
"roomId": "Ra8dbf4673c...",
"userId": "U80696558e1aa831..."
},
"replyToken": "757913772c4646b784d4b7ce46d12671",
"mode": "active",
"webhookEventId": "01FZ74A0TDDPYRVKNK77XKC3ZR",
"deliveryContext": {
"isRedelivery": false
},
"follow": {
"isUnblocked": false
},
"postback": {
"data": "storeId=12345",
"params": {
"datetime": "2017-12-25T01:00",
"newRichMenuAliasId": "richmenu-alias-b",
"status": "SUCCESS"
}
}
}
]
}
上記を実行すると、API Workflow Request dataに全てのパラメータが認識されます。

この初期化の仕方だと、以下の画像のようにパラメータを引用できるようになります。
なお、実際には値が入っていなくても必須チェックには引っかからないです。

ひとつのURLに送信されるパラメータが異なる時!
ということで、1つのURLに送信されるパラメータが異なる場合、実際にWebhookを送信してBubbleのDetect Dataで初期化するのではなく、Postman等から全パラメータを含むJSONを設定して初期化する とその後のステップでパラメータを引用できるようになるハックでした!