LINEbotのwebhookをfirebaseで行う

LINEbotのwebhookをfirebaseで行う

LINE botのWebhookをFirebaseで行うためには、
Firebase Cloud Functionsを使ってWebhookをセットアップする

コスト面から考えると
firebaseでpython を使いwebhookにするには
Cloud Run のコストも必要らしい

このためpython から javascriptに変更する

1
rm -rf functions

で削除する

functionsディレクトリがない状態で、Firebase FunctionsをJavaScriptで再初期化

1
firebase init functions

を実行

1
❯ Initialize

を選択

今回は

1
2
3
Functions can be deployed with firebase deploy.
 
? What should be the name of this codebase?

となったので調べる

GPTによれば

これはFirebase CLIの新しいバージョンで追加された**コードベース(codebase)**に関する設定です。
以下で詳しく説明し、どのように対応すればよいかご案内します。

## **コードベース(Codebase)とは**

**コードベース**は、Firebase Functionsの新しい機能で、
**同じFirebaseプロジェクト内で複数の関数セットを管理するためのもの**です。
これにより、異なるディレクトリや異なる言語で書かれた関数を、
同じプロジェクト内で個別にデプロイできます。

## **このプロンプトが表示される理由**

`firebase init functions`を実行した際、
または`firebase deploy`を初めて行う際に、CLIがコードベースの名前を尋ねてきます。

特に理由がなければ、デフォルトの名前を使用して問題ありません。
プロジェクトに適した名前を指定することもできます。

### **コードベースを使用するメリット**

– **複数の関数セットを管理**:異なるチームや機能ごとに関数を分離できます。
– **異なる言語のサポート**:同じプロジェクト内で、JavaScriptとTypeScript、
あるいは他の言語の関数を同時に使用できます。

### **コードベースの命名規則**

– **ユニークな名前**:各コードベースはプロジェクト内でユニークな名前を持つ必要があります。
– **わかりやすい名前**:コードベースの内容を反映した名前を付けると、管理が容易になります。

## **まとめ**

– **プロンプトに対して名前を指定**:`default`や`app`などの名前を入力します。
– **`firebase.json`を確認**:コードベースの設定が追加されていることを確認します。
– **デプロイを再試行**:`firebase deploy –only functions`でデプロイします。

とのこと

とりあえず

1
Default

にするが

1
2
functions.codebase must be unique but 'default' was used more than once.
? What should be the name of this codebase?

となるので

というように defaultから 別の名前に変更した

1
2
3
4
? What language would you like to use to write Cloud Functions?
❯ JavaScript
  TypeScript
  Python


javascriptを選択

1
? Do you want to use ESLint to catch probable bugs and enforce style? (y/N)

となる

GPTによれば

## **プロンプトの意味**

– **ESLint**は、JavaScriptのコード品質を向上させるための**静的コード解析ツール**です。
– **コードのバグやスタイルの問題を検出**し、一貫したコーディングスタイルを維持するのに役立ちます。

## **選択肢**

1. **`y` を入力して ESLint を有効にする**

– **メリット**:
– コードの潜在的なバグを早期に発見できます。
– チーム開発の場合、一貫したコーディングスタイルを維持できます。
– デプロイ前にコードの品質をチェックできます。
– **設定**:
– プロジェクトに`.eslintrc.js`という設定ファイルが追加されます。
– デフォルトのルールセットが適用されますが、必要に応じてカスタマイズ可能です。

2. **`n` を入力して ESLint を無効にする**

– **メリット**:
– 初期設定がシンプルになり、すぐに開発を開始できます。
– ESLintによる警告やエラーを気にせずにコーディングできます。
– **デメリット**:
– コードのバグやスタイルの問題を見逃す可能性があります。

## **おすすめの選択**

– **初心者や個人開発の場合**:
– **`y` を選択することをおすすめします**。ESLintは学習曲線がありますが、コード品質の向上に大いに役立ちます。
– **小規模なプロトタイプや試験的なプロジェクトの場合**:
– **`n` を選択しても問題ありません**。後から必要に応じてESLintを導入できます。

