マイコン温度通知システムの製作8 超過温度のLINE通知1

前回からの続きです。

つまづいた所など

WebhookURLの役割について

WebhookURLの役割についてよく理解しておらず、設定をすべきなのか省略していいいのか、右往左往していました。

コードを作成しそれをデプロイし、そのときにできたURLをWebhookURLとして使うため、LINE APIを使ったアプリケーションそのものがそのデプロイするコード(URL)になります。

そのためデプロイ(WebhookURL)は必須のものでした。

LINE APIの仕様について

LINE公式アカウントから友達になっているユーザーに、(温度超過の)メッセージを送信する際、相手ユーザーのID(LINEで確認できるものとは違うもの)が必要なのですが、LINEのAPIでは能動的にIDを取得できない仕様になっていました。

具体的には、ユーザーがLINE公式アカウントを友達登録したときや、ユーザーがLINE公式アカウントにメッセージを送ったときにユーザーのIDを取得が可能で、いきなりLINE公式アカウントの友達すべてのIDを取得するなどはできない、となっていました。

ユーザーIDの管理

ユーザーIDを取得して管理するために、Firestoreのデータベースに新しくコレクションを追加しました。

環境変数の設定

Firebaseの環境設定機能を利用して、アクセストークンとシークレットキーを設定し、コードに記述しなくて済むようにしました。

firebase functions:config:set line.channel_access_token="YOUR_CHANNEL_ACCESS_TOKEN" line.channel_secret="YOUR_CHANNEL_SECRET"

しかしエミュレータで環境変数を呼び出そうとするとエラーが出ていました。

$ firebase emulators:start
i  emulators: Starting emulators: functions, firestore, database, hosting, extensions
⚠  functions: The following emulators are not running, calls to these services from the Functions emulator will affect production: auth, pubsub, storage
i  firestore: Firestore Emulator logging to firestore-debug.log
✔  firestore: Firestore Emulator UI websocket is running on 9150.
⚠  database: Did not find a Realtime Database rules file specified in a firebase.json config file. The emulator will default to allowing all reads and writes. Learn more about this option: https://firebase.google.com/docs/emulator-suite/install_and_configure#security_rules_configuration.
i  database: Database Emulator logging to database-debug.log
i  hosting[temperature-measurement-b3fcd]: Serving hosting files from: public
✔  hosting[temperature-measurement-b3fcd]: Local server: http://127.0.0.1:8000
i  ui: Emulator UI logging to ui-debug.log
i  functions: Watching "/Users/user/firebase/functions" for Cloud Functions...
✔  functions: Using node@18 from host.
Serving at port 8224

TypeError: Cannot read properties of undefined (reading 'channel_access_token')
    at Object.<anonymous> (/Users/user/firebase/functions/lineMessageFunctions.js:13:48)
    at Module._compile (node:internal/modules/cjs/loader:1159:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1213:10)
    at Module.load (node:internal/modules/cjs/loader:1037:32)
    at Module._load (node:internal/modules/cjs/loader:878:12)
    at Module.require (node:internal/modules/cjs/loader:1061:19)
    at require (node:internal/modules/cjs/helpers:103:18)
    at Object.<anonymous> (/Users/user/firebase/functions/index.js:3:30)
    at Module._compile (node:internal/modules/cjs/loader:1159:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1213:10)

⬢  functions: Failed to load function definition from source: FirebaseError: Functions codebase could not be analyzed successfully. It may have a syntax or runtime error

以下の記述の.runtimeconfig.jsonファイルを作成したのですが、functions直下でなくfirebaseのディレクトリ配下だったのでエラーが出ていました。

・.runtimeconfig.json

{
  "line": {
    "channel_access_token": "xxx",
    "channel_secret": "xxx"
  }
}

functions直下にしたところ上記のエラーは無くなりました。

Firebase FunctionsのバージョンでCloud Run URLが異なる

Cloud Run URLはFunctionsのバージョンにより形式が異なっています。

以下のコード記述だと、「https://xxx.a.run.app(Firebase Functionsバージョン2)」になります。

const {onRequest} = require("firebase-functions/v2/https");

以下のコード記述だと、「https://us-central1-xxx.cloudfunctions.net/xxx(Firebase Functionsバージョン1)」になります。

const functions = require("firebase-functions");

Firebaseで「関数をデプロイできませんでした」と表示される

ローカルに必要な依存関係がインストールされておらず、またfunctions配下のpackage.jsonファイルに記載がないことが原因でした。

ターミナルでfunctions配下に移動し、以下のコマンドを実行してインストールとfunctions配下のpackage.jsonファイルへの記述をしたところ解消されました。

npm install express body-parser --save

LINEからの応答で200以外を返してしまう、Firebaseにログが残らない

Firebaseにデプロイし、Cloud Run URLをLINEのWebhookURLに設定、「検証」を押下で以下のようなエラーが出ました。

エラー
ボットサーバーから200以外のHTTPステータスコードが返されました。(403 Forbidden)

LINEプラットフォームから送信されたHTTP POSTリクエストに対してボットサーバーがステータスコード200を返すことを確認してください。詳しくは、Messaging APIリファレンスのレスポンスを参照してください。

これについてFirebaseのログが残っていないので不思議に思い調べたのですが、そもそもログはFirebase SDKを使用して記録されるもので、そのためLINE Developersからの検証などではログは残らないということでした。

Firebaseのエミュレータを使って素早く処理する

直接関係ありませんが、エラーの都度コードを修正してデプロイすることを繰り返すと時間がかかるのでエミュレータを使うことにしました。

$ firebase emulators:start
...
Functions │ 127.0.0.1:5001 │ http://127.0.0.1:4000/functions

動作しているエミュレータをインターネット上で公開するため、ngrokというトンネリングツールを使います。

末尾にはエミュレータ起動時に表示されるfunctionのlocalhostの番号を入力します。

上記ならば、5001になります。

$ ngrok http 5001
...
Forwarding https://xxx.app -> http://localhost:5001 

LINE Developersに設定するときは上記のURLとCloud Run URLを合わせます。

Cloud Run URLが、
firebaseapp-xxx/linemessage/webhook
なら、
https://xxx.app/firebaseapp-xxx/linemessage/webhook
になります。

これをLINE Developersに設定します。

LINE公式アカウントが即時退会し、グループID取得プログラムが動作しない

作ったLINE公式アカウントをグループに招待し、そこでメッセージを送らせようとしました。

しかしグループに招待すると即時退会し、LINEのグループIDが取得できませんでした。

LINE Developersの管理画面からグループの参加を許可したところ、意図するグループID取得ができました。

LINE公式アカウントの自動応答メッセージなどを変更する

LINE公式アカウントの友達登録やメッセージ送信で自動応答メッセージが出てきます。

それらをデフォルトから変更します。

LINE Developersのチャネル基本設定から、「LINE Official Account Manager」のリンクをクリックします。

以下から、応答メッセージの設定ができます。

 

タイトルとURLをコピーしました