LINEbot で特定のユーザーのメッセージの取得

LINEbot で特定のユーザーのメッセージの取得

LINEbotで特定のユーザのメッセージの取得をする
webhook には firebase第一世代を使用
使用しているのは node.js の18
この構成で LINEbot で特定のユーザーのメッセージの取得する python コード

これを行うには
Firebase プロジェクトが設定されており、
Firestore のアクセスに必要なクレデンシャル JSON ファイルがある

google-cloud-firestore パッケージがインストールされている
の条件を満たす必要がある

Firebase プロジェクトで
Firestore のアクセスに必要なクレデンシャル JSON ファイルが設定されているかを確認

まず
Firebase Console にアクセスし、対象のプロジェクトを選択

左側のメニューから 「プロジェクトの設定」 (Project settings) をクリック

「サービスアカウント」 (Service accounts) タブを開く

Admin SDK 構成スニペット
があるので調べる

Admin SDK 構成スニペットにはどれを選べば良い?
webhook には firebase第一世代を使用し 使用しているのは node.js の18の場合は?


GPTで調べると
Firebase 第一世代の webhook に Node.js 18 を使用している場合、
Firestore の管理者権限でアクセスするには、Admin SDK 構成スニペットとして Node.js を選択

となるので
Node.js のままで

var admin = require("firebase-admin");

var serviceAccount = require("path/to/serviceAccountKey.json");

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount)
});

「新しい秘密鍵の生成」をクリックして、サービスアカウントの JSON クレデンシャルをダウンロード
ファイルをプロジェクトにコピーする

とりあえずJSONファイルは取得できたので
次に

pip install google-cloud-firestore


firesroreのセットアップ

しかしよく考えてみれば
node.jsは firebaseで動かしているが
m1macbookAir では動かしていない

違いがわからないため再度質問

Admin SDK 構成スニペットにはどれを選べば良い?
webhook には firebase第一世代を使用し 使用しているのは node.js の18の場合は?
の答えは node.js だった。
この場合動かす環境は firebaseを想定しているか?
それともm1macbookAir で node.js を想定しているのか?

答えは

この場合、**動かす環境は Firebase を想定**しています。
具体的には、Node.js 18 を使って Firebase Gen 1 環境上で webhook が動作する構成です。
したがって、Node.js 用の Firebase Admin SDK 構成スニペットを選択することになります。

この Node.js のスニペットは、Firebase サーバー側で
webhook として動作する Node.js 環境向けに設定されており、
M1 MacBook Air 上ではなく、
**Firebase のサーバー上で稼働する Node.js のコードに適用**されるものです。

一方で、**Python は MacBook Air 上で動作し、
Firestore からメッセージを取得するためのコード**として使われます。
そのため、Python の Firebase Admin SDK を MacBook Air 上で利用して
Firestore にアクセスする構成になります。

となった

このため再度Admin SDK 構成スニペットをpythonで取得する

import firebase_admin
from firebase_admin import credentials

cred = credentials.Certificate("path/to/serviceAccountKey.json")
firebase_admin.initialize_app(cred)

ダウンロードできたら
でファイルをコピーする

なおこの構成スニペットで表示されているコードは
Python 用の Firebase Admin SDK を使用して、Firebase プロジェクトに接続するための初期設定を行うもの

このスクリプトによって、Python 環境から Firebase にアクセスできるようになる

serviceAccountKey.json
へファイル名を変更

これで

vim access.python

として

import firebase_admin
from firebase_admin import credentials

cred = credentials.Certificate("serviceAccountKey.json")
firebase_admin.initialize_app(cred)

として保存

実行したら

python access.json                
Traceback (most recent call last):
  File "/Users/snowpool/aw10s/linebot/access.json", line 1, in <module>
    import firebase_admin
ModuleNotFoundError: No module named 'firebase_admin'

となった

pip install firebase-admin

でインストール

今度は実行しても何も表示されない

接続が正常に行われているか確認するために、
Firestore のデータベースからデータを取得したり、簡単なメッセージを表示させる
以下のようにして Firestore からデータを取得

import firebase_admin
from firebase_admin import credentials, firestore

# サービスアカウント JSON ファイルのパスに置き換える
cred = credentials.Certificate("path/to/serviceAccountKey.json")
firebase_admin.initialize_app(cred)

# Firestore クライアントの取得
db = firestore.client()

