mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-05 13:29:44 +02:00
docs(autopilots): expand "where event name and action come from" with curl examples
Add concrete curl request/inference pairs under each derivation step
(body envelope, headers, body fallback, default) and a "common gotcha"
explaining why filter `event=trigger, action=true` does not match
`{"trigger": true}`. Mirrors the explanation that resolved the
on-call confusion about Event filter semantics.
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
@@ -125,25 +125,79 @@ Examples:
|
||||
|
||||
#### Where the event name and action come from
|
||||
|
||||
Multica derives `event` and `action` from the inbound request in this
|
||||
order — the first match wins:
|
||||
Multica derives the `event` name and `action` from the inbound request
|
||||
in this order — **the first match wins**.
|
||||
|
||||
1. **Body envelope** — if the body is a JSON object with an `event`
|
||||
string field, that value is the event name. An optional
|
||||
`eventPayload` object then provides `action` / `state` /
|
||||
`conclusion` / `status` candidates.
|
||||
2. **Headers** — `X-GitHub-Event: <event>` combined with body
|
||||
`action`; `X-Gitlab-Event: <event>`; `X-Event-Type: <event>` (passed
|
||||
through verbatim).
|
||||
3. **Body fallback** — top-level string `event` / `type` / `action`.
|
||||
4. **Default** — `webhook.received` if nothing above matches.
|
||||
**1. Body envelope.** If the body is a JSON object with a string
|
||||
`event` field, that value is the event name directly. An optional
|
||||
`eventPayload` object then supplies action candidates from its
|
||||
`action` / `state` / `conclusion` / `status` fields.
|
||||
|
||||
Action candidates come from the event-name suffix (`provider.event.<action>`)
|
||||
plus the body string fields `action`, `state`, `conclusion`, and
|
||||
`status`. **Non-string values don't qualify** — `{"action": true}` does
|
||||
not produce an action candidate. Trim values before saving; entries
|
||||
like `" workflow_run "` with surrounding whitespace are stored
|
||||
verbatim and will never match.
|
||||
```bash
|
||||
curl -X POST "$MULTICA_WEBHOOK_URL" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"event":"trigger","eventPayload":{"action":"true"}}'
|
||||
# inferred: event = trigger, action candidate = true
|
||||
```
|
||||
|
||||
**2. Headers.** When no body envelope is present, Multica reads the
|
||||
following well-known provider headers:
|
||||
|
||||
- `X-GitHub-Event: <event>` — combined with the top-level body
|
||||
`action` field (when present) to form `github.<event>.<action>`.
|
||||
- `X-Gitlab-Event: <event>` — becomes `gitlab.<event>`.
|
||||
- `X-Event-Type: <event>` — passed through verbatim.
|
||||
|
||||
```bash
|
||||
# GitHub-style: header gives the event name, body gives the action.
|
||||
curl -X POST "$MULTICA_WEBHOOK_URL" \
|
||||
-H 'X-GitHub-Event: workflow_run' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"action":"completed"}'
|
||||
# inferred: event = github.workflow_run.completed
|
||||
# → matches a filter row of workflow_run / completed
|
||||
|
||||
# Generic event-type header — no body fields needed.
|
||||
curl -X POST "$MULTICA_WEBHOOK_URL" \
|
||||
-H 'X-Event-Type: trigger.true' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{}'
|
||||
# inferred: event = trigger.true → matches trigger / true
|
||||
```
|
||||
|
||||
**3. Body fallback.** If neither a body envelope nor a known header is
|
||||
present, Multica falls back to top-level body string fields in this
|
||||
order: `event` → `type` → `action`.
|
||||
|
||||
```bash
|
||||
curl -X POST "$MULTICA_WEBHOOK_URL" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"type":"trigger","action":"true"}'
|
||||
# inferred: event = trigger (from `type`), action candidate = true
|
||||
```
|
||||
|
||||
**4. Default.** If nothing above matches, the event is
|
||||
`webhook.received` and there are no action candidates.
|
||||
|
||||
**Action candidates, in full.** Once the event is determined, Multica
|
||||
considers every value below as a possible action match:
|
||||
|
||||
- The event-name suffix, when the event has the form
|
||||
`provider.event.<action>` (e.g. `github.workflow_run.completed` →
|
||||
`completed`).
|
||||
- The body fields `action`, `state`, `conclusion`, and `status` —
|
||||
**only when they are JSON strings**. A boolean (`{"action": true}`)
|
||||
or a number does not qualify, so a filter expecting
|
||||
`event=trigger, action=true` will never match a body of
|
||||
`{"trigger": true}` because `true` is a bool, not a string.
|
||||
|
||||
**Common gotcha.** A filter row like `Event name: trigger` /
|
||||
`Actions: true` does **not** mean "fire when the body has
|
||||
`trigger: true`" — Event filters match the *inferred event and
|
||||
action*, not arbitrary body fields. Send `trigger.true` via
|
||||
`X-Event-Type` (or use the body envelope shown above) to hit it.
|
||||
Surrounding whitespace in saved filter rows (`" workflow_run "`) is
|
||||
stored verbatim and will never match — trim before saving.
|
||||
|
||||
#### Quick test
|
||||
|
||||
|
||||
@@ -120,21 +120,73 @@ curl -X POST "$MULTICA_WEBHOOK_URL" \
|
||||
|
||||
#### 事件名和 action 从哪来
|
||||
|
||||
Multica 按下面的顺序从入站请求里推断 `event` 和 `action`,**先命中先用**:
|
||||
Multica 按下面的顺序从入站请求里推断 `event` 和 `action`,**先命中先用**。
|
||||
|
||||
1. **Body envelope** —— 如果 body 是一个 JSON 对象、并且带
|
||||
`event: "<字符串>"` 字段,就用它。可选的 `eventPayload` 对象再
|
||||
提供 `action` / `state` / `conclusion` / `status` 候选。
|
||||
2. **请求头** —— `X-GitHub-Event: <event>` 配合 body `action`;
|
||||
`X-Gitlab-Event: <event>`;`X-Event-Type: <event>`(原样使用)。
|
||||
3. **Body 兜底** —— 顶层字符串 `event` / `type` / `action`。
|
||||
4. **默认值** —— 以上都没命中时取 `webhook.received`。
|
||||
**1. Body envelope。** 如果 body 是一个 JSON 对象、且带字符串字段
|
||||
`event`,就直接用它作为事件名。可选的 `eventPayload` 对象再
|
||||
从自己的 `action` / `state` / `conclusion` / `status` 字段里提供
|
||||
action 候选。
|
||||
|
||||
action 候选来自事件名后缀(`provider.event.<action>`)以及 body 里
|
||||
`action`、`state`、`conclusion`、`status` 这四个字符串字段。
|
||||
**非字符串值不算候选**——`{"action": true}` 不会被识别为 action。
|
||||
保存前请先 trim 掉首尾空格;`" workflow_run "` 这种带空白的值
|
||||
会被原样保存,但永远命中不了。
|
||||
```bash
|
||||
curl -X POST "$MULTICA_WEBHOOK_URL" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"event":"trigger","eventPayload":{"action":"true"}}'
|
||||
# 推断结果:event = trigger,action 候选 = true
|
||||
```
|
||||
|
||||
**2. 请求头。** 没有 body envelope 时按以下头部识别:
|
||||
|
||||
- `X-GitHub-Event: <event>` —— 结合 body 顶层的 `action` 字段
|
||||
(如果有),拼成 `github.<event>.<action>`。
|
||||
- `X-Gitlab-Event: <event>` —— 拼成 `gitlab.<event>`。
|
||||
- `X-Event-Type: <event>` —— 原样使用。
|
||||
|
||||
```bash
|
||||
# GitHub 风格:事件名来自 header,action 来自 body。
|
||||
curl -X POST "$MULTICA_WEBHOOK_URL" \
|
||||
-H 'X-GitHub-Event: workflow_run' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"action":"completed"}'
|
||||
# 推断结果:event = github.workflow_run.completed
|
||||
# → 命中 workflow_run / completed 的过滤规则
|
||||
|
||||
# 通用 event-type 头部 —— 不需要任何 body 字段。
|
||||
curl -X POST "$MULTICA_WEBHOOK_URL" \
|
||||
-H 'X-Event-Type: trigger.true' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{}'
|
||||
# 推断结果:event = trigger.true → 命中 trigger / true
|
||||
```
|
||||
|
||||
**3. Body 兜底。** Body envelope 和上面的 header 都没有时,
|
||||
从 body 顶层字符串字段里依次找:`event` → `type` → `action`。
|
||||
|
||||
```bash
|
||||
curl -X POST "$MULTICA_WEBHOOK_URL" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"type":"trigger","action":"true"}'
|
||||
# 推断结果:event = trigger(取自 `type`),action 候选 = true
|
||||
```
|
||||
|
||||
**4. 默认值。** 以上都没命中时,事件名取 `webhook.received`,
|
||||
没有 action 候选。
|
||||
|
||||
**action 候选的完整清单。** 事件名确定后,下面这些值都会被列为
|
||||
可能的 action:
|
||||
|
||||
- 事件名后缀,当事件形如 `provider.event.<action>` 时
|
||||
(例如 `github.workflow_run.completed` → `completed`)。
|
||||
- body 里 `action`、`state`、`conclusion`、`status` 这四个字段——
|
||||
**必须是 JSON 字符串**。布尔(`{"action": true}`)或数字都不算
|
||||
候选,所以 `event=trigger, action=true` 的过滤规则**永远命中不了**
|
||||
`{"trigger": true}` 这种 body,因为 `true` 是 bool 不是字符串。
|
||||
|
||||
**常见误区。** 一条 `Event name: trigger` / `Actions: true` 的规则
|
||||
**不是**「body 里出现 `trigger: true` 就放行」的意思——事件过滤匹配的是
|
||||
**推断出来的事件和 action**,不是任意 body 字段。要命中它,请用
|
||||
`X-Event-Type` 头发送 `trigger.true`,或者用上面的 body envelope。
|
||||
保存时带空格的值(例如 `" workflow_run "`)会被原样保存,但永远命中
|
||||
不了——保存前请先 trim。
|
||||
|
||||
#### 快速验证
|
||||
|
||||
|
||||
Reference in New Issue
Block a user