LoginSignup
9
6

More than 5 years have passed since last update.

Filebase FunctionでLineBotを作ろう(失敗)

Last updated at Posted at 2017-12-26

Filebase FunctionでLineBotを作ろうとした失敗メモ

Firebase FunctionのHttpトリガーを使ってLineBotを作ろうとしたが、
課金しなければLineAPI(Google外のサービス)をコールできなかったので途中までの経過をメモする。
(2017/12/27編集)
有効な請求先アカウント(クレジットカード等の登録)がなければLineAPI(Google外のサービス)をコールできなかったため途中までの経過をメモする。

有効な請求先アカウント(クレジットカード等の登録)があれば従量課金プランの無料枠で動くはず。

キーワード
linebot Firebase FirebaseCloudFunctions

FirebaseFunctionでコーディング

LINE SDKとFirebaseFunctionのチュートリアルのコピペだが、
LINE SDKのmiddlewareにリクエストのrawBodyを渡さなければLINE SDKでエラーが発生したので、暫定で修正。
LINE SDKのmiddlewareはBODYにストリームか文字列が設定されていることを期待しているが、Firebase側で自動的にBodyParseを行っているためBODYがJSONオブジェクトとなっている。
そのため、以下のタイプエラーが発生していた。

TypeError: Data must be a string or a buffer at TypeError (native) at Hmac.update

なんでかFirebaseFunctionの日本語ページ にはrawBodyの記述がなかったので躓いた。英語ページ には載ってる。

かなり無理やりだが、元のrawBodyを設定したJSONオブジェクトを作成してmiddlewareをコールすることで問題を回避してみた。

index.js
const functions = require('firebase-functions');
const express = require('express');
const line = require('@line/bot-sdk');

// create LINE SDK config from env variables
const config = {
  channelAccessToken: '***',
  channelSecret: '***'
};

// create Express app
const app = express();

// create LINE SDK client
const client = new line.Client(config);


let middle = line.middleware(config);

// register a webhook handler
app.post('/handler', (req, res) => {
  console.log("handler");
  // middlewareにはrawBodyと署名を渡す。
  middle({body:req.rawBody,headers:{"x-line-signature":req.headers["x-line-signature"]}},res,()=>{
     console.log("next");
  });
  Promise
    .all(req.body.events.map(handleEvent))
    .then((result) => {
      res.end()
  });
});

// event handler
function handleEvent(event) {
    console.log(event);
  if (event.type !== 'message' || event.message.type !== 'text') {
    // ignore non-text-message event
    return Promise.resolve(null);
  }

  // create a echoing text message
  const echo = { type: 'text', text: event.message.text };

  // use reply API
  return client.replyMessage(event.replyToken, echo);
}


// Expose Express API as a single Cloud Function:
exports.widgets = functions.https.onRequest(app);

発生するエラー

LineAPIをコールしようとして以下のエラーが発生する。
有効な請求先アカウント(クレジットカード等の登録)がなければLineAPI(Google外のサービス)を呼べないらしいのであきらめた。

Error: getaddrinfo ENOTFOUND api.line.me api.line.me:443 at RequestError
9
6
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6