– **ESLintの後からの導入**:
– 後でESLintを導入したい場合は、`npm install eslint –save-dev`でインストールし、設定ファイルを追加することで対応できます。
– **TypeScriptを使用する場合**:
– TypeScriptを選択した場合も同様にESLintを使用できます。

とのことなので
今回は n にする

1
? Do you want to install dependencies with npm now? (Y/n)

となるので
Y
で依存関係のインストール

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
npm warn EBADENGINE Unsupported engine {
npm warn EBADENGINE   package: undefined,
npm warn EBADENGINE   required: { node: '18' },
npm warn EBADENGINE   current: { node: 'v20.17.0', npm: '10.8.2' }
npm warn EBADENGINE }
npm warn deprecated inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
npm warn deprecated glob@7.2.3: Glob versions prior to v9 are no longer supported
 
added 491 packages, and audited 492 packages in 39s
 
51 packages are looking for funding
  run `npm fund` for details
 
found 0 vulnerabilities
npm notice
npm notice New patch version of npm available! 10.8.2 -> 10.8.3
npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.8.3
npm notice To update run: npm install -g npm@10.8.3
npm notice
 
i  Writing configuration info to firebase.json...
i  Writing project information to .firebaserc...
 
<img draggable="false" class="emoji" alt="✔" src="https://s.w.org/images/core/emoji/11/svg/2714.svg">  Firebase initialization complete!

となる

次に追加パッケージのインストール
LINE Bot SDKやExpressを使用する場合、
プロジェクトディレクトリに移動して以下のコマンドを実行

1
npm install @line/bot-sdk express

実行結果は

1
2
3
4
5
6
7
8
9
10
11
12
npm warn EBADENGINE Unsupported engine {
npm warn EBADENGINE   package: undefined,
npm warn EBADENGINE   required: { node: '18' },
npm warn EBADENGINE   current: { node: 'v20.17.0', npm: '10.8.2' }
npm warn EBADENGINE }
 
added 7 packages, and audited 499 packages in 3s
 
52 packages are looking for funding
  run `npm fund` for details
 
found 0 vulnerabilities

ログを元に調べたら

– **原因:**
– あなたのシステムでは Node.js バージョン 20.17.0 を使用していますが、パッケージはバージョン 18 を要求しています。
– このバージョンの不一致が警告を引き起こしています。

– 警告はバージョンの不一致を知らせていますが、致命的な問題ではありません。
– パッケージが正常に動作するか確認し、必要に応じて Node.js のバージョンを調整してくだい
とのこと

動くのか調べてみたいので

Node.jsとLINE Bot SDKで作るLINE Bot開発チュートリアル
とかみたけど
使用バージョンとかは載っていない

Expressで作ったLINE BotをVercelでデプロイする方法

LINE BotへのメッセージをGoogle Homeに喋らせてみる
あたりもこのバージョンについては書かれていない

LINE ボットを簡単な構成で作ってみた(TypeScript + Bot SDK ver.8 + Lambda)

2023年10月15日の記事で
前提条件
* LINE公式アカウントを作成していること(無料枠でテスト可能)
* Node.js ver.18の環境を準備済

とあるので、やはり ver18にしないと無理っぽい

1
nodebrew ls-remote

で調べると

1
2
3
4
5
v18.0.0   v18.1.0   v18.2.0   v18.3.0   v18.4.0   v18.5.0   v18.6.0   v18.7.0
v18.8.0   v18.9.0   v18.9.1   v18.10.0  v18.11.0  v18.12.0  v18.12.1  v18.13.0
v18.14.0  v18.14.1  v18.14.2  v18.15.0  v18.16.0  v18.16.1  v18.17.0  v18.17.1
v18.18.0  v18.18.1  v18.18.2  v18.19.0  v18.19.1  v18.20.0  v18.20.1  v18.20.2
v18.20.3  v18.20.4

となっているので

