はじめに
最近、LINE Bot で何か作れないか考えては、Echo ボットから先に進まない毎日です。
で、Echo ボットながらも、あーでもない、こーでもない、といろいろやっていると、
- イベントタイプやステートの振り分けで、ネストが深くなりがちなる
- Webhook に対するレスポンスは早めに返した方がいい
-> ボットとしての処理は、別のイベントループで実施する
とか思った次第1。
作った
それで作ったのがこれ。
インストール
いつもの npm install
2。
npm install node-linebot-message-handler --save
前準備
使い方ですが、まずは、new で作ったインスタンスに、on メソッドで各イベントタイプごとの処理を追加します。
const msgHandler = new LINEBotMessageHandler(config as Types.ClientConfig); msgHandler // `text` のメッセージを受け取ると、`text` イベントが飛ぶ。 // 'location' や 'sticker' (スタンプ) も同様。 .on('text', async (context:MessageContext) => { // MessageContext#getEvent() returns Message event object, so you can get message through MessageEvent#message // https://developers.line.biz/en/reference/messaging-api/#message-event const textEventMessage : TextEventMessage = context.getEvent().message as TextEventMessage; const eventSource : Types.EventSource = context.getEvent().source; // replyToken を気にせず、返事が送れる。 // 例えば、エコーだけならこれ await context.replyMessage([{ type: 'text', text: textEventMessage.text }]); // pushMessage も `to` を気にせず送れる await context.pushMessage([{ type: 'text', text: textEventMessage.text }]); if (!eventSource.userId) return; // オリジナルの API にアクセスしたければ、getClient から。 await context.getClient().pushMessage(eventSource.userId, [{ type: 'text', text: textEventMessage.text }]); }) // 'location' や 'sticker' (スタンプ) も同様。 .on('location', async (context:MessageContext) => { // : }) .on('sticker', async (context:MessageContext) => { // : }) // `image` のメッセージを受け取ると、`image` イベントが、データ情報とともに飛ぶ。 .on('image', async (context:MessageContext, data:RecievedData ) => { // contentType から拡張子を作って、WriteStream を生成 const dest = fs.createWriteStream(`dest.${data.contentType ? data.contentType.replace(/[^/]+\//, '') : 'dat'}`); // ストリームをそのまま保存 data.stream.pipe(dest); }) // 'video', 'audio' や 'file' も同様。 .on('video', async (context:MessageContext, data:RecievedData ) => { // : }) .on('audio', async (context:MessageContext, data:RecievedData ) => { // : }) .on('file', async (context:MessageContext, data:RecievedData ) => { // : }) // 署名検証でこけたら `invalid` が飛ぶ .on('invalid', async (data ) => { // invalid signature or request body. console.error('invalid'); });
利用時
Webhook 受信時には、リクエスト ボディをセットするだけで、前準備で設定したイベントに応じた処理が実行される、という単純なものです。
// Webhook で受信したリクエスト ボディを渡すと、上のイベントが発火する msgHandler.setRecievedMessage(requestBody.toString(), signature /* リクエスト中の x-line-signature ヘッダーから */);
LINE Bot を作った経験がある人に試してもらって、使い勝手について感想をいただきたいところです。