---
url: /zh/paas/system-hook.md
description: |
  说明 PAAS 版系统钩子的事件通知机制， 介绍如何配置回调地址接收平台事件推送， 支持资源变更与用户通知两种类型。
---
## 概述

系统钩子是平台提供的事件通知机制。当发生指定事件（如代码推送、Issue 变更、PR 操作、制品库变更等）时，
平台会向您预先配置的回调地址发送 HTTP POST 请求，将事件内容推送至您的系统。
您只需提供一个可接收 POST 请求的回调接口，即可实时获取事件通知。

系统钩子支持两种类型：

| 类型 | 说明 | 请求体格式 |
|------|------|-----------|
| **资源变更**（Resource Change） | 推送完整的资源变更事件数据，包含仓库、Issue、PR 等结构化信息 | `HookRequestBody` JSON |
| **用户通知**（User Notify） | 推送格式化的通知消息，适配企业微信等即时通讯工具 | `ReqSentMessageCard` JSON |

## 配置说明

登录 Admin 管理平台，依次点击「后台管理 → 系统钩子配置 → 新建系统钩子」进入配置页面。

配置参数如下：

| 参数名 | 类型 | 必选 | 说明 |
|:------:|:----:|:----:|------|
| 链接（URL） | String | 是 | 回调地址，接收事件通知的 HTTP(S) 接口 |
| 类型（Type） | Enum | 是 | `资源变更` 或 `用户通知` |
| 触发（Setting） | String | 是 | 订阅的事件类型，支持多选，逗号分隔 |
| 令牌（Token） | String | 否 | 鉴权令牌，配置后会通过 `X-CNB-Token` 请求头传递，用于验证请求来源 |

## 支持的事件类型

平台当前支持以下事件（事件名称即回调中的 `event_name` 字段值）：

### 仓库事件

| 事件名称 | 说明 |
|----------|------|
| `repo_archive` | 归档仓库 |
| `repo_default_branch_change` | 仓库默认分支变更 |
| `repo_update` | 更新仓库 |
| `repo_delete` | 删除仓库 |
| `repo_transfer` | 仓库转移 |
| `repo_non_compliant` | 仓库内容不合规 |
| `repo_member_role_change` | 仓库成员角色变更 |
| `repo_push` | 代码推送 |

### Issue 事件

| 事件名称 | 说明 |
|----------|------|
| `issue_opened` | Issue 新建 |
| `issue_comment_add` | Issue 新增评论 |
| `issue_assignee_add` | Issue 新增指派人 |
| `issue_status_change` | Issue 状态变更（打开/关闭/重新打开） |

### Pull Request 事件

| 事件名称 | 说明 |
|----------|------|
| `pull_request_opened` | PR 新建 |
| `pull_request_comment_add` | PR 新增评论 |
| `pull_request_assignee_add` | PR 新增指派人 |
| `pull_request_reviewer_add` | PR 新增审核人 |
| `pull_request_status_change` | PR 状态变更（合并/关闭/重新打开） |
| `pull_request_review_add` | PR 新增评审（仅评论/通过/需要改进） |

### 组织事件

| 事件名称 | 说明 |
|----------|------|
| `organization_delete` | 删除组织 |
| `organization_transfer` | 组织转移 |
| `organization_member_role_change` | 组织成员角色变更 |

### CI 事件

| 事件名称 | 说明 |
|----------|------|
| `ci_notice` | CI 通知（仅构建失败时触发） |

### 用户事件

| 事件名称 | 说明 |
|----------|------|
| `at_users` | @用户（出现在 Issue/PR 内容或评论中） |
| `user_notify` | 用户通知（系统自定义通知消息） |

### 制品库事件

| 事件名称 | 说明 |
|----------|------|
| `registry_create` | 制品库创建 |
| `registry_delete` | 制品库删除 |
| `artifact_push` | 制品推送 |
| `artifact_delete` | 制品删除 |
| `artifact_enable` | 制品启用 |
| `artifact_disable` | 制品禁用 |

## 回调请求说明

事件触发时，平台会向您的回调地址发送 POST 请求。

### 1. 请求头

| 字段 | 值 | 说明 |
|------|-----|------|
| `Content-Type` | `application/json;charset=utf-8` | 固定值，请求体为 JSON 格式 |
| `X-CNB-Event` | `System Hook` | 固定值，标识此为系统钩子事件 |
| `X-CNB-Token` | `${token}` | 选填，仅在配置了鉴权令牌时出现，用于验证请求来源 |

