前言
最近在部署 LINE Bot + Gemini API 的 Cloud Functions Gen2 專案時,遇到一個讓服務直接 500 Error 的大坑:
因為當下是線上服務,必須立即修復,於是我先做了一個 臨時解法——讓程式直接從環境變數讀金鑰,並保留 fallback,以確保服務不中斷。
這篇筆記會記錄完整的問題背景、臨時解法、優缺點分析,以及後續的長期解法,避免下次再踩雷。
1. 問題描述
- 環境:Cloud Functions Gen2(Node.js 20)
- 情況:部署後讀取 Secret Manager(LINE_CHANNEL_ACCESS_TOKEN、GEMINI_API_KEY)時發生錯誤。
- 原因:函式使用的 Service Account 沒有 roles/secretmanager.secretAccessor 權限,導致 Secret Manager 無法存取。
2. 臨時解法流程(改用環境變數)
目標:跳過 Secret Manager,直接從環境變數取得金鑰,並保留 fallback。
2.1 查詢 Functions 服務帳號
gcloud functions describe line-bot-gemini-node-js-dev \
--region=asia-east1 \
--gen2 \
--format="json(serviceConfig.serviceAccountEmail,serviceConfig.environmentVariables)"
2.2 程式碼加 fallback
// getLineToken()
export async function getLineToken() {
try {
const tokenFromSecret = await getSecret('LINE_CHANNEL_ACCESS_TOKEN');
return process.env.LINE_CHANNEL_ACCESS_TOKEN ?? tokenFromSecret;
} catch (error) {
console.error('Failed to get LINE token:', error);
return process.env.LINE_CHANNEL_ACCESS_TOKEN; // fallback
}
}
// getGeminiApiKey()
export async function getGeminiApiKey() {
try {
const keyFromSecret = await getSecret('GEMINI_API_KEY');
return process.env.GEMINI_API_KEY ?? keyFromSecret;
} catch (error) {
console.error('Failed to get GEMINI API key:', error);
return process.env.GEMINI_API_KEY; // fallback
}
}
2.3 部署時直接塞環境變數
gcloud functions deploy line-bot-gemini-node-js-dev \
--gen2 \
--region=asia-east1 \
--runtime=nodejs20 \
--source=. \
--entry-point=lineWebhook \
--set-env-vars LINE_CHANNEL_ACCESS_TOKEN="你的LINE金鑰",GEMINI_API_KEY="你的Gemini金鑰" \
--trigger-http \
--allow-unauthenticated
3. 優缺點分析
優點
- 快速修復,不受 Secret Manager 權限影響。
- 部署即生效。
缺點
- 金鑰存在 Functions 設定檔,安全性較弱。
- 更新金鑰需重新部署。
4. 長期解法(修正 Secret Manager 權限)
- 查出 Functions 使用的 Service Account gcloud functions describe <你的函式名稱> \ --region=asia-east1 \ --gen2 \ --format="value(serviceConfig.serviceAccountEmail)"
- 到 GCP Console → IAM & Admin → IAM 找到上一步查到的 Service Account。
- 為該帳號新增角色 新增角色:Secret Manager Secret Accessor 儲存變更。
- 重新部署 Functions(可不加環境變數) gcloud functions deploy line-bot-gemini-node-js-dev \ --gen2 \ --region=asia-east1 \ --runtime=nodejs20 \ --source=. \ --entry-point=lineWebhook \ --trigger-http \ --allow-unauthenticated
- 驗證 移除 --set-env-vars 部署後,測試程式是否能正常讀取 Secret Manager。
5. 建議
- 開發/測試:用環境變數方便快速部署。
- 正式環境:修好 Secret Manager 權限後切回 Secret Manager。
- 程式保留 fallback:即使 Secret Manager 臨時掛掉,也能用環境變數維持服務。




