1
nodebrew install-binary v18.20.4

でインストール

1
nodebrew use v18.20.4


使用バージョンを変更する

1
node -v

でバージョンを確認
v18.20.4

バージョンを変更した場合 firebase init functions などは再度実行する必要があるか調べる

– **Node.jsのバージョンを変更した場合でも、`firebase init functions`を再実行する必要はありません。**
– **依存関係を再インストールするために、`node_modules`と`package-lock.json`を削除してから`npm install`を実行してください。**
– **`package.json`の`engines`フィールドが正しく設定されていることを確認してください。**
– **デプロイ後にLINE Botが正常に動作するか確認し、問題があればエラーログをチェックしてください。**

ということで

1
2
rm -rf node_modules
rm package-lock.json

でver20 でインストールしたパッケージとロックファイルを削除

1
npm install

依存関係の再インストール

1
2
3
4
5
6
7
8
9
npm warn deprecated inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
npm warn deprecated glob@7.2.3: Glob versions prior to v9 are no longer supported
 
added 497 packages, and audited 498 packages in 1m
 
52 packages are looking for funding
  run `npm fund` for details
 
found 0 vulnerabilities

となる

これらの警告メッセージの意味

1. npm WARN deprecated
* deprecated(非推奨)とは、そのパッケージがサポートされておらず、将来的に使用しないことが推奨されていることを意味します。
* 具体的には、パッケージが古くなっている、メンテナンスされていない、または既知の問題がある場合に表示されます。

2. 各警告の詳細
a. inflight@1.0.6 の警告

npm WARN deprecated inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
* 意味:inflightパッケージはサポートされておらず、メモリリークの問題があるため、使用しないことが推奨されています。
* 対策:代替としてlru-cacheを使用することが提案されています。
b. glob@7.2.3 の警告

npm WARN deprecated glob@7.2.3: Glob versions prior to v9 are no longer supported
* 意味:globパッケージのバージョン7.2.3はサポートされておらず、バージョン9未満はサポート外であることを示しています。

とのこと

ということでファイルを調べる

1
cat package.json

で調べた

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"serve": "firebase emulators:start --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "18"
},
"main": "index.js",
"dependencies": {
"@line/bot-sdk": "^9.4.0",
"express": "^4.21.0",
"firebase-admin": "^12.1.0",
"firebase-functions": "^5.0.0"
},
"devDependencies": {
"firebase-functions-test": "^3.1.0"
},
"private": true
}

となっている

直接依存しているパッケージが古いバージョンがあるか調べた

## **結論**

直接依存しているパッケージのいくつかが最新バージョンではないため、**アップデートを行うことで警告が解消される可能性**があります。

## **まとめ**

– **直接依存しているパッケージに古いバージョンがあります**ので、最新バージョンにアップデートしましょう。
– **パッケージのアップデート後**、必ず動作確認とテストを行ってください。
– **エラーや警告が解消される**可能性があります。

となる

なので

1
2
npm install @line/bot-sdk@latest express@latest firebase-admin@latest firebase-functions@latest --save
npm install firebase-functions-test@latest --save-dev

を実行し

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
cat package.json
{
  "name": "functions",
  "description": "Cloud Functions for Firebase",
  "scripts": {
    "serve": "firebase emulators:start --only functions",
    "shell": "firebase functions:shell",
    "start": "npm run shell",
    "deploy": "firebase deploy --only functions",
    "logs": "firebase functions:log"
  },
  "engines": {
    "node": "18"
  },
  "main": "index.js",
  "dependencies": {
    "@line/bot-sdk": "^9.4.0",
    "express": "^4.21.0",
    "firebase-admin": "^12.5.0",
    "firebase-functions": "^6.0.1"
  },
  "devDependencies": {
    "firebase-functions-test": "^3.3.0"
  },
  "private": true
}

で内容を確認

1
npm install @line/bot-sdk@latest express@latest firebase-functions@latest --save

を行ったが変わらない

1
rm -rf node_modules package-lock.json

で削除