### 2. 请求体结构

#### 资源变更类型（Resource Change）

请求体为 JSON 数组，每个元素是一个 `HookRequestBody` 对象，核心结构如下：

```text
{
  "event_name": "事件类型",
  "user": {
    "id": "用户ID",
    "username": "用户名",
    "nickname": "用户昵称",
    "email": "邮箱",
    "type": 1,
    "access": "DEVELOPER"
  },
  "repo": { "/* 仓库信息 */" },
  "group": { "/* 组织信息 */" },
  "issue": { "/* Issue信息 */" },
  "pull_request": { "/* PR信息 */" },
  "pull_request_review": { "/* PR评审信息 */" },
  "at_users_position": "at_issue",
  "comment": { "/* 评论信息 */" },
  "commit": { "/* 提交信息 */" },
  "oci_build": { "/* CI构建信息 */" },
  "registry": { "/* 制品库信息 */" },
  "content": "通知内容",
  "NotifyUsers": [ "/* 需通知的用户列表 */" ]
}
```

> **注意**：业务字段按事件类型按需出现，并非所有字段同时存在。
> `event_name`、`user`、`NotifyUsers` 为通用字段。

#### 用户通知类型（User Notify）

请求体为 `ReqSentMessageCard` 格式，适配企业微信消息接口：

```json
{
  "touser": "UserID1|UserID2|UserID3",
  "msgtype": "text",
  "text": {
    "content": "通知消息内容"
  }
}
```

| 字段 | 说明 |
|------|------|
| `touser` | 接收消息的用户 ID 列表，多个用 `\|` 分隔，最多 1000 个 |
| `msgtype` | 消息类型，固定为 `text` |
| `text.content` | 消息内容，最长 2048 字节 |

## 数据结构详细说明

### 通用字段

| 字段 | 类型 | 说明 |
|------|------|------|
| `event_name` | String | 必填，事件类型（对应上述事件列表） |
| `user` | Object | 必填，触发事件的用户信息 |
| `NotifyUsers` | Array | 必填，需通知的用户列表 |

### 用户信息结构（user / NotifyUsers 元素）

| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | String | 用户唯一标识 |
| `username` | String | 用户名 |
| `nickname` | String | 用户昵称 |
| `email` | String | 邮箱 |
| `type` | Integer | 用户类型（0-微信用户 / 1-OAuth用户 / 2-测试用户 / 3-机器人 / 4-IOA用户） |
| `access` | String | 用户在资源下的权限角色（`GUEST` / `REPORTER` / `DEVELOPER` / `MASTER` / `OWNER`） |
| `old_access` | String | 旧权限角色（仅成员角色变更事件） |

### 仓库信息结构（repo）

| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | String | 仓库 ID |
| `name` | String | 仓库名称 |
| `path` | String | 仓库完整路径（如 `group/repo`） |
| `old_path` | String | 仓库旧路径（仅转移事件） |
| `description` | String | 仓库描述 |
| `visibility_level` | String | 可见性（`private` / `public` / `secret`） |
| `status` | String | 仓库状态（`active` / `archived`） |
| `web_url` | String | 仓库 Web 地址 |
| `star_count` | Integer | Star 数 |
| `fork_count` | Integer | Fork 数 |
| `created_at` | String | 创建时间（RFC3339） |
| `updated_at` | String | 更新时间（RFC3339） |

### 组织信息结构（group）

| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | String | 组织 ID |
| `name` | String | 组织名称 |
| `path` | String | 组织完整路径 |
| `old_path` | String | 组织旧路径（仅转移事件） |
| `description` | String | 组织描述 |
| `remark` | String | 组织备注 |
| `site` | String | 组织网站 |
| `email` | String | 组织邮箱 |
| `member_count` | Integer | 成员数 |
| `created_at` | String | 创建时间（RFC3339） |

### Issue 信息结构（issue）

| 字段 | 类型 | 说明 |
|------|------|------|
| `number` | Integer | Issue 编号 |
| `title` | String | Issue 标题 |
| `state` | String | 状态（`reopen` / `closed` / `created`） |
| `priority` | String | 优先级 |
| `label` | Array | 标签列表，每项含 `name`、`description`、`color` |
| `associated_pull_request_counts` | Integer | 关联 PR 数 |
| `comment_counts` | Integer | 评论数 |
| `comment_id` | Integer | 评论 ID（仅评论事件） |

