> ## Documentation Index
> Fetch the complete documentation index at: https://extension.js.org/llms.txt
> Use this file to discover all available pages before exploring further.

# 取得你的 Chrome Web Store 憑證

> 註冊 5 美元的 Chrome Web Store 開發者帳戶，手動建立第一個項目，並產生自動化提交所需的 OAuth 或服務帳戶憑證。

自動化提交到 Chrome Web Store 需要兩個識別碼與一組憑證：

| 值                    | 長什麼樣                                              | 從哪裡取得                                                       |
| -------------------- | ------------------------------------------------- | ----------------------------------------------------------- |
| Extension ID         | 32 個小寫字母，例如 `abcdefghijklmnopabcdefghijklmnop`    | 第一次手動上傳之後，開發者主控台裡該項目的 URL                                   |
| Publisher ID         | 一組 UUID，例如 `f1e2d3c4-0000-4000-8000-a1b2c3d4e5f6` | 你的開發者主控台 URL：`chrome.google.com/webstore/devconsole/<UUID>` |
| OAuth client ID      | 以 `.apps.googleusercontent.com` 結尾                | Google Cloud Console 的憑證頁面                                  |
| OAuth client secret  | 以 `GOCSPX-` 開頭                                    | 與 client ID 一起產生                                            |
| OAuth refresh token  | 以 `1//` 開頭                                        | 針對該 client ID 產生，見下文                                        |
| Service account JSON | 一個 JSON 金鑰檔                                       | Google Cloud Console，OAuth 三件組的替代方案                         |

OAuth 三件組與服務帳戶只需要其中之一，不必兩者都設。兩者都設定時，服務帳戶優先。

## 前置條件

<Warning>
  Chrome Web Store API 無法建立新項目。一個新擴充功能的第一次上傳，必須在開發者
  主控台（Developer Dashboard）中手動完成。那組 32 個字元的 extension ID，要到
  那次上傳之後才存在。
</Warning>

1. 在 [Chrome Web Store 開發者主控台](https://chrome.google.com/webstore/devconsole)
   註冊一個開發者帳戶。註冊需要一次性支付 5 美元。
2. 建置一個商店 zip（`npx extension build --browser chrome --zip`）。
3. 在主控台中手動上傳這個 zip，藉此建立該項目。
4. 從該項目的主控台 URL 中複製 extension ID。
5. 複製 publisher ID：它就是你開發者主控台 URL
   `chrome.google.com/webstore/devconsole/<UUID>` 裡的那組 UUID。

Extension.js 不會替你提交到任何商店，因此它從來不會向你索取這些值。
本頁講的是手動路徑：自己建立 OAuth 用戶端，自己產生 refresh token。

<Note>
  不要用 Google OAuth Playground 產生 refresh token。Playground 需要一個 Web
  application 類型的用戶端與它的重新導向 URI，而 Chrome Web Store 的流程需要
  Desktop app 類型的用戶端。把兩者湊在一起會以 `redirect_uri_mismatch` 失敗。
</Note>

## 建立 OAuth 用戶端

1. 在 [Google Cloud Console](https://console.cloud.google.com) 建立或選擇一個專案。
2. 為該專案啟用
   [Chrome Web Store API](https://console.cloud.google.com/apis/library/chromewebstore.googleapis.com)。
3. 在[憑證頁面](https://console.cloud.google.com/apis/credentials)建立一個
   OAuth client ID，應用程式類型選 **Desktop app**（桌面應用程式）。Web
   application 類型的用戶端在這裡行不通。
4. 複製 client ID 與 client secret。
5. 用 `127.0.0.1` 上的 loopback 同意流程為該用戶端產生一組 refresh token，
   這正是 Desktop app 類型用戶端接受的重新導向。該權杖必須取得
   `https://www.googleapis.com/auth/chromewebstore` 這個 scope 的授權。
   改用服務帳戶可以略過這一步，下一節會說明。

<Warning>
  如果你的 OAuth 同意畫面仍處於 **Testing**（測試）狀態，Google 會在 7 天後撤銷
  refresh token。你的第一次提交會成功，而這份憑證一週後就失效了。請把同意畫面
  發布出去（In production），或改用服務帳戶，服務帳戶沒有這種到期問題。
</Warning>

## 替代方案：服務帳戶

Google Cloud 服務帳戶完全避開 OAuth 同意流程，是 CI 場景中最穩定的選擇：

1. 在 Google Cloud Console 中，於那個已啟用 Chrome Web Store API 的同一個專案裡
   建立一個服務帳戶。
2. 為它建立一組 JSON 金鑰並下載該檔案。
3. 在 Chrome Web Store 開發者主控台中開啟 **Account**（帳戶），把這個服務帳戶的
   電子郵件地址加入你的發布者帳戶。一個發布者帳戶對應一個服務帳戶。

把 JSON 金鑰的內容（或指向該檔案的路徑）作為憑證提供。設定了服務帳戶時，
它會優先於 OAuth 三件組。

## 影響範圍與輪替

<Warning>
  Chrome 憑證是發布者帳戶層級的，而不是每個擴充功能各自獨立。一個能發布某個項目
  的權杖，也能發布同一個發布者帳戶底下的每一個項目。請據此看待 refresh token 與
  服務帳戶金鑰；如果你在替別人管理擴充功能，最好每個客戶各用一個獨立的發布者帳戶。
</Warning>

要輪替憑證，就產生一組新的 refresh token 或新的服務帳戶金鑰，並在存放它的地方
重新填入。

## 名稱對照

每個值對應的環境變數：

| 值                    | 環境變數                          |
| -------------------- | ----------------------------- |
| OAuth client ID      | `CHROME_CLIENT_ID`            |
| OAuth client secret  | `CHROME_CLIENT_SECRET`        |
| Refresh token        | `CHROME_REFRESH_TOKEN`        |
| Service account JSON | `CHROME_SERVICE_ACCOUNT_JSON` |
| Extension ID         | `CHROME_EXTENSION_ID`         |
| Publisher ID         | `CHROME_PUBLISHER_ID`         |

## 商店頁中繼資料仍然要手動填

Chrome Web Store API 不接受任何商店頁中繼資料。商店文案、截圖與權限說明都要在
開發者主控台中手動填寫。把它們放在 [STORE.md](/docs/workflows/store-metadata)
的 Chrome 小節裡，這樣每次重新提交都從同一份納入版本控制的來源複製。