# Firestore の 'messages' コレクションからデータを取得
def get_messages():
    messages_ref = db.collection("messages")
    docs = messages_ref.stream()
    
    for doc in docs:
        print(f"{doc.id} => {doc.to_dict()}")

# 動作確認のためにメッセージを取得
get_messages()

これをcheck.py
として実行たがエラー

原因は
Cloud Firestore API がプロジェクト「voicelinebot」で有効になっていないために発生しています。
Firestore API を有効にするがエラー

プロジェクトに Cloud Firestore データベースがまだ存在しないために発生しています。
Firestore データベースを初期化する必要があります

とのこと

firebase.jsonの修正

Firebase Functions(第2世代)は、内部的にCloud Run上で動作します。そのため、エラーメッセージにCloud Runが出てきます
とのこと

第1世代の関数に設定することで解決しそう

なのでfirebase.jsonを修正する

firebase.jsonの修正

firebase.jsonで関数を第1世代に設定する

Firebase Functionsの第1世代(Gen 1)と第2世代(Gen 2)の主な違いについて

### **1. 実行環境の違い**

– **第1世代(Gen 1):**
– **Google Cloud Functions**をベースにしています。
– Node.jsのサポートバージョンは**Node.js 10、12、14、16、18**です。
– メモリは最大**2GB**まで利用可能です。
– **シングルリクエストモデル**で、1つの関数インスタンスは同時に1つのリクエストのみを処理します。

– **第2世代(Gen 2):**
– **Google Cloud Run**をベースにしています。
– Node.jsのサポートバージョンは**Node.js 16、18**です。
– メモリは最大**16GB**まで利用可能です。
– **同時実行**が可能で、1つの関数インスタンスが複数のリクエストを同時に処理できます。

### **2. スケーリングとパフォーマンス**

– **第1世代:**
– スケーリングは自動ですが、**コールドスタート**が発生しやすいです。
– 最大インスタンス数はデフォルトで**1000**です。

– **第2世代:**
– スケーリングがより柔軟で、コールドスタートの影響が少ないです。
– 最大インスタンス数はデフォルトで**1000**ですが、同時実行により効率が向上します。

### **3. トリガーのサポート**

– **第1世代:**
– **すべてのFirebaseトリガー**
(Cloud Firestore、Realtime Database、Authentication、Storageなど)
をサポートしています。

– **第2世代:**
– **一部のトリガーのみ**サポートしています。
現在はHTTPトリガーやCloud Eventに対応していますが、他のトリガーは順次対応予定です。

### **4. 設定とカスタマイズ**

– **第1世代:**
– 設定オプションが限定的で、シンプルな設定が可能です。
– タイムアウトは最大**540秒(9分)**まで設定可能です。

– **第2世代:**
– **より詳細な設定**が可能です。タイムアウトは最大**3600秒(1時間)**まで設定できます。
– **VPC接続**や**同時実行数の設定**など、高度なカスタマイズが可能です。

### **5. 料金体系**

– **第1世代:**
– **無料枠**があり、リクエスト数や実行時間に応じて課金されます。
– **コールドスタート**が多い場合、待機時間も考慮する必要があります。

– **第2世代:**
– Cloud Runの料金体系に基づきます。
– 同時実行が可能なため、**コスト効率が向上**する場合があります。

### **6. 環境変数の取り扱い**

– **第1世代:**
– 環境変数は`functions.config()`を使用して取得します。
– `process.env`から直接取得することは推奨されていません。

– **第2世代:**
– 環境変数は`process.env`から直接取得できます。
– `.env`ファイルを使用した環境変数の管理も可能です。

### **7. デプロイと開発の違い**

– **第1世代:**
– 開発とデプロイがシンプルで、**迅速な開発**が可能です。
– Firebase CLIで簡単にデプロイできます。

– **第2世代:**
– **より高度な設定**が可能ですが、その分デプロイ手順が複雑になる場合があります。
– `firebase.json`で世代を指定する必要があります。

– **第1世代(Gen 1)は、シンプルで素早くデプロイしたい場合に適しています。**
– **第2世代(Gen 2)は、高いパフォーマンスや高度なカスタマイズが必要な場合に適しています。**

**参考情報:**