### PR 信息结构（pull\_request）

| 字段 | 类型 | 说明 |
|------|------|------|
| `number` | Integer | PR 编号 |
| `title` | String | PR 标题 |
| `state` | String | 状态（`merged` / `closed` / `reopen` / `created` / `submitted`） |
| `src_ref` | String | 源分支 |
| `target_ref` | String | 目标分支 |
| `build_status` | String | CI 构建状态 |
| `mergeable_state` | String | 可合并状态 |
| `label` | Array | 标签列表 |
| `associated_issue_counts` | Integer | 关联 Issue 数 |
| `comment_counts` | Integer | 评论数 |

### PR 评审信息结构（pull\_request\_review）

| 字段 | 类型 | 说明 |
|------|------|------|
| `reviewer_id` | Integer | 评审人 ID |
| `review_state` | String | 评审状态（`commented` / `approved` / `changes_requested`） |

### 评论信息结构（comment）

| 字段 | 类型 | 说明 |
|------|------|------|
| `comment_id` | Integer | 评论 ID |

### 提交信息结构（commit，仅 `repo_push` 事件）

| 字段 | 类型 | 说明 |
|------|------|------|
| `pusher` | Object | 推送者信息（含 `username`、`nickname`、`user_email`） |
| `commits` | Array | 提交列表，每项含 `id`、`message`、`timestamp`、`author`、`committer` |

### CI 构建信息结构（oci\_build，仅 `ci_notice` 事件）

| 字段 | 类型 | 说明 |
|------|------|------|
| `progress_type` | String | 执行类型（`build`） |
| `status` | String | 执行状态（仅 `fail` 时触发） |
| `duration` | String | 执行耗时 |
| `build_data` | Object | 构建详情，含 `event`、`sn`、`build_log_url`、`repo_name`、`event_url`、`ref_type`、`ref_diff`、`ref_url`、`commit_message_title` |
| `pipeline_data` | Object | 流水线详情，含 `pipeline_id`、`pipeline_name`、`success_pipeline_count`、`all_pipeline_count`、`pipeline_fail_msg` |

### 制品库信息结构（registry）

| 字段 | 类型 | 说明 |
|------|------|------|
| `name` | String | 制品库名称 |
| `registry_type` | String | 制品库类型（如 `docker` / `helm` / `docker-model` 等） |
| `description` | String | 制品库描述 |
| `visibility_level` | String | 可见性 |
| `path` | String | 制品库路径 |
| `pkg_name` | String | 制品包名（仅制品事件） |
| `pkg_version` | String | 制品版本（仅制品事件） |

### @用户事件附加字段

| 字段 | 类型 | 说明 |
|------|------|------|
| `at_users_position` | String | @出现的位置：`at_issue` / `at_issue_comment` / `at_pull_request` / `at_pull_request_comment` |

## 回调示例

### 示例 1：代码推送（repo\_push）

```json
[
  {
    "event_name": "repo_push",
    "user": {
      "id": "1001",
      "username": "zhangsan",
      "nickname": "张三",
      "email": "zhangsan@example.com",
      "type": 1,
      "access": "OWNER"
    },
    "repo": {
      "id": "2001",
      "name": "cnb-platform",
      "path": "cnb/cnb-platform",
      "description": "CNB 平台",
      "visibility_level": "private",
      "status": "active",
      "web_url": "https://cnb.cool/cnb/cnb-platform",
      "star_count": 10,
      "fork_count": 3
    },
    "commit": {
      "pusher": {
        "username": "zhangsan",
        "nickname": "张三",
        "user_email": "zhangsan@example.com"
      },
      "commits": [
        {
          "id": "abc123def456",
          "message": "fix: 修复系统钩子推送逻辑",
          "timestamp": "2025-12-12T10:00:00Z",
          "author": {
            "name": "张三",
            "email": "zhangsan@example.com",
            "when": "2025-12-12T10:00:00Z",
            "username": "zhangsan"
          }
        }
      ]
    },
    "NotifyUsers": [
      {
        "id": "1001",
        "username": "zhangsan",
        "nickname": "张三"
      }
    ]
  }
]
```

### 示例 2：Issue 状态变更（issue\_status\_change）

