【LINE Bot開発】チートシート for Node-RED × LINE Messaging API
前提
環境
- この記事はNode-RED上でLINE Bot開発をするときの様々なパターンを解説する記事です。
- LINE Messaging APIとの接続は次のノードを別途インストールして使う前提で書いています。
設定
- あらかじめLINE公式アカウントが作成済みであること
- Botにする対象のLINE公式アカウントと友達になっていること
- Botモードが有効であること(LINE公式アカウントマネージャー > 応答設定)
- Webhookが有効であること(LINE公式アカウントマネージャー > 応答設定)
- チャネルシークレットを取得済みであること(LINE Developers > チャネル基本設定)
- チャネルアクセストークンの発行・取得済みであること(LINE Developers > Messaging API設定)
- Webhook URLは「(自分のNode-REDホストのURL) /webhook」という形式で設定済みであること((LINE Developers > Messaging API設定))
友達全員に送りたいとき

※編集中
特定のユーザー(自分だけ)に送りたいとき

※編集中
ユーザーからのメッセージに返信したいとき
1. 基本形(オウム返し)

http in ノードと ReplyMessage ノードの2つが最小構成となります。
1-a. http in ノード
設定

必ずPOST形式で受け付けるようにしてください。
出力される msg.payload の中身
ユーザーからメッセージを受信したときに動作し、以下の msg.payload を出力します。
この内容はLINE Messaging APIの「Webhookイベントオブジェクト」に準拠するものです。
{
"destination": "U70dc61fe94897194712970606c1230cc",
"events": [
{
"type": "message",
"message": {
"type": "text",
"id": "14487099500750",
"text": "これはユーザーからのメッセージです"
},
"timestamp": 1627671638403,
"source": {
"type": "user",
"userId": "Uc5c5892088deb5c1a7b04fc24b7022ed"
},
"replyToken": "0c9fa91c72ad4e25a15584ba41410f82",
"mode": "active"
}
]
}
ユーザーからのメッセージを取り出すには?
msg.payload.events[0].message.text に入っています。
1-b. ReplyMessage ノード
設定

チャネルシークレットとチャネルアクセストークンは必須です。
ReplyMessage欄は基本空欄です。常に固定メッセージを送りたい場合のみ入力してください。
入力すべき msg.payload の中身
以下の内容の msg.payload が必要です。(テキスト送信の場合)
{
"events": [
{
"type": "message",
"message": {
"type": "text",
"text": "ここにいれたメッセージがユーザーに送られます"
},
"replyToken": "(http inで受け取ったリプライトークン文字列・必須)",
}
]
}
2. ユーザーメッセージをテンプレートに含めて返信

http in ノード および ReplyMessage ノードは 1.基本形 と同じです。
2-a. template ノード
設定

- Property(結果をセットする位置)は msg.payload.events[0].message.text にします。
- テンプレート内でユーザーから送信された文字列を表示するには {{ msg.payload.events.0.message.text }} を用います。
3. ユーザーメッセージを加工して返信

先頭の http in ノード および末尾の ReplyMessage ノードは「1.基本形」と同じです。
http in ノードから出力される msg.payload の内部には、LINEで最終的に「返信」の動作を行う際に必須となる情報(どのメッセージに返信するのかを示すIDなど)が含まれるため、最終の ReplyMessage ノードまで情報を保持する必要があります。したがって、次のような仕組みでLINE情報の保持と通常のpayload利用を両立させています。
-
function 1ノード内でその必須となる情報をmsg.lineに退避させます。 - 中間のノードで自由に文字列加工等を行います。複数のノードでも問題ありません。
-
function 2ノード内でmsg.lineに退避させておいた情報をmsg.payloadに復元したうえで、返信したいメッセージをmsg.payload.events[0].message.textに再設定(もししなければユーザーが送った文字列のまま)しています。
3-a. function 1 ノード
// LINEサーバーからの情報をmsg.lineに退避させる
msg.line = msg.payload;
// msg.payloadに送信されたメッセージ本体を入れる
msg.payload = msg.payload.events[0].message.text;
return msg;
3-b. 文字列加工 ノード
図では function ノードを使っていますが、入力、出力ともに msg.payload を使うもの(ほぼ全てでデフォルトですが)であればどんなノードでもかまいません。また、複数のノードの集合でもよいです。
3-c. function 2 ノード
// 送信したい文字列をresultに退避させておく
const result = msg.payload;
// LINEサーバーからの内容をpayloadに復元する
msg.payload = msg.line;
// 返信メッセージをhttp requestの結果にする
msg.payload.events[0].message.text = result;
return msg;
4. http request でAPIリクエスト結果を返信(APIパラメータなし)

「3. ユーザーメッセージを加工して返信」をベースに、中央の文字列加工をするノードを http request ノードに変更しているだけです。
4-a. http request ノード
設定

Returnの形式がUTF-8文字列とバイナリバッファの場合は、その内容がそのまま msg.payload に入ります。が、 文字列で複数のデータを得るAPIであればほとんどJSONオブジェクトです。この場合、まずこのノードの出力を debug ノードにつないで、その中身がどうなっているか確認しましょう。
4-b. function 2 ノード
設定(出力がJSONオブジェクトのときのみ)
まず http request ノードの直後に debug ノードを接続し、中身を確認しながら欲しいデータを探してみましょう。
例: Jikan API より
https://api.jikan.moe/v3/search/anime?q=jutsu&limit=10 へのリクエスト:

アニメタイトルを示す "Jujutsu Kaisen (TV)" という文字列が欲しい場合……
→「3-c. function 2 ノード」で示したソースコード2行目を以下のように変更したものを設定:
const result = msg.payload.results[7].title;
5. http request でAPIリクエスト結果を返信(GETメソッド・APIパラメータあり)
基本構成は「4. http request でAPIリクエスト結果を返信(APIパラメータなし)」と同じですが、function 1 ノードを書き換えてLINEからの文字列の一部がAPIのURL内に反映されるようにする必要があります。
5-a. http request ノード
例: Sunset and sunrise times API を使って
「2021年7月26日の、緯度35.70113度・経度139.76885度」を得たいとき……
→ アクセスすべきURLは以下の通りとなる:
https://api.sunrise-sunset.org/json?lat=35.70113&lng=139.76885&date=2021-07-26
このURLのうち ?lat=35.70113&lng=139.76885&date=2021-07-26 部分を、このノードの1つ手前である function 1 ノードから設定できるようにし、特に LINEで送った日付文字列をそのまま検索パラメータとして設定できるようにしてみます。
設定

5-b. function 1 ノード
// LINEサーバーからの情報をmsg.lineに退避させる
msg.line = msg.payload;
// msg.payload.dateに送信されたメッセージ本体(2021-07-26のような日付の形式を想定)を入れる
msg.payload.date = msg.payload.events[0].message.text;
// 緯度経度は固定値としてここで設定する
msg.payload.lat = 35.70113;
msg.payload.lng = 139.76885;
return msg;
6. http request でAPIリクエスト結果を返信(POSTメソッド・APIパラメータあり)
※編集中
Discussion