--- date: "2016-12-01T16:00:00+02:00" slug: "webhooks" sidebar_position: 30 aliases: - /zh-tw/webhooks --- # Webhooks Gitea 可以為儲存庫活動送出對外 Webhook。儲存庫層級的 Webhook 由儲存庫管理員 在 `/:username/:reponame/settings/hooks` 中設定。組織、使用者與系統管理層級 也有對應的 Webhook 設定頁面。 Webhook 設定支援四種範圍: - `儲存庫 Webhook`:只會對單一儲存庫中的活動觸發。 - `組織 Webhook`:對該組織擁有的儲存庫中的活動觸發。 - `使用者 Webhook`:對該使用者擁有的儲存庫中的活動觸發。 - `系統 Webhook`:對實例中所有符合條件的活動觸發。 Gitea 也支援由管理員定義的 `預設 Webhook`。它並不是額外的投遞範圍,而是會在 建立新儲存庫時被複製到該儲存庫中,之後就會像一般儲存庫 Webhook 一樣運作。 Gitea 支援以下對外 Webhook 整合: - Gitea - Gogs - Slack - Discord - Dingtalk - Telegram - Microsoft Teams - Feishu - Matrix - Wechatwork - Packagist `Gitea` 與 `Gogs` 類型會送出通用 Webhook payload。上面列出的聊天與服務整合 則會把同一個內部事件轉換成各自服務所需的請求主體格式。 本頁分成三個部分: - `設定`:如何設定 Webhook 選項,例如 URL、密鑰、分支過濾器與授權標頭。 - `投遞`:Gitea 如何送出 Webhook 請求、會附帶哪些標頭,以及如何驗證投遞。 - `事件`:Gitea 會投遞哪些事件,以及每個事件包含哪些頂層 payload 參數。 ## 設定 本節介紹在建立或編輯 Webhook 時可以設定的選項。 ### 設定 Webhook 建立 Webhook 時,主要設定項目包括: - `Target URL`:接收投遞的目標位址。 - `HTTP Method`:通用 Webhook 通常使用 `POST`。 - `POST Content Type`:通用 Webhook 可使用 `application/json` 或 `application/x-www-form-urlencoded`。 - `Secret`:用來對原始請求主體進行 HMAC 簽章。 - `Authorization Header`:可選的自訂 `Authorization` 標頭,會隨每次請求送出。 - `Branch Filter`:可選的分支或標籤過濾規則。 - `Trigger On`:`Push Events`、`All Events` 或自訂事件選擇。 - `Active`:是否啟用該 Webhook。 :::note 舊版範例中可能仍會在 JSON payload 裡看到 `secret` 欄位。當前版本的 Gitea 不會再把 Webhook 密鑰放進 payload 內容中。請務必透過簽章標頭驗證請求。 ::: ### 分支過濾器 分支過濾器使用與 [`github.com/gobwas/glob`](https://pkg.go.dev/github.com/gobwas/glob#Compile) 相容的 glob 語法。 - 空值、`*` 或 `**` 代表符合全部。 - 像 `main` 這樣的一般分支名稱會符合該分支。 - 也支援 `refs/tags/v*` 這類完整 ref。 - 支援 `{main,release/*}` 這類大括號表達式。 - 過濾器只會套用在帶有 git ref 的事件,例如 `create`、`delete` 與 `push`。 - 不帶 ref 的事件,例如 issue 或 release,會忽略分支過濾器。 範例: - `main` - `{main,feature/*}` - `{refs/heads/feature/*,refs/tags/release/*}` ### 授權標頭 Gitea 可以設定為在每次 Webhook 投遞時送出自訂的 [Authorization header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization)。 它與 Webhook 密鑰彼此獨立: - 使用密鑰透過 HMAC 驗證請求完整性。 - 當接收端需要應用層認證時,使用 `Authorization` 標頭。 ## 投遞 本節說明 Gitea 如何送出 Webhook 投遞,以及接收端如何識別與驗證這些請求。 ### 投遞行為 - Webhook 會透過 HTTP 非同步投遞。 - 通用 `Gitea` 與 `Gogs` Webhook 支援 `POST` 與 `GET`;通常應使用 `POST`。 - 對於 `POST` 請求,payload 可以直接以 JSON (`application/json`)送出,也可以放在名為 `payload` 的表單欄位中 (`application/x-www-form-urlencoded`)。 - 某些特定服務整合可能會使用該服務要求的 HTTP 方法與請求主體格式。 ### 投遞標頭 每次投遞都包含唯一的 delivery ID 與事件標頭。對於相容 GitHub 的整合, Gitea 也會同時送出對應的 GitHub 與 Gogs 風格標頭。 | 標頭 | 說明 | | --- | --- | | `X-Gitea-Delivery` | 本次投遞嘗試的唯一 UUID。 | | `X-Gitea-Event` | 規範化事件名稱,例如 `push`、`issues` 或 `pull_request`。 | | `X-Gitea-Event-Type` | 更具體的事件類型,例如 `issue_assign` 或 `pull_request_review_comment`。 | | `X-Gitea-Signature` | 原始請求主體的十六進位 HMAC-SHA256 值,不含前綴。 | | `X-Gitea-Hook-Installation-Target-Type` | Webhook 定義所在範圍,通常是 `repository`、`organization`、`user` 或 `system`。預設 Webhook 會先複製到儲存庫後再投遞,因此通常會呈現為 `repository`。 | | `X-Gogs-Delivery`、`X-Gogs-Event`、`X-Gogs-Event-Type`、`X-Gogs-Signature` | 與 Gitea 對應標頭值相同的相容性標頭。 | | `X-GitHub-Delivery`、`X-GitHub-Event`、`X-GitHub-Event-Type` | GitHub 風格相容性標頭。 | | `X-GitHub-Hook-Installation-Target-Type` | GitHub 風格的 Webhook 範圍標頭。 | | `X-Hub-Signature` | GitHub 相容的 HMAC-SHA1 標頭,格式為 `sha1=`。 | | `X-Hub-Signature-256` | GitHub 相容的 HMAC-SHA256 標頭,格式為 `sha256=`。 | 如果未設定密鑰,簽章標頭仍然會存在,但摘要值為空。 #### `Event` 與 `Event-Type` 某些 Gitea Webhook 訂閱會被歸類到同一個規範化事件名稱下。例如,issue 指派 投遞會歸類到 issue 事件群組: ```http X-Gitea-Event: issues X-Gitea-Event-Type: issue_assign X-GitHub-Event: issues X-GitHub-Event-Type: issue_assign ``` 如果你需要知道實際觸發投遞的具體事件類型,請使用 `X-Gitea-Event-Type`。 #### 驗證投遞 Gitea 會使用你的 Webhook 密鑰對原始請求主體進行簽章。要驗證一次投遞: 1. 以接收到的原始內容讀取請求主體。 2. 使用 Webhook 密鑰計算 HMAC-SHA256 摘要。 3. 將結果與 `X-Gitea-Signature` 或 GitHub 相容的 `X-Hub-Signature-256` 進行比較。 4. 盡量使用常數時間比較函式。 注意事項: - `X-Gitea-Signature` 只包含小寫十六進位的 SHA-256 摘要。 - `X-Hub-Signature-256` 使用相同摘要,但帶有 `sha256=` 前綴。 - `X-Hub-Signature` 也會為了相容性而送出,其演算法為 SHA-1。 - 在完成簽章驗證之前,不應先解析 JSON 或修改請求主體。 ##### PHP 範例 下面的範例示範如何驗證以 `application/json` 送出的通用 `Gitea` Webhook。 ```php