```json
[
  {
    "event_name": "issue_status_change",
    "user": {
      "id": "1001",
      "username": "zhangsan",
      "nickname": "张三",
      "type": 1,
      "access": "DEVELOPER"
    },
    "repo": {
      "id": "2001",
      "name": "cnb-platform",
      "path": "cnb/cnb-platform",
      "web_url": "https://cnb.cool/cnb/cnb-platform"
    },
    "issue": {
      "number": 42,
      "title": "修复登录页面样式问题",
      "state": "closed",
      "priority": "P1",
      "label": [
        {
          "name": "bug",
          "description": "",
          "color": "#FF0000"
        }
      ],
      "associated_pull_request_counts": 1,
      "comment_counts": 3
    },
    "NotifyUsers": [
      {
        "id": "1002",
        "username": "alice",
        "nickname": "Alice"
      }
    ]
  }
]
```

### 示例 3：PR 新建（pull\_request\_opened）

```json
[
  {
    "event_name": "pull_request_opened",
    "user": {
      "id": "1001",
      "username": "zhangsan",
      "nickname": "张三",
      "type": 1,
      "access": "DEVELOPER"
    },
    "repo": {
      "id": "2001",
      "name": "cnb-platform",
      "path": "cnb/cnb-platform",
      "web_url": "https://cnb.cool/cnb/cnb-platform"
    },
    "pull_request": {
      "number": 15,
      "title": "feat: 新增系统钩子文档",
      "state": "created",
      "src_ref": "feature/hooks-doc",
      "target_ref": "main",
      "build_status": "",
      "mergeable_state": "MERGEABLE",
      "label": [],
      "associated_issue_counts": 0,
      "comment_counts": 0
    },
    "NotifyUsers": [
      {
        "id": "1003",
        "username": "admin",
        "nickname": "管理员"
      }
    ]
  }
]
```

### 示例 4：仓库成员角色变更（repo\_member\_role\_change）

```json
[
  {
    "event_name": "repo_member_role_change",
    "user": {
      "id": "1003",
      "username": "admin",
      "nickname": "管理员",
      "type": 1,
      "access": "OWNER"
    },
    "repo": {
      "id": "2001",
      "name": "cnb-platform",
      "path": "cnb/cnb-platform",
      "web_url": "https://cnb.cool/cnb/cnb-platform"
    },
    "NotifyUsers": [
      {
        "id": "1001",
        "username": "zhangsan",
        "nickname": "张三",
        "access": "DEVELOPER",
        "old_access": "REPORTER"
      }
    ]
  }
]
```

### 示例 5：制品推送（artifact\_push）

```json
[
  {
    "event_name": "artifact_push",
    "user": {
      "id": "1001",
      "username": "zhangsan",
      "nickname": "张三",
      "type": 1,
      "access": "OWNER"
    },
    "registry": {
      "name": "cnb-platform",
      "registry_type": "docker",
      "path": "cnb/cnb-platform",
      "visibility_level": "private",
      "pkg_name": "cnb-platform/v1.0.0",
      "pkg_version": "v1.0.0"
    },
    "NotifyUsers": [
      {
        "id": "1001",
        "username": "zhangsan",
        "nickname": "张三"
      }
    ]
  }
]
```

### 示例 6：用户通知类型回调（User Notify）

```json
{
  "touser": "1001|1002",
  "msgtype": "text",
  "text": {
    "content": "zhangsan 批准了 PR #15\n\nfeat: 新增系统钩子文档\nhttps://cnb.cool/cnb/cnb-platform/-/pulls/15"
  }
}
```

## 接入注意事项

1. **接口要求**：回调地址需支持 POST 请求，且能正确解析 JSON 格式请求体。
2. **响应要求**：处理完成后请返回 HTTP 200 OK 状态码，避免平台重复推送。
3. **安全建议**：若配置了 `X-CNB-Token`，请验证该字段以确保请求来自平台。
4. **配置回调**：如需设置/修改回调地址，请联系平台管理员或通过 Admin 管理平台操作。
5. **数据格式**：
   * **资源变更**类型的请求体为 **JSON 数组**（`[{...}]`），即使只有一条事件也是数组。
   * **用户通知**类型的请求体为 **JSON 对象**（`{...}`）。
6. **CI 通知**：`ci_notice` 事件仅在**构建失败**时触发，不会推送构建成功的通知。
7. **成员角色变更**：派生（继承）的成员变更不会触发钩子，仅直接变更才触发。
