#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をコールすることで問題を回避してみた。
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