– [Firebase公式ドキュメント – 第1世代と第2世代の比較](https://firebase.google.com/docs/functions/compare-gen-1-and-gen-2?hl=ja)
– [Firebase Functionsの概要](https://firebase.google.com/docs/functions?hl=ja)

これらを元に書き換える

{
  "functions": [
    {
      "source": "プロジェクト名",
      "codebase": "プロジェクト名",
      "runtime": "nodejs18",
      "ignore": [
        "node_modules",
        ".git",
        "firebase-debug.log",
        "firebase-debug.*.log",
        "*.local"
      ]
    }
  ],
  "functions.deployment": {
    "line-bot": {
      "gen": 1
    }
  }
}

というようにした

これで再度

firebase deploy --only functions

を実行すると

   ╭────────────────────────────────────────────────────────────────────╮
   │                                                                    │
   │                 Update available 13.18.0 → 13.19.0                 │
   │           To update to the latest version using npm, run           │
   │                   npm install -g firebase-tools                    │
   │   For other CLI management options, visit the CLI documentation    │
   │         (https://firebase.google.com/docs/cli#update-cli)          │
   │                                                                    │
   │                                                                    │
   │                                                                    │
   ╰────────────────────────────────────────────────────────────────────╯

この後に
Index.js を編集

const functions = require("firebase-functions");
const express = require("express");
const line = require("@line/bot-sdk");

const config = {
  channelAccessToken: functions.config().line.channel_access_token,
  channelSecret: functions.config().line.channel_secret,
};

const app = express();

app.post("/webhook", line.middleware(config), (req, res) => {
  Promise.all(req.body.events.map(handleEvent))
    .then((result) => res.json(result))
    .catch((err) => {
      console.error(err);
      res.status(500).end();
    });
});

const client = new line.Client(config);

function handleEvent(event) {
  if (event.type !== "message" || event.message.type !== "text") {
    return Promise.resolve(null);
  }

  return client.replyMessage(event.replyToken, {
    type: "text",
    text: event.message.text,
  });
}

exports.webhook = functions.https.onRequest(app);

として保存し

firebase deploy --only functions

を実行

webhookのURLが判明するので

これをLINEアカウントにログインして設定する

Blazeプランの概要

Blazeプランの概要

無料枠について
* 無料枠は毎月リセットされます。
* 無料枠の内容は、以下のサービスごとに定められています。
例:Firebase Functions(Cloud Functions for Firebase)

* 関数の呼び出し回数:200万回/月
* コンピューティング時間:400,000 GB-秒/月
* ネットワーク送信量:5 GB/月
その他のサービスの無料枠
* Firebase Authentication
* 無制限の認証機能が無料で利用可能
* Firebase Realtime Database
* 1 GBのデータストレージ
* 10 GB/月のダウンロード
* Firestore
* 1 GBのデータストレージ
* 5万回の読み取り/日
* 2万回の書き込み/日
* 2万回の削除/日
* Firebase Hosting
* 10 GB/月のデータ送信
* 10 GBのストレージ
* カスタムドメインのSSL証明書が無料

費用の管理
* 無料枠内であれば料金は発生しません。
* 無料枠を超過した場合のみ、使用量に応じて課金されます。
* 予算アラートや費用上限の設定が可能で、予期しない高額な請求を防ぐことができます。

料金の例
Firebase Functions
* 関数の呼び出し:$0.40/100万回(無料枠超過分)
* コンピューティング時間:
* GB-秒あたり$0.0000025(メモリ使用量と実行時間に基づく)
* ネットワーク送信量:
* 北米地域:$0.12/GB(無料枠超過分)
Firestore
* データストレージ:$0.18/GB/月(無料枠超過分)
* 読み取り操作:$0.06/10万回
* 書き込み操作:$0.18/10万回
* 削除操作:$0.02/10万回

これらを元に対策をしておく
従量課金の場合助言はないためリスク管理が必要

Firebase の課金で爆死しないための設定方法
を参考に設定を調べる

Functions は関数の実行時間、関数の呼び出し回数、関数にプロビジョニングしたリソースの数に基づいて課金される

export const api = functions.https.onRequest(app);

の部分を

export const api = functions.runWith({
  maxInstances: 1,
  timeoutSeconds: 30,
  memory: "128MB",
}).https.onRequest(app);

というように

最大インスタンス数1
timeoutSeconds30秒
メモリ128MB
というように設定することで回避できそう

次に
Hosting はストレージが10GBまで無料
データ転送は1ヶ月あたり 10GB まで無料
それを超えると課金が発生
デフォルトでは無制限に保持する設定になっているため
Firebase コンソールの Hostring から設定を変更

これらを元に
個人アプリなら10もあれば十分

転送量は制限できないのでアプリケーションの作りで頑張るしかない

あと
Firestore は以下の内容で課金されます。
* 読んだり、書いたり、削除したりする文書の数。
* 集計クエリで一致したインデックス エントリの数。
クエリに一致する最大 1000 のインデックス
エントリのバッチごとに 1 つのドキュメントの読み取りが課金されます。

* メタデータとインデックスのオーバーヘッドを含む、データベースが使用するストレージの量。
* 使用するネットワーク帯域幅の量。
Firestore は何か制限を設けることができません。


なので上記を参考に書き込みや読み取り方法をチューニングしたり、
インデックスを作成してアプリケーション側をよくしていくしかない

そして
コストアラートを設定する
予算の 50%, 90%, 100% でアラートが来る設定をできるらしい

そして
最悪、Firebaseを止める方法

 firebase hosting:disable

を実行すれば
Hosting は止まる

Functions を止める方法は

 firebase functions:delete {関数名}

Firestore を止める方法は
Firebase コンソールから以下のルールの設定を入れて公開

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read: if false;
      allow write: if false;
    }
  }
}