本当にあってるか調べることにした

https://www.npmjs.com/package/firebase-functions
で調べたら
firebase-functionsは6.01

https://www.npmjs.com/package/@line/bot-sdk

@line/bot-sdk は9.4.0

firebase-admin が12.5.0
https://www.npmjs.com/package/firebase-admin

expressが4.21.0
https://www.npmjs.com/package/express

つまりchatgpt が間違いで
ファイルはあっていた

1
npm cache clean --force

でキャッシュファイルをクリア

1
npm warn using --force Recommended protections disabled.

警告が出たので調べた

警告メッセージの意味
この警告は、npm cache clean コマンドを
–force オプション付きで実行 した場合に表示されるものです。

* –force オプションの意味:通常、npm cache clean はデフォルトでキャッシュを削除しません。
–force オプションを付けることで、キャッシュの強制削除を行います。

* 警告の内容:
Recommended protections disabled.
(推奨される保護機能が無効になりました)と表示されている通り、
キャッシュの強制削除は慎重に行うべき操作であるため、警告が表示されます。
対処方法と次のステップ

1. 警告は無視しても大丈夫か?
* 結論:この警告は 予期されたもの であり、特に問題はありません。
* 理由:npm cache clean –force を実行するときに、必ずこの警告が表示されます。
これはユーザーに対して注意を促すためのものです。

とりあえず無視で良いらしい

1
npm install

でパッケージの再インストール

ちなみに再度 javascriptで構成したときに
ユニーク名である必要があり
functionsではなく line-bot となっているので
これで置き換えて考えればいい

とりあえずここまでできたので
必要なライブラリのインストールはOK

シークレット情報であるchannelAccessTokenとchannelSecretをFirebaseの環境変数として設定

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

を実行する

しかし

1
zsh: command not found: firebase

となる

1
npm install -g firebase-tools

で再度インストール
これは ver18に変更したので再インストールが必要だった

1
firebase --version

13.18.0
でバージョンを確認

https://www.npmjs.com/search?q=firebase%20
でも確認し、最新版であるのを確認

1
firebase login

でログインできるのも確認ずみ

再度

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

を実行する

1
2
3
<img draggable="false" class="emoji" alt="✔" src="https://s.w.org/images/core/emoji/11/svg/2714.svg">  Functions config updated.
 
Please deploy your functions for the change to take effect by running firebase deploy --only functions

となってセット完了

次に
functions/index.js
の編集
とは言っても functions から フォルダを変更しているので
移動してから
index.js を編集する

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
 * Import function triggers from their respective submodules:
 *
 * const {onCall} = require("firebase-functions/v2/https");
 * const {onDocumentWritten} = require("firebase-functions/v2/firestore");
 *
 * See a full list of supported triggers at https://firebase.google.com/docs/functions
 */
 
const {onRequest} = require("firebase-functions/v2/https");
const logger = require("firebase-functions/logger");
 
// Create and deploy your first functions
// https://firebase.google.com/docs/functions/get-started
 
// exports.helloWorld = onRequest((request, response) => {
//   logger.info("Hello logs!", {structuredData: true});
//   response.send("Hello from Firebase!");
// });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
const functions = require('firebase-functions');
const express = require('express');
const line = require('@line/bot-sdk');
 
const app = express();
 
// 環境変数からLINEのチャネルアクセストークンとシークレットを取得
const config = {
  channelAccessToken: functions.config().line.channel_access_token,
  channelSecret: functions.config().line.channel_secret,
};
 
const client = new line.Client(config);
 
// 署名検証のミドルウェアを設定
app.post('/callback', line.middleware(config), (req, res) => {
  Promise
    .all(req.body.events.map(handleEvent))
    .then(() => res.end('OK'))
    .catch((err) => {
      console.error(err);
      res.status(500).end();
    });
});
 
