July 29th, 2025
前情提要
關於 Vertex AI 上面使用 Gemini 來做圖形偵測的架構圖
絕對可以!您的想法完全正確,這是解決這個問題的標準且唯一的途徑。
既然不能用一個「超級管理員」帳號(服務帳號)來處理所有事情,我們就必須讓每一個使用者授權您的應用程式來存取他們自己的 Google Drive。這就是 OAuth 2.0 的用途。
這個改動會比之前複雜很多,因為它引入了使用者互動的認證流程。我會為您詳細拆解。
宏觀概念:使用者授權流程
- 使用者發起連線:使用者在 Telegram 中對您的機器人發送一個指令,例如 /connect_drive。
- 產生授權連結:您的機器人會產生一個獨一無二的 Google 授權連結,並將它傳回給使用者。
- 使用者授權:使用者點擊連結,會被帶到 Google 的登入和授權頁面。頁面會顯示「TG Helper 想要存取您的 Google Drive」,使用者點擊「允許」。
- 重新導向並取得授權碼:Google 會將使用者重新導向到您預先設定好的一個網址(Callback URL),並附上一組一次性的授權碼 (Authorization Code)。
- 交換權杖:您的後端服務(Cloud Run)收到這個授權碼後,會用它跟 Google 交換一組存取權杖 (Access Token) 和一個非常重要的更新權杖 (Refresh Token)。
- 儲存權杖:您的應用程式需要一個資料庫(例如 Firestore),將使用者的 Telegram ID 和他們的更新權杖安全地儲存起來。
- 上傳檔案:當這位使用者之後傳送檔案時,您的機器人會:
- 從資料庫中讀取這位使用者的更新權杖。
- 使用更新權杖取得一組新的、有時效性的存取權杖。
- 使用這組代表該使用者的存取權杖,將檔案上傳到他自己的 Google Drive。
新的架構
這個流程需要一些新的元件:
- 一個 Web 端點:您的 Cloud Run 應用程式除了接收 Telegram 的 Webhook,還需要一個新的 HTTP 路徑 (例如 /oauth/callback) 來接收 Google 的重新導向。
- 一個資料庫:用來儲存使用者 ID 和他們的 Refresh Token。最簡單的選擇是 Firestore,因為它與 Cloud Run 整合得很好,而且有免費額度。
實作步驟
步驟 1:Google Cloud Console 設定
- 設定 OAuth 同意畫面
- 前往 OAuth 同意畫面 (https://console.cloud.google.com/apis/credentials/consent)。
- 使用者類型:選擇「外部」。
- 填寫應用程式名稱(例如 TG Helper Bot)、使用者支援電子郵件等資訊。
- 範圍:點擊「新增或移除範圍」,找到並加入 …/auth/drive.file。這個範圍代表「僅允許上傳由本應用程式建立的檔案」,是權限最小、最安全的選擇。
- 儲存並繼續。在「測試使用者」步驟中,將您自己的 Gmail 加入,這樣在應用程式發布前您才能進行測試。
- 建立 OAuth 2.0 用戶端 ID
- 前往 憑證頁面 (https://console.cloud.google.com/apis/credentials)。
- 點擊「建立憑證」 > 「OAuth 用戶端 ID」。
- 應用程式類型:選擇「網頁應用程式」。
- 已授權的重新導向 URI:這是最關鍵的一步。點擊「新增 URI」,然後輸入您的 Cloud Run 服務網址,並在後面加上一個回呼路徑,例如: https://tg-helper-xxxx-an.a.run.app/oauth/callback
- 點擊「建立」。
- 建立後,您會得到一組用戶端 ID (Client ID) 和用戶端密鑰 (Client Secret)。請將這兩者複製下來,它們非常重要。
步驟 2:啟用 Firestore 並安全地儲存密鑰
- 啟用 Firestore API
1 gcloud services enable firestore.googleapis.com
- 建立 Firestore 資料庫
- 前往 Firestore 主控台 (https://console.cloud.google.com/firestore)。
- 選擇「原生模式」(Native mode)。
- 選擇一個離您最近的位置。
- 建立資料庫。
- 安全地儲存 Client Secret 我們應該再次使用 Secret Manager 來儲存您在步驟 1-2 取得的 Client Secret。
1 # 將您的 Client Secret 貼在引號中 2 echo -n “YOUR_COPIED_CLIENT_SECRET” | gcloud secrets create tg-bot-client-secret –data-file=-
步驟 3:修改 Go 程式碼 (概念)
這將是一個較大的重構。我先不提供完整程式碼,而是描述邏輯上的變更:
- 新增
/connect_drive
指令處理:- 當收到此指令,程式會使用 Google 的 Go Auth 函式庫產生一個授權 URL。
- 這個 URL 會包含您的 Client ID、redirect_uri、scope,以及一個 state 參數。state 參數通常會包含該使用者的 Telegram ID,以便在回呼時能識別是誰。
- 機器人將此 URL 回傳給使用者。
- 新增
/oauth/callback
HTTP 處理器:- 這個函式會處理來自 Google 的重新導向。
- 它會從 URL 參數中取得 code 和 state。
- 驗證 state 以確保請求的合法性,並從中解析出 Telegram User ID。
- 使用 code 和您的 Client Secret 向 Google 交換權杖。
- 將 (Telegram User ID, Refresh Token) 這組對應關係存入 Firestore。
- 向使用者顯示一個「授權成功!」的簡單網頁。
- 重構
handleFile
函式:- 當收到檔案時,它會先用檔案傳送者的 Telegram User ID 去 Firestore 查詢。
- 如果找不到對應的 Refresh Token,就回覆訊息請使用者先執行 /connect_drive。
- 如果找到了,就用 Refresh Token 取得一個新的 Access Token。
- 用這個 Access Token 建立一個 Drive 服務,然後上傳檔案。