アルパカログ

Webエンジニア兼マネージャーがプログラミングやマネジメント、読んだ本のまとめを中心に書いてます。

GCP Cloud Functions(GCF)を使ってサーバーレスでLINE Botを作る方法

f:id:otoyo0122:20200919153735p:plain:w300

GCPのCloud Functions(GCF)を使えば、サーバーレスでLINE Botを作ることができます。しかも無料です。

このエントリでは、GCFを使ってサーバーレスでLINE Botを作る方法を紹介します。

システム構成

システムはいたってシンプルで、下図のようにLINE Messaging APIからのHTTPリクエスト(webhook)をGCFで受けてreplyするだけです。

f:id:otoyo0122:20180127144353p:plain:w600

サーバーレスと言えばAWS Lambdaもありますが、GCFの良いところは、HTTPリクエストを受けるためのエンドポイントも一緒に付いてくる点です。

Lambdaで同じことをやるにはAPI Gatewayを前に置いてあげる必要があります。

LambdaもGCFも個人利用レベルでは無料になると思いますが、API Gatewayは有料です。*1

動かしてみよう

サンプルコードをデプロイして実際に動かしてみましょう。

1. 前準備

前準備として下記の手順を済ませてください。

  1. GCF の HTTP Tutorialを済ませる
  2. LINE Messaging APIを開始しクイックスタートを済ませる

2. Config 配置

下記のサンプルコードを任意のディレクトリにcloneします。

サンプルコードのconfigディレクトリにdefault.jsonを作成し、下記のようにLINE Messaging APIのChannel Secretとアクセストークンを記載します。

config/default.json

{
  "channelAccessToken": "xxxx",
  "channelSecret": "xxxx"
}

Channel SecretとアクセストークンはLINE Developers の Consoleからチャネル(Bot) を選んだ先のページに記載されています。

もしまだ発行されていなければ発行しましょう。

3. デプロイ

index.jsと同じディレクトリで下記デプロイコマンドを実行します。

$ gcloud beta functions deploy webhook --trigger-http --source .

数十秒ほどでデプロイが完了しhttpsTrigger URLが表示されます(下図赤枠)。

f:id:otoyo0122:20180127155715p:plain:w500

このURLをLINE 側コンソールの「Webhook URL」に設定し接続確認します。

f:id:otoyo0122:20180127160042p:plain:w600

✅ 成功しました。と表示されれば完了です。

4. 動作確認

BotをLINEアプリで友達追加し「ホイちゃん」と話しかけると反応します。

f:id:otoyo0122:20180128095222p:plain:w400

リアクションさせたいキーワードはindex.js内の下記箇所で指定しています。

GCFの注意点

今回作成したコードは「LINE Bot SDK / Node.js」) のecho-botサンプルがベースになっています。

今回作成したプログラムをGCFで動かす際に、注意すべき点が2つあります。

  • GCF のリクエストハンドラで受け取るRequest Body(JSON)はパース済みであること
  • そのため署名を検証するためのメソッドを自分で呼ばなければならないこと

LINE Messaging APIでは、リクエストがLINEプラットフォームから送信されたことを確認する必要があります。署名の検証です。

echo-botサンプルではExpressが使われており、署名はリクエストハンドラの最初のチェインmiddleware()内で検証されています。

app.post('/callback', line.middleware(config), (req, res) => {

middleware()内で呼ばれる検証メソッドvalidateSignature()には生のRequest Bodyを渡す必要があります。

if (!validateSignature(body, secret, signature)) {

GCF ではreq.bodyは既にパース済みのため、req.rawBodyを引数にして直接validateSignature()を呼び出さなければなりません。

今回のサンプルプログラムでもそのようにしています。

if (!line.validateSignature(req.rawBody, config.channelSecret, signature)) {

以上です。

このエントリでは、GCFを使ってサーバーレスでLINE Botを作る方法を紹介しました。

参考になった方は、ぜひ「はてブ」やSNSでシェアしていただけると嬉しいです。

参考リンク

*1:とはいえ必ずご自身でご確認ください。 GCF 料金 / Lambda 料金