// イベントハンドラーの実装
function handleEvent(event) {
  // メッセージイベント以外は無視
  if (event.type !== 'message' || event.message.type !== 'text') {
    return Promise.resolve(null);
  }
 
  // 受信したメッセージと同じ内容を返信
  const echo = { type: 'text', text: event.message.text };
  return client.replyMessage(event.replyToken, echo);
}
 
// Firebase Functionsとしてエクスポート
exports.app = functions.https.onRequest(app);

として保存

1
firebase deploy --only functions

を実行したが

1
2
3
4
5
6
7
8
9
10
11
12
13
=== Deploying to 'voicelinebot'...
 
i  deploying functions
i  functions: preparing codebase default for deployment
i  functions: preparing codebase line-bot for deployment
i  functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i  functions: ensuring required API cloudbuild.googleapis.com is enabled...
i  artifactregistry: ensuring required API artifactregistry.googleapis.com is enabled...
<img draggable="false" class="emoji" alt="⚠" src="https://s.w.org/images/core/emoji/11/svg/26a0.svg">  functions: missing required API cloudbuild.googleapis.com. Enabling now...
<img draggable="false" class="emoji" alt="⚠" src="https://s.w.org/images/core/emoji/11/svg/26a0.svg">  artifactregistry: missing required API artifactregistry.googleapis.com. Enabling now...
<img draggable="false" class="emoji" alt="✔" src="https://s.w.org/images/core/emoji/11/svg/2714.svg">  functions: required API cloudfunctions.googleapis.com is enabled
 
Error: Your project voicelinebot must be on the Blaze (pay-as-you-go) plan to complete this command. Required API artifactregistry.googleapis.com can't be enabled until the upgrade is complete. To upgrade, visit the following URL:

となる

以下はGPTでの回答

## **原因の説明**

このエラーは、**Firebaseプロジェクトが無料のSparkプランではなく、
有料のBlaze(従量課金)プランにアップグレードする必要がある**ことを示しています。

具体的な原因は以下のとおりです:

– **Node.js 18を使用したFirebase Functionsのデプロイ**:

– 現在、Firebase Functionsで**Node.js 18**を使用する場合、
**Artifact Registry API**と**Cloud Build API**が必要です。
– これらのAPIは、**Blazeプランでのみ利用可能**です。

– **必要なAPIの有効化**:

– エラーメッセージにある`artifactregistry.googleapis.com`や
`cloudbuild.googleapis.com`は、Blazeプランでないと有効化できません。

## **解決策**

### **オプション1:FirebaseプロジェクトをBlazeプランにアップグレードする**

– **手順**:

1. **Firebaseコンソールにアクセス**:

– エラーメッセージに記載されているURL、または[Firebaseコンソール](https://console.firebase.google.com/)にアクセスします。

2. **プロジェクトを選択**:

3. **プランのアップグレード**:

– 左側のメニューから「**Usage and billing(使用量と請求)**」
または「**Billing(請求)**」を選択します。

– 「**Sparkプラン**」から「**Blazeプラン**」にアップグレードします。
– クレジットカード情報を入力する必要がありますが、**無料利用枠内であれば料金は発生しません**。

– **メリット**:

– **Node.js 18を引き続き使用**できます。
– **最新のランタイム環境**で開発とデプロイが可能です。

– **注意点**:

– **従量課金制**であるため、無料枠を超えると料金が発生します。
– **料金が発生する可能性**があるため、費用管理を適切に行う必要があります。

### **オプション2:Node.jsのバージョンを16にダウングレードする**

– **注意点**:

– **Node.js 16は2024年9月11日にEOL(サポート終了)**となります。
– **将来的にアップグレードが必要**になるため、一時的な解決策となります。

## **補足情報**

### **Blazeプランについて**

– **無料利用枠は引き続き適用**されます。
– **実際に使用した分だけ**料金が発生します。
– **無料枠を超過した場合**のみ課金されます。

### **料金の管理**

– **Firebaseコンソールで予算アラート**を設定できます。
– **費用上限を設定**することで、予期せぬ料金発生を防止できます。

つまりBlazeプラン使用にしないとwebhookはできないらしい

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です