これで読み取り、書き込み全てをブロック

これらを元にまずはアラートを予算1000円で動作するよう設定
https://console.cloud.google.com/billing/

予算を設定できるので1,000円に設定

index.js の内容を

export const api = functions.https.onRequest(app);

から

const runtimeOpts = {
    timeoutSeconds: 30,
    memory: '128MB',
    maxInstances: 1, // 最大同時実行数を5に制限
  };
exports.app = functions
.runWith(runtimeOpts)
.https.onRequest(app);

へ変更し保存

これでBlazeプランに変更する

請求アカウントは予算を作成したものを選択

LINEbotのwebhookをfirebaseで行う

LINEbotのwebhookをfirebaseで行う

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

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

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

rm -rf functions

で削除する

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

firebase init functions

を実行

❯ Initialize 

を選択

今回は

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`でデプロイします。

とのこと

とりあえず

Default 

にするが

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

となるので

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

? What language would you like to use to write Cloud Functions? 
❯ JavaScript 
  TypeScript 
  Python 


javascriptを選択

? 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 にする

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

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

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...

✔  Firebase initialization complete!

となる

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

npm install @line/bot-sdk express

実行結果は

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にしないと無理っぽい

nodebrew ls-remote

で調べると

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  

となっているので

nodebrew install-binary v18.20.4 

でインストール

nodebrew use v18.20.4


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

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が正常に動作するか確認し、問題があればエラーログをチェックしてください。**

ということで

rm -rf node_modules
rm package-lock.json

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

npm install

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

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未満はサポート外であることを示しています。

とのこと

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

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.1.0",
"firebase-functions": "^5.0.0"
},
"devDependencies": {
"firebase-functions-test": "^3.1.0"
},
"private": true
}

となっている

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

## **結論**

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

## **まとめ**

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

となる

なので

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

を実行し

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
}

で内容を確認

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

を行ったが変わらない

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 が間違いで
ファイルはあっていた

npm cache clean --force            

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

npm warn using --force Recommended protections disabled.

警告が出たので調べた

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

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

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

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

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

npm install

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

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

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

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

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

を実行する

しかし

zsh: command not found: firebase

となる

npm install -g firebase-tools

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

firebase --version

13.18.0
でバージョンを確認

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

firebase login

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

再度

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

を実行する

✔  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 を編集する

/**
 * 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!");
// });

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);

として保存

firebase deploy --only functions

を実行したが

=== 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...
⚠  functions: missing required API cloudbuild.googleapis.com. Enabling now...
⚠  artifactregistry: missing required API artifactregistry.googleapis.com. Enabling now...
✔  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はできないらしい

Firebase セットアップ

Firebase セットアップ

実行環境
M1 MacbookAir 16GB

npm install -g firebase-tools

でFirebase CLIをインストール

次に料金体系などを調べておく
これは以前、従量課金でワトソンを使ったら
後で数万円の請求が来たことがあるので
調べるようにしている

使うのは無料枠にする

chatGPTの回答

Firebaseの無料枠と料金プランについて説明します。
Firebaseの無料枠 (Sparkプラン)
Firebaseには無料で利用できるSparkプランがあり、主に以下のサービスに対して無料枠が提供されています:
1. Firebase Hosting:
    * 1GBのストレージ
    * 10GB/月のデータ転送量
2. Firestore (NoSQL データベース):
    * 1GBのストレージ
    * 50,000 回/月の読み取り操作
    * 20,000 回/月の書き込み操作
    * 20,000 回/月の削除操作
3. Realtime Database:
    * 100MBのストレージ
    * 1GB/月のデータ転送量
4. Firebase Authentication:
    * 無制限の認証 (メール/パスワード、匿名、Google、Facebook、Twitterなど)
5. Firebase Cloud Functions:
    * 125,000呼び出し/月
    * 400,000GB-秒の計算時間/月
    * 5GBの出力データ転送量/月
6. Firebase Cloud Messaging:
    * 無制限のプッシュ通知 (送信数に制限なし)
7. Firebase Cloud Storage:
    * 1GBのストレージ
    * 5GB/月のデータ転送量
その他の注意点
* Firebase Authentication はSparkプランで無制限に利用できますが、電話認証(SMS認証)については無料枠があり、それを超えると従量課金が発生します。

次に

Firebase CLIのインストール

Firebase Hostingの設定があったので
有効にしているようだが使わない場合はどうなるか?
を調べる

今回のように、**WebhookサーバーとしてFirebaseを使用する場合、Firebase Hostingは必須ではありません**。Webhookサーバーを構築するためには、主に次のFirebase機能を使用します:

1. **Firebase Cloud Functions**:
– Webhookのエンドポイントを作成するために使用します。Cloud Functionsを使えば、サーバーレスでスケーラブルなWebhookサーバーを簡単にセットアップできます。

2. **Firebase Firestore(またはRealtime Database)**:
– 必要に応じて、Webhookからのデータを保存するために使用します。例えば、音声データのテキスト変換結果や、ユーザーアクションのログを記録するなどの用途です。

### Firebase Hostingが必要ない理由

– **サーバーレスアーキテクチャ**:
– WebhookサーバーのエンドポイントはCloud Functionsで処理されるため、物理的なサーバーや特定のホスティング環境は不要です。

– **静的コンテンツがない**:
– Webhookサーバーは、通常、静的なウェブページを提供するわけではなく、リクエストを受け取って処理するだけのエンドポイントを提供します。したがって、静的コンテンツをホストする必要がない場合、Firebase Hostingは無関係です。

### まとめ

WebhookサーバーをFirebase Cloud Functionsで実装する場合、Firebase Hostingは必要ありません。Firebase Hostingは主に静的ウェブサイトやSPA(シングルページアプリケーション)の公開に使用されるため、Webhookサーバーの構築には直接関係がありません。

そのため、今回はFirebase Hostingを有効にしなくても、Webhookサーバーとしての機能は十分に提供されます。Firebase Cloud Functionsと、必要に応じてFirestoreなどの他のFirebaseサービスを組み合わせて使用すれば、要件を満たすことができます。

ということなので
使うのは
Firebase Cloud Functions
Firebase Firestore(またはRealtime Database)
ということになる

firebase functions(バックエンドサービス)を使うなら
nodeは18 or 20(public beta)が必要らしい

Firebase Functions(Cloud Functions for Firebase)を使用する場合、
現在サポートされているNode.jsのバージョンは18と、最近追加された20(パブリックベータ版)です。
これはFirebaseが提供する最新の機能やセキュリティ強化のためです。

### Firebase FunctionsでのNode.jsバージョンの要件

1. **Node.js 18**:
– これは現在のデフォルトでサポートされている安定版のNode.jsバージョンです。Node.js 18は長期サポート(LTS)リリースであり、セキュリティやパフォーマンスの向上が期待されます。
– Firebase CLIを使用して新しいCloud Functionsプロジェクトを作成する場合、デフォルトでNode.js 18が使用されます。

2. **Node.js 20 (Public Beta)**:
– Node.js 20は最新の機能を試すためのパブリックベータ版として提供されています。新しい言語機能やパフォーマンスの改善が含まれていますが、ベータ版であるため、プロダクション環境での使用には慎重になる必要があります。
– Node.js 20を使用するには、Firebaseプロジェクトの設定で明示的に指定する必要があります。

### Node.jsバージョンを指定する方法

`firebase-functions`のNode.jsバージョンを指定するには、`package.json`ファイルで指定します。以下の例のように設定してください。

```json
{
  "engines": {
    "node": "18"
  }
}
```

または、Node.js 20を使用したい場合は:

```json
{
  "engines": {
    "node": "20"
  }
}
```

### まとめ

– Firebase Functionsで最新の機能とセキュリティを利用するためには、
Node.js 18が推奨されており、これは現在のデフォルトです。
– Node.js 20はパブリックベータ版であり、新しい機能を試したい場合に利用できますが、
プロダクション環境での使用には慎重を要します。
– `package.json`でNode.jsのバージョンを明示的に指定することで、
使用するNode.jsバージョンをコントロールできます。

この情報に基づいて、プロジェクトの要件に最も適したNode.jsのバージョンを選択し、
Firebase Functionsを利用してください。

既に
npm install -g firebase-tools
 を実行しているが nvm install 20 nvm use 20 の後に再度実行する必要があるか?

の答えは

Node.jsのバージョンを変更した後、
`npm install -g firebase-tools`を再度実行する必要は**通常ありません**。
以下に、状況を整理してお答えします。

### なぜ再インストールが不要か

- **グローバルインストール**: `npm install -g firebase-tools`でインストールした`firebase-tools`は、グローバルにインストールされているため、Node.jsのバージョンに依存せず、システム全体で利用できます。
- **互換性**: Firebase CLIは通常、異なるNode.jsのバージョンで互換性があります。したがって、Node.jsのバージョンを切り替えた後でも、既にインストールされているFirebase CLIが動作します。

### nvmでNode.jsのバージョンを変更した場合の注意点

1. **パッケージの互換性**:
   - Node.jsのバージョンを切り替えた場合、特定のプロジェクトが新しいNode.jsバージョンで動作しない場合があります。この場合、プロジェクトの依存関係(`node_modules`)を再インストールする必要がありますが、これは`firebase-tools`の再インストールとは関係ありません。

2. **環境設定**:
   - `nvm use 20`でNode.js 20を使用するようにした場合、シェルセッション内でそのバージョンが有効になります。このシェルセッション内で`firebase-tools`コマンドを使用することに問題はありません。

### Firebase CLIのバージョンを確認する方法

Firebase CLIのバージョンが適切に動作しているか確認したい場合、以下のコマンドでバージョンを確認できます。

```bash
firebase --version
```

### まとめ

- `nvm`でNode.jsのバージョンを切り替えた後に、`firebase-tools`を再インストールする必要は通常ありません。
- Firebase CLIはグローバルにインストールされているため、Node.jsのバージョンを変更しても利用できます。
- `firebase --version`でCLIのバージョンが正常に動作しているかを確認してください。

これにより、`nvm`でのNode.jsバージョンの切り替えとFirebase CLIの使用が円滑に行えるはずです。

とのこと

つまり
WebhookサーバーとしてFirebaseを使用する場合
Firebase Cloud Functionsが必要
これを使用するには
Node.js 20 (Public Beta)
が必要

chatGPTでは

nvm install 20

となっているが
実行すると

zsh: command not found: nvm

M1macにインストールした時には

nodebrew install-binary stable


v22.7.0
がインストールされている

ちなみにバージョンを指定するので

nodebrew ls-remote

で調べると
20の場合は

v20.0.0  v20.1.0  v20.2.0  v20.3.0  v20.3.1  v20.4.0  v20.5.0  v20.5.1
v20.6.0  v20.6.1  v20.7.0  v20.8.0  v20.8.1  v20.9.0  v20.10.0 v20.11.0
v20.11.1 v20.12.0 v20.12.1 v20.12.2 v20.13.0 v20.13.1 v20.14.0 v20.15.0
v20.15.1 v20.16.0 v20.17.0  

となっている

今回は

v20.17.0
をインストールするので

nodebrew install-binary v20.17.0

結果は

Fetching: https://nodejs.org/dist/v20.17.0/node-v20.17.0-darwin-arm64.tar.gz
######################################################################### 100.0%
Installed successfully

使用バージョンを変更

nodebrew use v20.17.0
use v20.17.0

確認のため

node -v

とすれば

v20.17.0

となる

nodebrew ls

の結果は

v20.17.0
v22.7.0

current: v20.17.0

でインストールされているバージョンも確認

ここまでできたので
ゼロから始めるFirebase入門

を参考に

firebase login 

としたら

zsh: command not found: firebase

となる
chatGPTでは再度実行不要と言っていたけど

npm install -g firebase-tools   

を実行しインストール

firebase --version           

を実行すると

13.16.0

と表示される

Firebase でサイト公開

Firebase でサイト公開

Firebase プロジェクトの設定ができると
firebase.json
というファイルが作成される

これは
firebase init で作成された設定用ファイルになる

また public フォルダ内に
404.html が作成される

これらを確認したら
次にサイトを公開するので
プロジェクトフォルダに移動し

firebase deploy

を実行するとアップロードされ
Hosting URL が発行される

あとはこのURLをブラウザで表示すればページが表示される

また、変更をして更新をするときには
再度

firebase deploy

を実行すれば更新できる

サイトの更新履歴については
Firebase にログインして
Hosting をクリックすれば更新履歴を確認できる

また、バージョン管理もされているので
ロールバック機能を使うことで過去の状態に戻すことも可能

firebase プロジェクトの設定

firebase プロジェクトの設定

公開するフォルダを
firebase 用に初期化する

まず public のあるディレクトリに移動

cd MyPortfolioProject

次に

firebase list

を実行

これで現在 firebase にあるプロジェクト一覧が表示される

必要になるのは
Project ID / Instance の値

今回は
myportfolioproject-5e36a
を使う

次に初期化

firebase  init --project=myportfolioproject-5e36a

実行するとどのサービスを使うかい聞かれるので

◯ Hosting: Configure and deploy Firebase Hosting sites

までカーソルを十字キーで移動して
スペースで決定してから
Enter

いくつか変更があったので
create-react-appで作ったアプリをFirebaseで公開する方法

を参考に実践

ここから少し変わっている

? Please select an option: 
❯ Use an existing project 
  Create a new project 
  Add Firebase to an existing Google Cloud Platform project 
  Don't set up a default project 

とでてくる

今回はすでに作成したプロジェクトを使うので
そのままEnter

What do you want to use as your public directory? (public) 

となり
どのフォルダを公開用にするかと聞かれるので
これも デフォルトの public でよいので
そのまま Enter

次に

Configure as a single-page app (rewrite all urls to /index.html)? (y/N)

と聞かれSPAとして設定するかきかれるけど
今回は No にしたいので
そのままEnter でOK

SPAは Single Page Application の意味

次に

File public/index.html already exists. Overwrite? (y/N) 

となり
public の中にある index.html を上書きするか聞かれる
No なので Enter でOK

これで
Firebase initialization complete!
と表示されれば初期化はOK

ubuntu 16.04 へ Firebase-tools のインストール

ubuntu 16.04 へ Firebase-tools のインストール

Firebase CLI リファレンス

を参考にインストール

Node.js を使うため
npm を使ったインストールにする

sudo npm install -g firebase-tools

でインストール

しかし

firebase -V

を実行しても

┌────────────────────────────────────────────────────────────┐
│             firebase-tools update check failed             │
│            Try running with sudo or get access             │
│            to the local update config store via            │
│ sudo chown -R $USER:$(id -gn $USER) /home/snowpool/.config │
└────────────────────────────────────────────────────────────┘
/usr/local/lib/node_modules/firebase-tools/node_modules/configstore/index.js:53
				throw err;
				^

Error: EACCES: permission denied, open '/home/snowpool/.config/configstore/firebase-tools.json'
You don't have access to this file.

    at Object.openSync (fs.js:443:3)
    at Object.readFileSync (fs.js:343:35)
    at Configstore.get (/usr/local/lib/node_modules/firebase-tools/node_modules/configstore/index.js:34:26)
    at new Configstore (/usr/local/lib/node_modules/firebase-tools/node_modules/configstore/index.js:27:45)
    at Object.<anonymous> (/usr/local/lib/node_modules/firebase-tools/lib/configstore.js:4:18)
    at Module._compile (internal/modules/cjs/loader.js:776:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:787:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)

となってしまう

このため

sudo chown -R $USER:$(id -gn $USER) /home/snowpool/.config

を実行

これで再度

firebase -V

を実行すると
少し時間がかかるけどバージョンが表示される

これで

firebase login

を実行すると

i  Firebase optionally collects CLI usage and error reporting information to help improve our products. Data is collected in accordance with Google's privacy policy (https://policies.google.com/privacy) and is not used to identify you.

? Allow Firebase to collect CLI usage and error reporting information? (Y/n) 

となり
利用状況のデータを送信しますかとでるので
Yes ならそのまま Enter でOK

するとブラウザが立ち上がるので
アカウントを選択

次の画面で許可をクリック

これで
Firebase CLI Login Successful
となればOK