【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つが最小構成となります。
http in
ノード
1-a. 設定
必ず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
に入っています。
ReplyMessage
ノード
1-b. 設定
チャネルシークレットとチャネルアクセストークンは必須です。
ReplyMessage欄は基本空欄です。常に固定メッセージを送りたい場合のみ入力してください。
入力すべき msg.payload
の中身
以下の内容の msg.payload
が必要です。(テキスト送信の場合)
{
"events": [
{
"type": "message",
"message": {
"type": "text",
"text": "ここにいれたメッセージがユーザーに送られます"
},
"replyToken": "(http inで受け取ったリプライトークン文字列・必須)",
}
]
}
2. ユーザーメッセージをテンプレートに含めて返信
http in
ノード および ReplyMessage
ノードは 1.基本形 と同じです。
template
ノード
2-a. 設定
- 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
に再設定(もししなければユーザーが送った文字列のまま)しています。
function 1
ノード
3-a. // LINEサーバーからの情報をmsg.lineに退避させる
msg.line = msg.payload;
// msg.payloadに送信されたメッセージ本体を入れる
msg.payload = msg.payload.events[0].message.text;
return msg;
文字列加工
ノード
3-b. 図では function
ノードを使っていますが、入力、出力ともに msg.payload
を使うもの(ほぼ全てでデフォルトですが)であればどんなノードでもかまいません。また、複数のノードの集合でもよいです。
function 2
ノード
3-c. // 送信したい文字列をresultに退避させておく
const result = msg.payload;
// LINEサーバーからの内容をpayloadに復元する
msg.payload = msg.line;
// 返信メッセージをhttp requestの結果にする
msg.payload.events[0].message.text = result;
return msg;
http request
でAPIリクエスト結果を返信(APIパラメータなし)
4. 「3. ユーザーメッセージを加工して返信」をベースに、中央の文字列加工をするノードを http request
ノードに変更しているだけです。
http request
ノード
4-a. 設定
Returnの形式がUTF-8文字列とバイナリバッファの場合は、その内容がそのまま msg.payload
に入ります。が、 文字列で複数のデータを得るAPIであればほとんどJSONオブジェクトです。この場合、まずこのノードの出力を debug
ノードにつないで、その中身がどうなっているか確認しましょう。
function 2
ノード
4-b. 設定(出力が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;
http request
でAPIリクエスト結果を返信(GETメソッド・APIパラメータあり)
5. 基本構成は「4. http request
でAPIリクエスト結果を返信(APIパラメータなし)」と同じですが、function 1
ノードを書き換えてLINEからの文字列の一部がAPIのURL内に反映されるようにする必要があります。
http request
ノード
5-a. 例: 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で送った日付文字列をそのまま検索パラメータとして設定できるようにしてみます。
設定
function 1
ノード
5-b. // 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;
http request
でAPIリクエスト結果を返信(POSTメソッド・APIパラメータあり)
6. ※編集中
Discussion