LINE Bot を Firebase Cloud Functions を使って実装してみてハマったこと
はじめに
年末に友達と何か簡単なものを作ってみようという話になり、LINE BOT を作ってみました。
実装自体は本当に簡単で Qiita 等にもやり方が詳しく載っていたので、ほとんどその通りやれば実装自体はスムーズに行うことができました。
ただ、ちょいちょいハマったポイントがあったので紹介します。
ちなみにコードは全て TypeScript で記述しています。
秘匿情報の扱いについて
LINE Bot を利用するためにチャンネルシークレットとチャンネルアクセストークンの2つのトークンを用意する必要があります。
これらをそのままソースコードで管理するのはまずいので、最初は dotenv を使用してそれらを gitignore に設定することで管理しようと思っていました。
しかし、デプロイしても .env ファイルに記述した情報は undefined になってしまい取得することができませんでした。
少し調べてみると、公式で環境変数をデプロイの際に組み込むコマンドがあったので、そちらを利用するようにしました。
このコマンドで環境変数をセットし、無事コードから読み込むことができました。
// 以下のコマンドで環境変数をセット
// firebase functions:config:set someservice.key="THE API KEY" someservice.id="THE CLIENT ID"
// JS のオブジェクトになるので以下のようにアクセスすることができる
functions.config().someservice.id
Flex Message の送信について
LINE Bot には通常のテキストのみのメッセージ以外にも Flex Message と言うレイアウトを自由にカスタマイズできるメッセージが送信できます。
Flex Message を利用する際は公式の Flex Message Simulator を利用してレイアウトを組み、結果の JSON をソースコードで利用するという形になると思います。
await client.replyMessage(events.replyToken, { type: "flex", altText: "Flex Message", contents: /* ここに Flex Message の内容を入れる */ });
しかし Node.js 用の LINE Bot SDK では JSON をそのまま使うことができませんでした。きちんとオブジェクトに直してから replyMessage メソッドの引数に渡してあげる必要がありました。
const flexMessage: FlexMessage = {
type: "flex",
altText: `Flex Message が送信されました`,
contents: {
type: "bubble",
body: {
type: "box",
layout: "vertical",
contents: [
// 省略 ...
]
},
},
};
await client.replyMessage(events.replyToken, flexMessage);
レスポンスが遅い
Functions に必要な処理を記述し、無事デプロイが完了してメッセージを送ると返答があることが確認できましたが、異様にレスポンスが遅くなる現象に遭遇しました。
こちらからテキストのメッセージを送ると返ってこない時もあったり、3通ほど送るとようやく返ってくるようになったりと動作が不安定でした。
ただ、誰かが一度メッセージを送っているとすぐにレスポンスが返ってきていたので、Functions のインスタンスの立ち上げや初期化に時間がかかっているのかと思っていました。
とは言え流石に遅すぎるのでもう一度コードを見直してみました。当初は公開されている記事等を参考にして Express を使用して API を Functions にデプロイするようにしていました。
const app = express();
app.post('/', line.middleware(config), (req, res, next) => {
// 省略 ...
});
export const lineBot = functions.region('asia-northeast1').https.onRequest(app);
Webhook 経由で POST リクエストが送られてくるだけだし、Express はオーバーなのでは?ということで Express を無くして、Functions の onRequest をトリガーにするようにしてみるとレスポンスの速度が改善されました。
export const lineBot = functions.region('asia-northeast1').https.onRequest(async (request, response) => {
// 省略 ...
});
はっきりとした原因は分かりませんでしたが、Express の初期化の処理等に時間がかかっていたのかもしれないです。
さいごに
LINE Bot が応答してくれるまでは簡単に実装できましたが、ちょっとしたハマるポイントがありました。
ただ、LINE Bot の実装自体は本当に簡単で、Firebase を使ってしまえばさくっと無料で動くものが作れるのでオススメです👍
参考
・LINE MessagingAPIで遊ぶ①動かしてみる [Qiita]
・超絶簡単!LINE bot開発 [Qiita]