diff --git a/flashduty/en/1. On-call/2. Incidents/2.2 View Incidents.md b/flashduty/en/1. On-call/2. Incidents/2.2 View Incidents.md
index ab3a9d47..82a5ecec 100644
--- a/flashduty/en/1. On-call/2. Incidents/2.2 View Incidents.md
+++ b/flashduty/en/1. On-call/2. Incidents/2.2 View Incidents.md
@@ -24,7 +24,7 @@ Flashduty provides two entry points to view the incident list: one within the ch
8. **Pagination Settings**: Adjust page numbers and items per page.
:::highlight orange 💡
-For performance reasons, when search conditions match more than **1000** incidents, the system only shows 1000+, rather than an exact number. Therefore, you can only view 1000 incidents through pagination. If you need to view more, please adjust your search time interval or use the [Incident Query](https://developer-en.flashcat.cloud/api-110655782) API to get all data.
+For performance reasons, when search conditions match more than **1000** incidents, the system only shows 1000+, rather than an exact number. Therefore, you can only view 1000 incidents through pagination. If you need to view more, please adjust your search time interval or use the [Incident Query](https://docs.flashcat.cloud/en/api-reference/on-call/incidents/incident-list) API to get all data.
:::
### Using Group Views
diff --git a/flashduty/en/1. On-call/2. Incidents/2.6 Custom Actions.md b/flashduty/en/1. On-call/2. Incidents/2.6 Custom Actions.md
index e525eb64..db9c4457 100644
--- a/flashduty/en/1. On-call/2. Incidents/2.6 Custom Actions.md
+++ b/flashduty/en/1. On-call/2. Incidents/2.6 Custom Actions.md
@@ -33,4 +33,4 @@ After creation, you can find the action button under [Incident Details-More Acti
### How to implement webhook?
-Visit [Webhook Getting Started](https://developer-en.flashcat.cloud/doc-2996930) to learn more.
\ No newline at end of file
+Visit [Webhook Getting Started](https://docs.flashcat.cloud/en/on-call/integration/webhooks/incident-webhook) to learn more.
\ No newline at end of file
diff --git a/flashduty/en/1. On-call/4. Configure On-call/4.5 Label Enrichment.md b/flashduty/en/1. On-call/4. Configure On-call/4.5 Label Enrichment.md
index 4c11bc31..64ce4080 100644
--- a/flashduty/en/1. On-call/4. Configure On-call/4.5 Label Enrichment.md
+++ b/flashduty/en/1. On-call/4. Configure On-call/4.5 Label Enrichment.md
@@ -33,7 +33,7 @@ Each alert event in the integration center has label enrichment configuration op
### Types of Label Enrichment
- **Extract:** Using regular expressions to extract needed information from alert titles, detailed descriptions, and existing label fields to automatically generate additional labels.
- **Compose:** Composition rules can build new labels using Go template syntax, extracting label values with {{.Labels.Field}} format or generating new labels using fixed values.
-- **Map:** Maps source key-value pairs to new key-value pairs through mapping relationships. Requires pre-creating [schema](https://developer-en.flashcat.cloud/api-142409927) mapping relationships and [uploading metadata](https://developer-en.flashcat.cloud/api-145679479) before configuration. See configuration examples below.
+- **Map:** Maps source key-value pairs to new key-value pairs through mapping relationships. Requires pre-creating [schema](https://docs.flashcat.cloud/en/api-reference/on-call/alert-enrichment/mapping-schema-write-create) mapping relationships and [uploading metadata](https://docs.flashcat.cloud/en/api-reference/on-call/alert-enrichment/mapping-data-write-upsert) before configuration. See configuration examples below.
- **Delete:** Removes labels with specified names. If the label to be deleted doesn't exist, the operation is ineffective.

@@ -132,6 +132,6 @@ In the mapping table details page, you can manage the mapping table data, includ
::: tip
-If you do not want the source label to exist, you can achieve this through the delete rule. Also, label mapping supports API management, which can be referred to [Label Mapping API](https://developer-en.flashcat.cloud/api-142429470).
+If you do not want the source label to exist, you can achieve this through the delete rule. Also, label mapping supports API management, which can be referred to [Label Mapping API](https://docs.flashcat.cloud/en/api-reference/on-call/alert-enrichment/mapping-data-write-upsert).
:::
\ No newline at end of file
diff --git a/flashduty/en/1. On-call/6. Advanced/6.1 Referencing Variables.md b/flashduty/en/1. On-call/6. Advanced/6.1 Referencing Variables.md
index 44721fd4..31e11544 100644
--- a/flashduty/en/1. On-call/6. Advanced/6.1 Referencing Variables.md
+++ b/flashduty/en/1. On-call/6. Advanced/6.1 Referencing Variables.md
@@ -10,7 +10,7 @@ url: "https://docs.flashcat.cloud/en/flashduty/customize-incident-attrs"
By referencing alert labels and attributes, you can customize incident severity and title information. This feature is mainly used in the following two scenarios:
-1. When reporting custom alert events using the [Alert Event API](https://developer-en.flashcat.cloud/en/flashduty/event-api/alert-event?nav=01JCQ7A4N4WRWNXW8EWEHXCMF5), you can use the `title_rule` field to customize the alert title.
+1. When reporting custom alert events using the [Alert Event API](https://docs.flashcat.cloud/en/on-call/integration/alert-integration/alert-sources/standard alert), you can use the `title_rule` field to customize the alert title.
```
# Example: Specify resource and check labels as alert title
diff --git a/flashduty/en/1. On-call/6. Advanced/6.3 Insights.md b/flashduty/en/1. On-call/6. Advanced/6.3 Insights.md
index fc51adb3..b5d3d71a 100644
--- a/flashduty/en/1. On-call/6. Advanced/6.3 Insights.md
+++ b/flashduty/en/1. On-call/6. Advanced/6.3 Insights.md
@@ -77,14 +77,14 @@ Export incident list data in CSV format, supporting incident list, team, channel
#### Export Limitations
-- Incident list exports exclude Labels data; for more detailed data, use the [Incident List](https://developer-en.flashcat.cloud/api-110655782) API.
+- Incident list exports exclude Labels data; for more detailed data, use the [Incident List](https://docs.flashcat.cloud/en/api-reference/on-call/incidents/incident-list) API.
- Maximum query and export limit is 100,000 records; for more data, export in time segments.
### FAQ
How to query older data?
- The insights dashboard currently supports querying last 180 days of data. For older data, use the [API query](https://developer-en.flashcat.cloud/api-213441443).
+ The insights dashboard currently supports querying last 180 days of data. For older data, use the [API query](https://docs.flashcat.cloud/en/api-reference/on-call/analytics/insight-incident-list).
diff --git a/flashduty/en/1. On-call/8. Integrations/8.1 Alerts integration/8.1.0 Standard Alert Integration.md b/flashduty/en/1. On-call/8. Integrations/8.1 Alerts integration/8.1.0 Standard Alert Integration.md
index 271e4529..01902c17 100644
--- a/flashduty/en/1. On-call/8. Integrations/8.1 Alerts integration/8.1.0 Standard Alert Integration.md
+++ b/flashduty/en/1. On-call/8. Integrations/8.1 Alerts integration/8.1.0 Standard Alert Integration.md
@@ -89,7 +89,7 @@ Field|Required|Type|Description
Field|Required|Type|Description
:-:|:-:|:-:|:---
| alt | No | string | Image alternative text, limit 128 characters, truncated if exceeded.
-| src | Yes | string | Image source, value: http/https URL or image_key returned by [Image Upload API](https://developer.flashcat.cloud/api-344943718). Limit 256 characters, discarded if exceeded
+| src | Yes | string | Image source, value: http/https URL or image_key returned by Image Upload API. Limit 256 characters, discarded if exceeded
| href | No | string | Hyperlink reference path, limit 256 characters, truncated if exceeded
diff --git a/flashduty/en/1. On-call/8. Integrations/8.1 Alerts integration/8.1.60 Http Pull Alert Integration.md b/flashduty/en/1. On-call/8. Integrations/8.1 Alerts integration/8.1.60 Http Pull Alert Integration.md
new file mode 100644
index 00000000..41456e37
--- /dev/null
+++ b/flashduty/en/1. On-call/8. Integrations/8.1 Alerts integration/8.1.60 Http Pull Alert Integration.md
@@ -0,0 +1,225 @@
+---
+title: "HTTP Pull alert integration"
+description: "Ingest alert events by periodically pulling from an external HTTP endpoint, ideal for systems that cannot push alerts."
+---
+
+**Plan requirement**: HTTP Pull integration requires a Pro or higher On-call plan.
+
+Flashduty supports two alert ingestion modes: **Push** and **Pull**. Most integrations use the push mode, where the external monitoring system actively sends alerts to Flashduty. However, some systems do not support webhook push, or alert data can only be retrieved through an API query.
+
+HTTP Pull integration is designed for these scenarios — you simply provide an HTTP endpoint that returns alert data in JSON format, and Flashduty will periodically pull the data on a schedule you define, converting it into standard alert events for processing.
+
+## Use cases
+
+- The monitoring system only provides a query API and does not support webhook push
+- Alert data is stored in a database or object storage and must be queried via an HTTP endpoint
+- A custom system cannot be retrofitted for push mode yet, and you want to integrate quickly via pull
+
+## Configuration steps
+
+
+
+Go to the Flashduty console, navigate to **Integration Center → Alert Events**, search for and select the **HTTP Pull** integration.
+
+
+
+Configure the parameters Flashduty uses when making requests to your endpoint:
+
+| Parameter | Required | Description |
+| :--- | :--- | :--- |
+| **URL** | Yes | Target HTTP endpoint URL. Only `http` and `https` are supported. Supports [template variables](#template-variables) |
+| **Method** | No | Request method, `GET` or `POST`. Defaults to `GET`. Body cannot be set when using GET |
+| **Headers** | No | Custom request headers in key-value format. For security reasons, sensitive headers such as `Authorization` and `Cookie` are not allowed |
+| **Body** | No | Request body, only available for POST. Supports [template variables](#template-variables) and must be valid JSON |
+| **Timeout** | No | Per-request timeout, 1–10 seconds. Defaults to 5 seconds |
+| **RetryCount** | No | Number of retries on failure, 0–2. Defaults to 1 |
+
+
+
+
+Set the **pull cycle (cycle_seconds)** — how often data is pulled. Minimum is 30 seconds, default is 300 seconds (5 minutes).
+
+
+
+If the severity values returned by your endpoint differ from Flashduty's standard, use **severity_mapping** to map them.
+
+For example, if your system uses `high` / `medium` / `low`, you can map them to Flashduty's `Critical` / `Warning` / `Info`.
+
+
+
+If your endpoint supports pagination, configure pagination parameters to retrieve complete data. See [Pagination configuration](#pagination-configuration) for details.
+
+
+
+After saving, the integration will automatically pull data on the configured schedule. You can also manually trigger a pull from the integration details page.
+
+
+
+## Response format requirements
+
+
+
+Your HTTP endpoint must meet the following requirements:
+
+1. **Return an HTTP 200 status code**
+2. **Content-Type must contain `json`** (e.g., `application/json`)
+3. **The response body must be JSON and contain an `items` array**
+
+Each element in `items` corresponds to one alert event. The fields are consistent with the [standard alert event](/en/on-call/integration/alert-integration/alert-sources/standard%20alert) protocol:
+
+```json
+{
+ "items": [
+ {
+ "event_status": "Warning",
+ "title_rule": "CPU idle lower than 20%",
+ "alert_key": "host-01::cpu-idle",
+ "description": "Host host-01 CPU idle is 15%",
+ "labels": {
+ "host": "host-01",
+ "check": "cpu.idle",
+ "metric": "node_cpu_seconds_total"
+ }
+ },
+ {
+ "event_status": "Ok",
+ "alert_key": "host-02::cpu-idle"
+ }
+ ]
+}
+```
+
+### Event field reference
+
+| Field | Required | Type | Description |
+| :--- | :--- | :--- | :--- |
+| event_status | Yes | string | Alert status. Enum (capitalized): `Critical`, `Warning`, `Info`, `Ok` (recovery) |
+| title_rule | Yes | string | Alert title, up to 512 characters |
+| alert_key | No | string | Alert identifier for updating or recovering existing alerts. Up to 255 characters; auto-generated if not specified |
+| description | No | string | Alert description, up to 2048 characters |
+| labels | No | map | Alert label collection in key-value format. Up to 50 labels |
+
+
+A maximum of 100 events are processed per page, and up to 2000 events in total across all pages per pull. Excess events are truncated and recorded in the pull history.
+
+
+## Template variables
+
+
+
+URL and Body support Go `text/template` syntax. The following variables are available to dynamically generate request content:
+
+| Variable | Type | Description |
+| :--- | :--- | :--- |
+| `{{.LastPullTime}}` | int64 | Last pull time (Unix timestamp in seconds) |
+| `{{.NowTime}}` | int64 | Current time (Unix timestamp in seconds) |
+| `{{.LastPullTimeISO}}` | string | Last pull time (ISO 8601 format, e.g., `2026-05-13T06:00:00Z`) |
+| `{{.NowTimeISO}}` | string | Current time (ISO 8601 format) |
+| `{{.CursorValue}}` | string | Pagination cursor value, empty for the first page |
+
+### Examples
+
+Using time range parameters in the URL:
+
+```
+https://api.example.com/alerts?start={{.LastPullTime}}&end={{.NowTime}}
+```
+
+Using ISO-formatted time in the Body:
+
+```json
+{
+ "start_time": "{{.LastPullTimeISO}}",
+ "end_time": "{{.NowTimeISO}}"
+}
+```
+
+## Pagination configuration
+
+
+
+If your endpoint cannot return all data in a single response, you can configure cursor-based pagination.
+
+| Parameter | Description |
+| :--- | :--- |
+| **mode** | Pagination mode. Currently supports `cursor` |
+| **max_pages** | Maximum number of pages to pull. Defaults to 20 |
+| **next_value_path** | Path to extract the next-page cursor value from the response JSON, using [gjson](https://github.com/tidwall/gjson) syntax. For example, `pagination.next_cursor` |
+| **param_name** | Pagination parameter name, e.g., `cursor` or `page_token` |
+| **inject_to** | Where to inject the pagination parameter: `query` (append to URL query string) or `body` (merge into request body JSON) |
+
+### Pagination workflow
+
+
+
+Flashduty sends the first request without pagination parameters.
+
+
+
+The next-page cursor value is extracted from the response JSON using `next_value_path`.
+
+
+
+The cursor value is injected into the next request using `param_name` as the key, either in the query string or the body.
+
+
+
+Pagination stops when `next_value_path` returns no value, the response contains an empty array, or the `max_pages` limit is reached.
+
+
+
+### Pagination response example
+
+```json
+{
+ "items": [
+ { "event_status": "Critical", "title_rule": "Disk full", "alert_key": "disk-01" }
+ ],
+ "pagination": {
+ "next_cursor": "eyJpZCI6MTAwfQ=="
+ }
+}
+```
+
+With `next_value_path` set to `pagination.next_cursor`, the system will automatically use `eyJpZCI6MTAwfQ==` as the parameter value for the next page request.
+
+## FAQ
+
+
+
+For security reasons, Flashduty (non-private deployment) does not allow access to private network addresses (e.g., `127.0.0.1`, `10.x.x.x`, `192.168.x.x`). Ensure your endpoint is accessible from the public internet.
+
+This restriction does not apply to private deployment versions.
+
+
+
+In the integration details page under **Pull History**, you can view the results of each pull execution, including status, number of events pulled, error messages, and more.
+
+
+
+Check the following:
+
+1. Confirm the JSON response contains an `items` array and it is not empty.
+2. Confirm each event has `event_status` and `title_rule` fields.
+3. If you use `alert_key`, check whether the alert is a duplicate — events with identical status and content are deduplicated and discarded.
+4. Check if any drop rules, inhibit rules, or silence rules are matching.
+
+For more information, see [Noise reduction](/en/on-call/channel/noise-reduction).
+
+
+
+Yes. Click the manual trigger button on the integration details page. Manual triggers have a 60-second cooldown and cannot run concurrently with an ongoing scheduled pull.
+
+
+
+If your system uses custom severity identifiers (e.g., `P1`, `high`), you can configure mapping rules in the integration settings. For example:
+
+| Your value | Flashduty value |
+| :--- | :--- |
+| P1 | Critical |
+| P2 | Warning |
+| P3 | Info |
+
+Values that do not match any mapping are processed as-is.
+
+
diff --git a/flashduty/en/1. On-call/8. Integrations/8.2 Change integration/8.2.1 Standard Change Event.md b/flashduty/en/1. On-call/8. Integrations/8.2 Change integration/8.2.1 Standard Change Event.md
index 79c4eabf..76bdad7f 100644
--- a/flashduty/en/1. On-call/8. Integrations/8.2 Change integration/8.2.1 Standard Change Event.md
+++ b/flashduty/en/1. On-call/8. Integrations/8.2 Change integration/8.2.1 Standard Change Event.md
@@ -26,7 +26,7 @@ Flashduty has already adapted webhook protocols for several commonly used ticket
## Implementation Protocol
---
-Please refer to the [Developer Documentation](https://developer-en.flashcat.cloud/en/flashduty/event-api/change-event) to complete the protocol development.
+Please refer to the [Developer Documentation](https://docs.flashcat.cloud/en/on-call/integration/change-integration/custom-event) to complete the protocol development.
## Best Practices
---
diff --git a/flashduty/en/3. Monitors/2. Alert Rules/999-description-template-manual.md b/flashduty/en/3. Monitors/2. Alert Rules/999-description-template-manual.md
new file mode 100644
index 00000000..c76744ad
--- /dev/null
+++ b/flashduty/en/3. Monitors/2. Alert Rules/999-description-template-manual.md
@@ -0,0 +1,560 @@
+# Alert Rule Description Template Manual
+
+This document describes the variables and functions available in the alert rule
+`Description` field.
+
+The `Description` field is rendered by Go `text/template`. Template syntax such
+as `{{ ... }}`, `if`, `range`, variable assignment, pipelines, and comparison
+operators follows Go template rules.
+
+## Basic Syntax
+
+Use `{{ ... }}` to render a value:
+
+```gotemplate
+Current value: {{ printf "%.2f" $value }}
+```
+
+Use `if` for conditional output:
+
+```gotemplate
+{{- if eq $status "firing" }}
+Alert is firing.
+{{- else }}
+Alert has recovered.
+{{- end }}
+```
+
+Use `range` to iterate over a list:
+
+```gotemplate
+{{- range $row := $relates.R1 }}
+- message: {{ $row.Fields._msg }}
+{{- end }}
+```
+
+For map keys that contain special characters such as `.`, `/`, `-`, or `$`, use
+the built-in `index` function:
+
+```gotemplate
+{{ index $labels "service.name" }}
+{{ index $values "$A.latency" }}
+{{ index $row.Fields "log.message" }}
+```
+
+## Built-in Variables
+
+The following short variables are injected before the user template is rendered.
+
+| Variable | Type | Description |
+| --- | --- | --- |
+| `$labels` | `map[string]string` | Labels of the alerting data point. Alias of `.DataLabels`. |
+| `$values` | `map[string]float64` | Numeric values used by the alert evaluation. Alias of `.Values`. |
+| `$value` | `float64` | Main alert value. Alias of `.Value`. |
+| `$appendLabels` | `map[string]string` | Extra labels configured on the rule after label interpolation. Alias of `.AppendLabels`. |
+| `$annotations` | `map[string]string` | Rule annotations after label interpolation. Alias of `.Annotations`. |
+| `$dsType` | `string` | Data source type. Alias of `.DataSourceType`. |
+| `$dsName` | `string` | Data source name. Alias of `.DataSourceName`. |
+| `$dsAddress` | `string` | Data source address without credentials. Alias of `.DataSourceAddress`. |
+| `$checkMode` | `string` | Check mode, for example `threshold`, `anydata`, or `nodata`. Alias of `.CheckMode`. |
+| `$relates` | `map[string][]*ResultRow` | Related query results, keyed by related query name. Alias of `.Relates`. |
+| `$status` | `string` | Event status: `firing` or `recovered`. Alias of `.Status`. |
+| `$severity` | `string` | Alert severity, for example `Critical`, `Warning`, or `Info`. Alias of `.Severity`. |
+
+Examples:
+
+```gotemplate
+{{- if eq $status "firing" }}
+{{ $dsName }} triggered {{ $severity }} with value {{ printf "%.2f" $value }}.
+{{- else }}
+{{ $dsName }} recovered.
+{{- end }}
+```
+
+```gotemplate
+Instance: {{ index $labels "instance" }}
+Value A: {{ getvalue $values "$A" "%.2f" }}
+```
+
+## Root Event Fields
+
+The template root object is the full alert event. These fields can be accessed
+with `.FieldName`.
+
+| Field | Type | Description |
+| --- | --- | --- |
+| `.Hash` | `string` | Stable event hash. Firing and recovery events share the same hash. |
+| `.DataSourceType` | `string` | Data source type. |
+| `.DataSourceName` | `string` | Data source name. |
+| `.DataSourceAddress` | `string` | Data source address without credentials. |
+| `.RuleName` | `string` | Alert rule name. |
+| `.RuleID` | `uint64` | Alert rule ID. |
+| `.Queries` | `[]Query` | Rule query definitions. |
+| `.RelateQueries` | `[]RelateQuery` | Related query definitions. |
+| `.CheckMode` | `string` | Check mode. |
+| `.DataLabels` | `map[string]string` | Alert labels. |
+| `.AppendLabels` | `map[string]string` | Extra labels configured on the rule. |
+| `.EnrichLabels` | `map[string]string` | Labels returned by enrichment. This is usually empty while rendering `Description`, because enrichment happens after description rendering. |
+| `.Values` | `map[string]float64` | Numeric values used by alert evaluation. |
+| `.Annotations` | `map[string]string` | Rule annotations. |
+| `.Relates` | `map[string][]*ResultRow` | Related query result rows. |
+| `.Status` | `string` | `firing` or `recovered`. |
+| `.Severity` | `string` | Alert severity. |
+| `.EvalTime` | `int64` | Evaluation timestamp in Unix seconds. |
+| `.Description` | `string` | Rendered description. This is set after template execution. |
+| `.DescriptionType` | `string` | Description type, for example `text` or `markdown`. |
+| `.Value` | `float64` | Main alert value. |
+| `.TitleRule` | `string` | Title rule configured on the edge. |
+| `.DebugLogEnabled` | `bool` | Whether debug logging is enabled for this rule. This field is mainly for internal diagnostics. |
+| `.LogPrefix` | `string` | Internal log prefix for this evaluation. This field is mainly for internal diagnostics. |
+
+Example:
+
+```gotemplate
+Rule {{ .RuleID }} / {{ .RuleName }} fired on {{ .DataSourceName }}.
+```
+
+`Query` objects in `.Queries` have the following fields:
+
+| Field | Type | Description |
+| --- | --- | --- |
+| `.Name` | `string` | Query name, usually `A`, `B`, `C`, and so on. |
+| `.Expr` | `string` | Query expression. |
+| `.LabelFields` | `[]string` | Fields used as labels. |
+| `.ValueFields` | `[]string` | Fields used as numeric values. |
+| `.Args` | `map[string]string` | Extra query arguments for data sources that require them. |
+
+`RelateQuery` objects in `.RelateQueries` have the following fields:
+
+| Field | Type | Description |
+| --- | --- | --- |
+| `.Name` | `string` | Related query name, such as `R1`. |
+| `.Expr` | `string` | Related query expression. |
+| `.Args` | `map[string]string` | Extra query arguments for data sources that require them. |
+
+## Related Query Rows
+
+Related query results are available through `$relates`. The map key is the
+related query name, such as `R1`.
+
+Each row has:
+
+| Field or Method | Type | Description |
+| --- | --- | --- |
+| `$row.Fields` | `map[string]interface{}` | Non-numeric or display fields returned by the related query. |
+| `$row.Values` | `map[string]float64` | Numeric fields returned by the related query. |
+| `$row.Field "name"` | `interface{}` | Returns one field from `$row.Fields`. |
+| `$row.Value` | `float64` | Returns the first numeric value in `$row.Values`, or `NaN` if no value exists. |
+| `$row.Value "name"` | `float64` | Returns one numeric value from `$row.Values`, or `NaN` if the key does not exist. |
+| `$row.String` | `string` | Returns a debug-style string representation of the row. |
+
+Examples:
+
+```gotemplate
+{{- range $row := $relates.R1 }}
+- msg: {{ $row.Fields._msg }}
+- count: {{ printf "%.0f" ($row.Value "count") }}
+{{- end }}
+```
+
+```gotemplate
+{{- range $row := $relates.R1 }}
+ {{- $msg := printf "%v" ($row.Field "_msg") }}
+ {{- if sprig_contains "Unknown column" $msg }}
+ {{- $field := sprig_regexReplaceAll ".*Unknown column '([^']+)'.*" $msg "$1" }}
+- Missing field: {{ $field }}
+ {{- end }}
+{{- end }}
+```
+
+## Go Template Built-in Functions
+
+These functions are provided by Go `text/template`.
+
+| Function | Description | Example |
+| --- | --- | --- |
+| `and` | Boolean AND. Evaluation stops when the result is known. | `{{ if and $a $b }}yes{{ end }}` |
+| `or` | Boolean OR. Evaluation stops when the result is known. | `{{ if or $a $b }}yes{{ end }}` |
+| `not` | Boolean NOT. | `{{ if not $ok }}failed{{ end }}` |
+| `eq` | Equal. | `{{ if eq $status "firing" }}...{{ end }}` |
+| `ne` | Not equal. | `{{ if ne $severity "Info" }}...{{ end }}` |
+| `lt` | Less than. | `{{ if lt $value 10.0 }}...{{ end }}` |
+| `le` | Less than or equal. | `{{ if le $value 10.0 }}...{{ end }}` |
+| `gt` | Greater than. | `{{ if gt $value 10.0 }}...{{ end }}` |
+| `ge` | Greater than or equal. | `{{ if ge $value 10.0 }}...{{ end }}` |
+| `index` | Reads an item from a map, slice, or array. | `{{ index $labels "instance" }}` |
+| `slice` | Slices a string, slice, or array. | `{{ slice "abcdef" 0 3 }}` |
+| `len` | Returns length. | `{{ len $relates.R1 }}` |
+| `printf` | Formats text with `fmt.Sprintf` syntax. | `{{ printf "%.2f" $value }}` |
+| `print` | Concatenates values with default formatting. | `{{ print $dsName ":" $status }}` |
+| `println` | Like `print`, with a trailing newline. | `{{ println $dsName }}` |
+| `call` | Calls a function value. Rarely needed in descriptions. | `{{ call .SomeFunc }}` |
+| `html` | Escapes text for HTML. | `{{ html $text }}` |
+| `js` | Escapes text for JavaScript. | `{{ js $text }}` |
+| `urlquery` | Escapes text for URL query usage. | `{{ urlquery $text }}` |
+
+## monit-edge Custom Functions
+
+These functions are registered by monit-edge without a prefix.
+
+| Function | Description | Example |
+| --- | --- | --- |
+| `pathEscape text` | URL path escaping. | `{{ pathEscape "a/b c" }}` |
+| `queryEscape text` | URL query escaping. | `{{ queryEscape "level=error msg" }}` |
+| `getvalue values key [format]` | Reads a numeric value from a `map[string]float64` and formats it. Default format is `%.4f`. Returns `template_function_error: ...` text if the key is invalid or missing. | `{{ getvalue $values "$A" "%.2f" }}` |
+| `getfvalue values key` | Reads a numeric value from a `map[string]float64`. Returns `NaN` if the key is invalid or missing. | `{{ if gt (getfvalue $values "$A") 10.0 }}high{{ end }}` |
+| `trunc count text` | Alias of `truncRune`. Truncates by Unicode characters, not bytes. Negative count keeps characters from the end. | `{{ trunc 10 $msg }}` |
+| `truncRune count text` | Truncates by Unicode characters. | `{{ truncRune -8 "abcdef你好" }}` |
+| `runeCount text` | Counts Unicode characters. | `{{ runeCount "你好abc" }}` |
+| `args ...` | Builds a map with keys `arg0`, `arg1`, and so on. Mainly useful when composing helper calls. | `{{ args "a" 1 }}` |
+| `reReplaceAll pattern repl text` | Regex replacement. Argument order is `pattern`, `replacement`, `text`. Invalid regex will fail rendering. | `{{ reReplaceAll ".*id=([0-9]+).*" "$1" $msg }}` |
+| `safeHtml text` | Marks text as HTML-safe. For normal text or markdown descriptions, avoid this unless HTML output is expected. | `{{ safeHtml "OK" }}` |
+| `match pattern text` | Regex match. Equivalent to Go `regexp.MatchString`. Invalid regex will fail rendering. | `{{ if match "Unknown column" $msg }}...{{ end }}` |
+| `toUpper text` | Converts text to uppercase. | `{{ toUpper $severity }}` |
+| `toLower text` | Converts text to lowercase. | `{{ toLower $status }}` |
+| `stripPort hostPort` | Removes port from `host:port`. If parsing fails, returns the original value. | `{{ stripPort "example.com:9100" }}` |
+| `stripDomain hostPort` | Removes domain suffix from hostname while preserving port. IP addresses are returned unchanged. | `{{ stripDomain "node01.prod.local:9100" }}` |
+| `humanize value` | Formats a number using SI units. | `{{ humanize 12345 }}` |
+| `humanize1024 value` | Formats a number using base-1024 units. | `{{ humanize1024 1048576 }}` |
+| `humanizeDuration seconds` | Formats seconds as a readable duration. | `{{ humanizeDuration 3661 }}` |
+| `humanizePercentage value` | Formats a ratio as a percentage. `0.1234` becomes `12.34%`. | `{{ humanizePercentage 0.95 }}` |
+| `humanizeTimestamp seconds` | Converts a Unix timestamp in seconds to UTC time text. | `{{ humanizeTimestamp .EvalTime }}` |
+| `toTime seconds` | Converts a Unix timestamp in seconds to a `time.Time`. | `{{ (toTime .EvalTime).Format "2006-01-02 15:04:05" }}` |
+| `nanoTime value [tzOffset]` | Converts a Unix nanosecond timestamp to `time.Time`. Optional timezone offset is in hours. | `{{ (nanoTime $row.Fields.__time__ 8).Format "2006-01-02 15:04:05" }}` |
+| `timeFormat value format [tzOffset]` | Formats a `time.Time`, `*time.Time`, RFC3339 string, or RFC3339Nano string. Optional timezone offset is in hours. | `{{ timeFormat "2026-01-06T11:48:12Z" "2006-01-02 15:04:05" 8 }}` |
+| `parseDuration duration` | Parses a duration string and returns seconds. Supported units follow monit-edge duration parsing. | `{{ parseDuration "5m" }}` |
+| `add a b` | Numeric addition. | `{{ add 1 2 }}` |
+| `sub a b` | Numeric subtraction. | `{{ sub 10 3 }}` |
+| `mul a b` | Numeric multiplication. | `{{ mul $value 100 }}` |
+| `div a b` | Numeric division. Division by zero fails rendering. | `{{ div $value 1024 }}` |
+| `now` | Current time as `time.Time`. | `{{ now.Format "2006-01-02 15:04:05" }}` |
+| `toString value` | Converts a value to string using `fmt.Sprint`. | `{{ toString $row.Fields._msg }}` |
+
+## Sprig Functions
+
+monit-edge also registers Sprig functions, but every Sprig function is prefixed
+with `sprig_`.
+
+For example, use:
+
+```gotemplate
+{{ sprig_contains "error" $msg }}
+{{ sprig_regexMatch "Unknown column" $msg }}
+{{ sprig_regexFind "Unknown column '[^']+'" $msg }}
+```
+
+Do not use unprefixed Sprig names such as `contains`, `regexMatch`, or
+`regexFind`; those names are not registered.
+
+Important regex note: `sprig_regexFind` returns the full matched substring. It
+does not return a capture group. To extract a capture group, use
+`sprig_regexReplaceAll`:
+
+```gotemplate
+{{- $msg := "Unknown column 'community_posts.comment_count' in 'field list'" }}
+{{- sprig_regexReplaceAll ".*Unknown column '([^']+)'.*" $msg "$1" }}
+```
+
+The result is:
+
+```text
+community_posts.comment_count
+```
+
+### Common Sprig Functions
+
+| Function | Description | Example |
+| --- | --- | --- |
+| `sprig_contains substr text` | Checks whether `text` contains `substr`. | `{{ if sprig_contains "Unknown column" $msg }}...{{ end }}` |
+| `sprig_hasPrefix prefix text` | Checks prefix. | `{{ sprig_hasPrefix "prod-" $name }}` |
+| `sprig_hasSuffix suffix text` | Checks suffix. | `{{ sprig_hasSuffix ".log" $file }}` |
+| `sprig_regexMatch pattern text` | Regex match. | `{{ sprig_regexMatch "error|failed" $msg }}` |
+| `sprig_regexFind pattern text` | Returns the first full regex match. | `{{ sprig_regexFind "trace_id=[a-z0-9]+" $msg }}` |
+| `sprig_regexFindAll pattern text n` | Returns up to `n` full regex matches. Use `-1` for all. | `{{ sprig_regexFindAll "id=[0-9]+" $msg -1 }}` |
+| `sprig_regexReplaceAll pattern text repl` | Regex replacement. Argument order is `pattern`, `text`, `replacement`. | `{{ sprig_regexReplaceAll ".*id=([0-9]+).*" $msg "$1" }}` |
+| `sprig_trim text` | Trims leading and trailing whitespace. | `{{ sprig_trim $msg }}` |
+| `sprig_lower text` | Lowercase. | `{{ sprig_lower $severity }}` |
+| `sprig_upper text` | Uppercase. | `{{ sprig_upper $severity }}` |
+| `sprig_default default value` | Uses a default value when `value` is empty. | `{{ sprig_default "unknown" (index $labels "instance") }}` |
+| `sprig_toJson value` | Converts a value to JSON. | `{{ sprig_toJson $labels }}` |
+| `sprig_dict ...` | Creates a dictionary. | `{{ sprig_dict "name" $dsName "status" $status }}` |
+| `sprig_list ...` | Creates a list. | `{{ sprig_list "a" "b" "c" }}` |
+
+### Complete Sprig Function Names
+
+The following names are available in the current monit-edge build:
+
+```text
+sprig_abbrev
+sprig_abbrevboth
+sprig_add
+sprig_add1
+sprig_add1f
+sprig_addf
+sprig_adler32sum
+sprig_ago
+sprig_all
+sprig_any
+sprig_append
+sprig_atoi
+sprig_b32dec
+sprig_b32enc
+sprig_b64dec
+sprig_b64enc
+sprig_base
+sprig_bcrypt
+sprig_biggest
+sprig_buildCustomCert
+sprig_camelcase
+sprig_cat
+sprig_ceil
+sprig_chunk
+sprig_clean
+sprig_coalesce
+sprig_compact
+sprig_concat
+sprig_contains
+sprig_date
+sprig_dateInZone
+sprig_dateModify
+sprig_date_in_zone
+sprig_date_modify
+sprig_decryptAES
+sprig_deepCopy
+sprig_deepEqual
+sprig_default
+sprig_derivePassword
+sprig_dict
+sprig_dig
+sprig_dir
+sprig_div
+sprig_divf
+sprig_duration
+sprig_durationRound
+sprig_empty
+sprig_encryptAES
+sprig_env
+sprig_expandenv
+sprig_ext
+sprig_fail
+sprig_first
+sprig_float64
+sprig_floor
+sprig_fromJson
+sprig_genCA
+sprig_genCAWithKey
+sprig_genPrivateKey
+sprig_genSelfSignedCert
+sprig_genSelfSignedCertWithKey
+sprig_genSignedCert
+sprig_genSignedCertWithKey
+sprig_get
+sprig_getHostByName
+sprig_gt
+sprig_gte
+sprig_has
+sprig_hasKey
+sprig_hasPrefix
+sprig_hasSuffix
+sprig_hello
+sprig_htmlDate
+sprig_htmlDateInZone
+sprig_htpasswd
+sprig_indent
+sprig_initial
+sprig_initials
+sprig_int
+sprig_int64
+sprig_isAbs
+sprig_join
+sprig_kebabcase
+sprig_keys
+sprig_kindIs
+sprig_kindOf
+sprig_last
+sprig_list
+sprig_lower
+sprig_lt
+sprig_lte
+sprig_max
+sprig_maxf
+sprig_merge
+sprig_mergeOverwrite
+sprig_min
+sprig_minf
+sprig_mod
+sprig_mul
+sprig_mulf
+sprig_mustAppend
+sprig_mustChunk
+sprig_mustCompact
+sprig_mustDateModify
+sprig_mustDeepCopy
+sprig_mustFirst
+sprig_mustFromJson
+sprig_mustHas
+sprig_mustInitial
+sprig_mustLast
+sprig_mustMerge
+sprig_mustMergeOverwrite
+sprig_mustPrepend
+sprig_mustPush
+sprig_mustRegexFind
+sprig_mustRegexFindAll
+sprig_mustRegexMatch
+sprig_mustRegexReplaceAll
+sprig_mustRegexReplaceAllLiteral
+sprig_mustRegexSplit
+sprig_mustRest
+sprig_mustReverse
+sprig_mustSlice
+sprig_mustToDate
+sprig_mustToJson
+sprig_mustToPrettyJson
+sprig_mustToRawJson
+sprig_mustUniq
+sprig_mustWithout
+sprig_must_date_modify
+sprig_nindent
+sprig_nospace
+sprig_now
+sprig_omit
+sprig_osBase
+sprig_osClean
+sprig_osDir
+sprig_osExt
+sprig_osIsAbs
+sprig_pick
+sprig_pluck
+sprig_plural
+sprig_prepend
+sprig_push
+sprig_quote
+sprig_randAlpha
+sprig_randAlphaNum
+sprig_randAscii
+sprig_randBytes
+sprig_randInt
+sprig_randNumeric
+sprig_regexFind
+sprig_regexFindAll
+sprig_regexMatch
+sprig_regexQuoteMeta
+sprig_regexReplaceAll
+sprig_regexReplaceAllLiteral
+sprig_regexSplit
+sprig_repeat
+sprig_replace
+sprig_rest
+sprig_reverse
+sprig_round
+sprig_semver
+sprig_semverCompare
+sprig_seq
+sprig_set
+sprig_sha1sum
+sprig_sha256sum
+sprig_sha512sum
+sprig_shuffle
+sprig_slice
+sprig_snakecase
+sprig_sortAlpha
+sprig_split
+sprig_splitList
+sprig_splitn
+sprig_squote
+sprig_sub
+sprig_subf
+sprig_substr
+sprig_swapcase
+sprig_ternary
+sprig_title
+sprig_toDate
+sprig_toDecimal
+sprig_toJson
+sprig_toPrettyJson
+sprig_toRawJson
+sprig_toString
+sprig_toStrings
+sprig_trim
+sprig_trimAll
+sprig_trimPrefix
+sprig_trimSuffix
+sprig_trimall
+sprig_trunc
+sprig_tuple
+sprig_typeIs
+sprig_typeIsLike
+sprig_typeOf
+sprig_uniq
+sprig_unixEpoch
+sprig_unset
+sprig_until
+sprig_untilStep
+sprig_untitle
+sprig_upper
+sprig_urlJoin
+sprig_urlParse
+sprig_uuidv4
+sprig_values
+sprig_without
+sprig_wrap
+sprig_wrapWith
+```
+
+Some Sprig functions can read environment variables, generate random data, do
+network lookup, or generate cryptographic material. They are available because
+Sprig is registered as-is with the `sprig_` prefix, but alert descriptions
+should normally prefer deterministic string, regex, math, date, JSON, dict, and
+list functions.
+
+## Complete Example: Extract MySQL Unknown Column
+
+The following template extracts the missing column name from related log rows.
+
+```gotemplate
+{{- if eq $status "firing" }}
+在过去5分钟的时间内,数据库操作出现缺失字段错误 {{ $value | printf "%.0f" }} 次;
+{{- range $x := $relates.R1 }}
+ {{- $msg := printf "%v" $x.Fields._msg }}
+ {{- if sprig_contains "Unknown column" $msg }}
+ {{- $field := sprig_regexReplaceAll ".*Unknown column '([^']+)'.*" $msg "$1" }}
+
+- 缺失字段:{{ $field }}
+- 查看地址:https://example.com/logs?query={{ queryEscape "Unknown column" }}
+ {{- end }}
+{{- end }}
+{{- else }}
+数据库缺字段错误已恢复
+{{- end }}
+```
+
+## Troubleshooting
+
+If rendering fails with:
+
+```text
+function "contains" not defined
+```
+
+the template is using an unprefixed Sprig function. Use `sprig_contains`
+instead.
+
+If rendering fails with:
+
+```text
+function "regexFind" not defined
+```
+
+use `sprig_regexFind`.
+
+If the extracted value contains the whole matched text instead of only the
+capture group, replace `sprig_regexFind` with `sprig_regexReplaceAll` and use
+`$1`, `$2`, and so on in the replacement string.
+
+If a map key cannot be read with dot syntax, use `index`:
+
+```gotemplate
+{{ index $labels "service.name" }}
+{{ index $x.Fields "_msg" }}
+```
diff --git a/flashduty/en/3. Monitors/2. FAQ/1. FAQ.md b/flashduty/en/3. Monitors/3. FAQ/1. FAQ.md
similarity index 100%
rename from flashduty/en/3. Monitors/2. FAQ/1. FAQ.md
rename to flashduty/en/3. Monitors/3. FAQ/1. FAQ.md
diff --git a/flashduty/en/5. Platform/1. Teams and Members.md b/flashduty/en/5. Platform/1. Teams and Members.md
index 088e74a8..4fcfb432 100644
--- a/flashduty/en/5. Platform/1. Teams and Members.md
+++ b/flashduty/en/5. Platform/1. Teams and Members.md
@@ -46,7 +46,7 @@ After deletion, other associated paths will become invalid immediately and canno
### Invitation Methods
- The console only supports email invitations, with the username defaulting to the email prefix, which can be modified in account settings after activation
-- You can send invitations through [Open API](https://developer-en.flashcat.cloud/api-110655699), which supports phone invitations
+- You can send invitations through [Open API](https://docs.flashcat.cloud/en/api-reference/platform/members/member-invite), which supports phone invitations
- The system will send SMS or email to invited colleagues, with a daily invitation limit of 200 people and a maximum of 10 people per invitation
- Additionally, you can contact the organization administrator to configure SSO, where new member accounts are created automatically upon login
- After sending an invitation, the account will be activated upon the recipient's login. Unactivated accounts cannot receive alert notifications
diff --git "a/flashduty/zh/1. On-call/3. \346\225\205\351\232\234\347\256\241\347\220\206/2. \346\243\200\347\264\242\344\270\216\346\237\245\347\234\213\346\225\205\351\232\234.md" "b/flashduty/zh/1. On-call/3. \346\225\205\351\232\234\347\256\241\347\220\206/2. \346\243\200\347\264\242\344\270\216\346\237\245\347\234\213\346\225\205\351\232\234.md"
index ed1ef9c4..2b561804 100644
--- "a/flashduty/zh/1. On-call/3. \346\225\205\351\232\234\347\256\241\347\220\206/2. \346\243\200\347\264\242\344\270\216\346\237\245\347\234\213\346\225\205\351\232\234.md"
+++ "b/flashduty/zh/1. On-call/3. \346\225\205\351\232\234\347\256\241\347\220\206/2. \346\243\200\347\264\242\344\270\216\346\237\245\347\234\213\346\225\205\351\232\234.md"
@@ -24,7 +24,7 @@ Flashduty 提供了两个入口查看故障列表。一个是协作空间内,
8. **分页设置**:分页和单页条数调整。
:::highlight orange 💡
-为了提升性能,当检索条件匹配到超过 **1000** 条故障,系统仅展示1000+,而不是精确的数字。因此,您通过跳页,也只能查看1000条故障,如果需要查看更多,请调整你的检索时间区间。或通过 [故障查询](https://developer.flashcat.cloud/api-110655782) API 获取全部数据。
+为了提升性能,当检索条件匹配到超过 **1000** 条故障,系统仅展示1000+,而不是精确的数字。因此,您通过跳页,也只能查看1000条故障,如果需要查看更多,请调整你的检索时间区间。或通过 [故障查询](https://docs.flashcat.cloud/zh/api-reference/on-call/incidents/incident-list) API 获取全部数据。
:::
### 使用聚合视图
@@ -69,7 +69,7 @@ Flashduty 提供各种维度的筛选能力,并给您足够多的灵活度。
2. **操作区域**:各类高频操作按钮,在更多操作中,包含了自定义操作和低频操作按钮,其中创建作战室需要在IM集成中开启[作战室](https://docs.flashcat.cloud/zh/flashduty/war-room)。
3. **详细信息**:故障的描述、标签信息,其中AI总结可以快速提炼故障详情,并以事件概况、影响范围、可行措施三个维度进行输出,标签内容支持拖拽排序和以JSON视图展示。
4. **关联告警**:故障所关联的所有被[聚合](https://docs.flashcat.cloud/zh/flashduty/noise-reduction-settings)的告警,支持按处理进度筛选,以及支持视图切换。
-5. **综合信息**:展示该故障的属性、处理状态、[图片](https://developer.flashcat.cloud/api-344943718)以及处理人员信息。
+5. **综合信息**:展示该故障的属性、处理状态、图片以及处理人员信息。
6. **自定义字段**:自定义字段配置区域。
您可以切换上方 Tab 页,查看更详细的 **关联告警**,**时间线**,以及 **历史变更**,用于故障根因定位。对于已关闭的故障,系统还会展示 **问题修复** 页面,用于展示故障的根因和解决办法。
diff --git "a/flashduty/zh/1. On-call/3. \346\225\205\351\232\234\347\256\241\347\220\206/6. \350\207\252\345\256\232\344\271\211\346\223\215\344\275\234.md" "b/flashduty/zh/1. On-call/3. \346\225\205\351\232\234\347\256\241\347\220\206/6. \350\207\252\345\256\232\344\271\211\346\223\215\344\275\234.md"
index 858c308d..eb6cf1af 100644
--- "a/flashduty/zh/1. On-call/3. \346\225\205\351\232\234\347\256\241\347\220\206/6. \350\207\252\345\256\232\344\271\211\346\223\215\344\275\234.md"
+++ "b/flashduty/zh/1. On-call/3. \346\225\205\351\232\234\347\256\241\347\220\206/6. \350\207\252\345\256\232\344\271\211\346\223\215\344\275\234.md"
@@ -34,4 +34,4 @@ url: "https://docs.flashcat.cloud/zh/flashduty/custom-actions"
### 如何实现 webhook?
-前往 [Webhook 入门](https://developer.flashcat.cloud/doc-2996930)。了解更多。
\ No newline at end of file
+前往 [Webhook 入门](https://docs.flashcat.cloud/zh/on-call/integration/webhooks/incident-webhook)。了解更多。
\ No newline at end of file
diff --git "a/flashduty/zh/1. On-call/3. \351\205\215\347\275\256\347\256\241\347\220\206/4.5 \351\205\215\347\275\256\346\240\207\347\255\276\345\242\236\345\274\272.md" "b/flashduty/zh/1. On-call/3. \351\205\215\347\275\256\347\256\241\347\220\206/4.5 \351\205\215\347\275\256\346\240\207\347\255\276\345\242\236\345\274\272.md"
index 8f71fed7..d72edd0a 100644
--- "a/flashduty/zh/1. On-call/3. \351\205\215\347\275\256\347\256\241\347\220\206/4.5 \351\205\215\347\275\256\346\240\207\347\255\276\345\242\236\345\274\272.md"
+++ "b/flashduty/zh/1. On-call/3. \351\205\215\347\275\256\347\256\241\347\220\206/4.5 \351\205\215\347\275\256\346\240\207\347\255\276\345\242\236\345\274\272.md"
@@ -133,6 +133,6 @@ Flashduty 故障详情中的故障标签以 key:value 的形式展示告警的
::: tip
-如果不希望源标签还存在,可以通过删除规则实现。以及标签映射也支持API进行管理,具体可以参考[标签映射API](https://developer.flashcat.cloud/api-142429470)。
+如果不希望源标签还存在,可以通过删除规则实现。以及标签映射也支持API进行管理,具体可以参考[标签映射API](https://docs.flashcat.cloud/zh/api-reference/on-call/alert-enrichment/mapping-data-write-upsert)。
:::
\ No newline at end of file
diff --git "a/flashduty/zh/1. On-call/3. \351\205\215\347\275\256\347\256\241\347\220\206/4.7 \351\205\215\347\275\256\351\200\232\347\237\245\346\250\241\346\235\277.md" "b/flashduty/zh/1. On-call/3. \351\205\215\347\275\256\347\256\241\347\220\206/4.7 \351\205\215\347\275\256\351\200\232\347\237\245\346\250\241\346\235\277.md"
index d4e9e66f..53a009dd 100644
--- "a/flashduty/zh/1. On-call/3. \351\205\215\347\275\256\347\256\241\347\220\206/4.7 \351\205\215\347\275\256\351\200\232\347\237\245\346\250\241\346\235\277.md"
+++ "b/flashduty/zh/1. On-call/3. \351\205\215\347\275\256\347\256\241\347\220\206/4.7 \351\205\215\347\275\256\351\200\232\347\237\245\346\250\241\346\235\277.md"
@@ -248,7 +248,7 @@ EndTime | int64 | 否 | 恢复时间,Unix 秒时间戳,默认为 0
10. **如何通过图片[Image](#Image)的 Src 属性获取对应的图片 URL**
- imageSrcToURL 可以实现,入参: $root 和 Src
- - 若 Src 是 [图片上传](https://developer.flashcat.cloud/api-344943718)接口的 image_key, 则 转换成短时间内可访问的地址
+ - 若 Src 是 图片上传接口的 image_key, 则 转换成短时间内可访问的地址
- 若 Src 是 http/https 可访问地址,则直接返回该地址
- 钉钉/Slack App 使用本函数来展示图片
```
@@ -260,7 +260,7 @@ EndTime | int64 | 否 | 恢复时间,Unix 秒时间戳,默认为 0
11. **如何将图片转换并上传到第三方通知平台**
- transferImage 可以实现,入参: $root 和 Src
- - Src 可以是 [图片上传](https://developer.flashcat.cloud/api-344943718) 接口的 image_key 或者 http/https 可访问图片地址
+ - Src 可以是 图片上传 接口的 image_key 或者 http/https 可访问图片地址
- 图片大小不能超过 10 MB
- 支持上传 JPG、JPEG、PNG、WEBP、GIF、BMP、ICO、TIFF、HEIC 格式的图片
- 需要开启 应用 获取与上传图片或文件资源 权限
diff --git "a/flashduty/zh/1. On-call/4. \351\253\230\347\272\247\345\212\237\350\203\275/1. \345\274\225\347\224\250\345\217\230\351\207\217.md" "b/flashduty/zh/1. On-call/4. \351\253\230\347\272\247\345\212\237\350\203\275/1. \345\274\225\347\224\250\345\217\230\351\207\217.md"
index c1cc4a9d..389f3f01 100644
--- "a/flashduty/zh/1. On-call/4. \351\253\230\347\272\247\345\212\237\350\203\275/1. \345\274\225\347\224\250\345\217\230\351\207\217.md"
+++ "b/flashduty/zh/1. On-call/4. \351\253\230\347\272\247\345\212\237\350\203\275/1. \345\274\225\347\224\250\345\217\230\351\207\217.md"
@@ -10,7 +10,7 @@ url: "https://docs.flashcat.cloud/zh/flashduty/customize-incident-attrs"
通过引用告警标签、属性的变量,实现对故障的严重程度和标题以及描述等信息的修改与定制。主要应用在两种场景:
-1. 通过告警 [Event API](https://developer.flashcat.cloud/zh/flashduty/event-api/alert-event) 上报自定义告警事件时,可以使用 title_rule 字段自定义告警的标题。
+1. 通过告警 [Event API](https://docs.flashcat.cloud/zh/on-call/integration/alert-integration/alert-sources/standard alert) 上报自定义告警事件时,可以使用 title_rule 字段自定义告警的标题。
```
# 示例:指定resource和check标签作为告警标题
diff --git "a/flashduty/zh/1. On-call/4. \351\253\230\347\272\247\345\212\237\350\203\275/3. \345\210\206\346\236\220\346\225\260\346\215\256.md" "b/flashduty/zh/1. On-call/4. \351\253\230\347\272\247\345\212\237\350\203\275/3. \345\210\206\346\236\220\346\225\260\346\215\256.md"
index 5277497c..c4d61187 100644
--- "a/flashduty/zh/1. On-call/4. \351\253\230\347\272\247\345\212\237\350\203\275/3. \345\210\206\346\236\220\346\225\260\346\215\256.md"
+++ "b/flashduty/zh/1. On-call/4. \351\253\230\347\272\247\345\212\237\350\203\275/3. \345\210\206\346\236\220\346\225\260\346\215\256.md"
@@ -89,14 +89,14 @@ url: "https://docs.flashcat.cloud/zh/flashduty/insights"
#### 导出限制
-- 故障列表导出时,不包含 Labels 数据,如果需要更详细的数据,建议通过[故障列表](https://developer.flashcat.cloud/api-110655782)的 API 查询。
+- 故障列表导出时,不包含 Labels 数据,如果需要更详细的数据,建议通过[故障列表](https://docs.flashcat.cloud/zh/api-reference/on-call/incidents/incident-list)的 API 查询。
- 数据列表的查询和导出的数据量最大是 10 万条,如果需要更多数据,建议分时间段导出。
### 常见问题
想要查询更久的数据怎么办?
- 目前分析看板中仅支持查询最近180天的数据,如果需要查询更久的数据,可以通过 [API 查询](https://developer.flashcat.cloud/api-213441443)。
+ 目前分析看板中仅支持查询最近180天的数据,如果需要查询更久的数据,可以通过 [API 查询](https://docs.flashcat.cloud/zh/api-reference/on-call/analytics/insight-incident-list)。
diff --git "a/flashduty/zh/1. On-call/5. \351\233\206\346\210\220\345\274\225\345\257\274/8.1 \345\221\212\350\255\246\351\233\206\346\210\220/8.1.0 \346\240\207\345\207\206\345\221\212\350\255\246\344\272\213\344\273\266\351\233\206\346\210\220\346\214\207\345\274\225.md" "b/flashduty/zh/1. On-call/5. \351\233\206\346\210\220\345\274\225\345\257\274/8.1 \345\221\212\350\255\246\351\233\206\346\210\220/8.1.0 \346\240\207\345\207\206\345\221\212\350\255\246\344\272\213\344\273\266\351\233\206\346\210\220\346\214\207\345\274\225.md"
index 39a1fa90..b6d1092f 100644
--- "a/flashduty/zh/1. On-call/5. \351\233\206\346\210\220\345\274\225\345\257\274/8.1 \345\221\212\350\255\246\351\233\206\346\210\220/8.1.0 \346\240\207\345\207\206\345\221\212\350\255\246\344\272\213\344\273\266\351\233\206\346\210\220\346\214\207\345\274\225.md"
+++ "b/flashduty/zh/1. On-call/5. \351\233\206\346\210\220\345\274\225\345\257\274/8.1 \345\221\212\350\255\246\351\233\206\346\210\220/8.1.0 \346\240\207\345\207\206\345\221\212\350\255\246\344\272\213\344\273\266\351\233\206\346\210\220\346\214\207\345\274\225.md"
@@ -93,7 +93,7 @@ POST, Content-Type:"application/json"
字段|必含|类型|释义
:-:|:-:|:-:|:---
| alt | 否 | string | 图片的替代文本, 长度限制 128 字符,超长截断。
-| src | 是 | string | 图片来源,值:http/https 开头的图片链接地址 或 [图片上传接口](https://developer.flashcat.cloud/api-344943718)返回的image_key,长度限制 256 字符,超长会被丢弃
+| src | 是 | string | 图片来源,值:http/https 开头的图片链接地址 或 图片上传接口返回的image_key,长度限制 256 字符,超长会被丢弃
| href | 否 | string | 超链接引用路径,长度限制 256 字符,超长截断
diff --git "a/flashduty/zh/1. On-call/5. \351\233\206\346\210\220\345\274\225\345\257\274/8.1 \345\221\212\350\255\246\351\233\206\346\210\220/8.1.60 Http Pull \345\221\212\350\255\246\351\233\206\346\210\220.md" "b/flashduty/zh/1. On-call/5. \351\233\206\346\210\220\345\274\225\345\257\274/8.1 \345\221\212\350\255\246\351\233\206\346\210\220/8.1.60 Http Pull \345\221\212\350\255\246\351\233\206\346\210\220.md"
new file mode 100644
index 00000000..46c4ad9c
--- /dev/null
+++ "b/flashduty/zh/1. On-call/5. \351\233\206\346\210\220\345\274\225\345\257\274/8.1 \345\221\212\350\255\246\351\233\206\346\210\220/8.1.60 Http Pull \345\221\212\350\255\246\351\233\206\346\210\220.md"
@@ -0,0 +1,225 @@
+---
+title: "HTTP Pull 告警集成"
+description: "通过定时拉取外部 HTTP 接口的方式接入告警事件,适用于无法主动推送告警的系统。"
+---
+
+**版本要求**:HTTP Pull 集成需要 On-call 专业版及以上订阅。
+
+Flashduty 支持两种告警接入模式:**推送(Push)** 和 **拉取(Pull)**。大多数集成使用推送模式,由外部监控系统主动将告警发送到 Flashduty。但部分系统不支持 Webhook 推送,或者告警数据只能通过 API 查询获取。
+
+HTTP Pull 集成正是为这类场景设计的——您只需提供一个返回 JSON 格式告警数据的 HTTP 接口,Flashduty 会按照您设定的周期定时拉取,并将拉取到的数据转换为标准告警事件进行处理。
+
+## 适用场景
+
+- 监控系统仅提供查询 API,不支持 Webhook 推送
+- 告警数据存储在数据库或对象存储中,需要通过 HTTP 接口查询
+- 自研系统暂时无法改造为推送模式,希望先通过拉取方式快速接入
+
+## 配置步骤
+
+
+
+进入 Flashduty 控制台,选择 **集成中心 → 告警事件**,搜索并选择 **HTTP Pull** 集成。
+
+
+
+配置 Flashduty 向您的接口发起请求时的参数:
+
+| 配置项 | 必填 | 说明 |
+| :--- | :--- | :--- |
+| **URL** | 是 | 目标 HTTP 接口地址,仅支持 `http` 或 `https` 协议。支持 [模板变量](#模板变量) |
+| **Method** | 否 | 请求方法,支持 `GET` 和 `POST`,默认 `GET`。使用 GET 时不可设置 Body |
+| **Headers** | 否 | 自定义请求头,Key-Value 格式。出于安全考虑,`Authorization`、`Cookie` 等敏感 Header 不可使用 |
+| **Body** | 否 | 请求体,仅 POST 方法可用。支持 [模板变量](#模板变量),需为合法的 JSON 格式 |
+| **Timeout** | 否 | 单次请求超时时间,范围 1-10 秒,默认 5 秒 |
+| **RetryCount** | 否 | 请求失败时的重试次数,范围 0-2 次,默认 1 次 |
+
+
+
+
+设置 **拉取周期(cycle_seconds)**,即多久拉取一次数据。最小值为 30 秒,默认 300 秒(5 分钟)。
+
+
+
+如果您的接口返回的告警严重程度与 Flashduty 的标准不一致,可以通过 **severity_mapping** 进行映射。
+
+例如您的系统使用 `high` / `medium` / `low`,可映射为 Flashduty 的 `Critical` / `Warning` / `Info`。
+
+
+
+如果您的接口支持分页,可以配置分页参数以获取完整数据。详见 [分页配置](#分页配置)。
+
+
+
+保存配置后,集成将按照设定的周期自动拉取数据。您也可以在集成详情页手动触发一次拉取。
+
+
+
+## 响应格式要求
+
+
+
+您的 HTTP 接口必须满足以下要求:
+
+1. **返回 HTTP 200 状态码**
+2. **Content-Type 须包含 `json`**(如 `application/json`)
+3. **响应体须为 JSON 格式,且包含 `items` 数组**
+
+每个 `items` 元素对应一条告警事件,字段与 [标准告警事件](/zh/on-call/integration/alert-integration/alert-sources/standard%20alert) 协议一致:
+
+```json
+{
+ "items": [
+ {
+ "event_status": "Warning",
+ "title_rule": "CPU idle lower than 20%",
+ "alert_key": "host-01::cpu-idle",
+ "description": "Host host-01 CPU idle is 15%",
+ "labels": {
+ "host": "host-01",
+ "check": "cpu.idle",
+ "metric": "node_cpu_seconds_total"
+ }
+ },
+ {
+ "event_status": "Ok",
+ "alert_key": "host-02::cpu-idle"
+ }
+ ]
+}
+```
+
+### 事件字段说明
+
+| 字段 | 必含 | 类型 | 说明 |
+| :--- | :--- | :--- | :--- |
+| event_status | 是 | string | 告警状态。枚举值(首字母大写):`Critical`、`Warning`、`Info`、`Ok`(恢复) |
+| title_rule | 是 | string | 告警标题,不超过 512 字符 |
+| alert_key | 否 | string | 告警标识,用于更新或恢复已有告警。不超过 255 字符,不指定时系统自动生成 |
+| description | 否 | string | 告警描述,不超过 2048 字符 |
+| labels | 否 | map | 告警标签集合,Key-Value 格式。至多 50 个标签 |
+
+
+单页最多处理 100 条事件,单次拉取全部分页累计最多处理 2000 条事件。超出的事件会被截断并记录在拉取历史中。
+
+
+## 模板变量
+
+
+
+URL 和 Body 支持 Go `text/template` 语法,可使用以下变量动态生成请求内容:
+
+| 变量 | 类型 | 说明 |
+| :--- | :--- | :--- |
+| `{{.LastPullTime}}` | int64 | 上次拉取时间(Unix 秒级时间戳) |
+| `{{.NowTime}}` | int64 | 当前时间(Unix 秒级时间戳) |
+| `{{.LastPullTimeISO}}` | string | 上次拉取时间(ISO 8601 格式,如 `2026-05-13T06:00:00Z`) |
+| `{{.NowTimeISO}}` | string | 当前时间(ISO 8601 格式) |
+| `{{.CursorValue}}` | string | 分页游标值,首页为空 |
+
+### 使用示例
+
+URL 中使用时间范围参数:
+
+```
+https://api.example.com/alerts?start={{.LastPullTime}}&end={{.NowTime}}
+```
+
+Body 中使用 ISO 格式时间:
+
+```json
+{
+ "start_time": "{{.LastPullTimeISO}}",
+ "end_time": "{{.NowTimeISO}}"
+}
+```
+
+## 分页配置
+
+
+
+如果您的接口一次返回不了全部数据,可以配置基于游标的分页。
+
+| 配置项 | 说明 |
+| :--- | :--- |
+| **mode** | 分页模式,当前支持 `cursor` |
+| **max_pages** | 最大拉取页数,默认 20 页 |
+| **next_value_path** | 从响应 JSON 中提取下一页游标值的路径,使用 [gjson](https://github.com/tidwall/gjson) 语法。例如 `pagination.next_cursor` |
+| **param_name** | 分页参数名称,例如 `cursor` 或 `page_token` |
+| **inject_to** | 分页参数注入位置:`query`(追加到 URL Query String)或 `body`(合并到请求 Body JSON) |
+
+### 分页工作流程
+
+
+
+Flashduty 发起第一次请求(不含分页参数)。
+
+
+
+从响应 JSON 中,按 `next_value_path` 提取下一页的游标值。
+
+
+
+将游标值以 `param_name` 为键注入到下一次请求的 Query String 或 Body 中。
+
+
+
+当 `next_value_path` 提取不到值、返回空数组、或达到 `max_pages` 上限时,停止分页。
+
+
+
+### 分页响应示例
+
+```json
+{
+ "items": [
+ { "event_status": "Critical", "title_rule": "Disk full", "alert_key": "disk-01" }
+ ],
+ "pagination": {
+ "next_cursor": "eyJpZCI6MTAwfQ=="
+ }
+}
+```
+
+对应配置 `next_value_path` 为 `pagination.next_cursor`,系统会自动将 `eyJpZCI6MTAwfQ==` 作为下一页请求的参数值。
+
+## 常见问题
+
+
+
+出于安全考虑,Flashduty(非私有化部署)不允许访问内网地址(如 `127.0.0.1`、`10.x.x.x`、`192.168.x.x` 等)。请确保您的接口地址可以从公网访问。
+
+如果您使用私有化部署版本,此限制不适用。
+
+
+
+在集成详情页的 **拉取历史** 中,可以查看每次拉取的执行结果,包括状态、拉取的事件数量、错误信息等。
+
+
+
+请检查以下几点:
+
+1. 确认接口返回的 JSON 中包含 `items` 数组,且数组不为空。
+2. 确认每条事件都有 `event_status` 和 `title_rule` 字段。
+3. 如果使用了 `alert_key`,检查是否与之前的告警重复——状态和内容完全相同的事件会被去重丢弃。
+4. 检查是否匹配到了排除、抑制或静默规则。
+
+更多内容请参考 [告警降噪](/zh/on-call/channel/noise-reduction)。
+
+
+
+支持。在集成详情页点击手动触发按钮即可。手动触发有 60 秒的冷却时间,且不能与正在进行的定时拉取同时执行。
+
+
+
+如果您的系统使用自定义的严重程度标识(如 `P1`、`high`),可以在集成配置中设置映射关系。例如:
+
+| 您的值 | Flashduty 值 |
+| :--- | :--- |
+| P1 | Critical |
+| P2 | Warning |
+| P3 | Info |
+
+未匹配到映射的值将保持原样处理。
+
+
diff --git "a/flashduty/zh/1. On-call/5. \351\233\206\346\210\220\345\274\225\345\257\274/8.2 \345\217\230\346\233\264\351\233\206\346\210\220/8.2.1 \350\207\252\345\256\232\344\271\211\344\272\213\344\273\266\351\233\206\346\210\220\346\214\207\345\274\225.md" "b/flashduty/zh/1. On-call/5. \351\233\206\346\210\220\345\274\225\345\257\274/8.2 \345\217\230\346\233\264\351\233\206\346\210\220/8.2.1 \350\207\252\345\256\232\344\271\211\344\272\213\344\273\266\351\233\206\346\210\220\346\214\207\345\274\225.md"
index 3be0ea2e..c5df7524 100644
--- "a/flashduty/zh/1. On-call/5. \351\233\206\346\210\220\345\274\225\345\257\274/8.2 \345\217\230\346\233\264\351\233\206\346\210\220/8.2.1 \350\207\252\345\256\232\344\271\211\344\272\213\344\273\266\351\233\206\346\210\220\346\214\207\345\274\225.md"
+++ "b/flashduty/zh/1. On-call/5. \351\233\206\346\210\220\345\274\225\345\257\274/8.2 \345\217\230\346\233\264\351\233\206\346\210\220/8.2.1 \350\207\252\345\256\232\344\271\211\344\272\213\344\273\266\351\233\206\346\210\220\346\214\207\345\274\225.md"
@@ -26,7 +26,7 @@ Flashduty 已经适配部分常用工单、部署系统的 webhook 协议,对
## 实现协议
---
-请您参照 [开发文档](https://developer.flashcat.cloud/zh/flashduty/event-api/change-event) 完成协议开发。
+请您参照 [开发文档](https://docs.flashcat.cloud/zh/on-call/integration/change-integration/custom-event) 完成协议开发。
## 最佳实践
---
diff --git "a/flashduty/zh/3. Monitors/2. \345\221\212\350\255\246\350\247\204\345\210\231\351\205\215\347\275\256/999-description-template-manual.md" "b/flashduty/zh/3. Monitors/2. \345\221\212\350\255\246\350\247\204\345\210\231\351\205\215\347\275\256/999-description-template-manual.md"
new file mode 100644
index 00000000..ce3fe450
--- /dev/null
+++ "b/flashduty/zh/3. Monitors/2. \345\221\212\350\255\246\350\247\204\345\210\231\351\205\215\347\275\256/999-description-template-manual.md"
@@ -0,0 +1,543 @@
+# 告警规则 Description 模板使用手册
+
+本文档说明告警规则 `Description` 字段中可使用的变量和函数。
+
+`Description` 字段使用 Go `text/template` 渲染。模板语法遵循 Go template 规则,包括 `{{ ... }}`、`if`、`range`、变量赋值、管道和比较操作等。
+
+## 基本语法
+
+使用 `{{ ... }}` 输出变量或表达式结果:
+
+```gotemplate
+当前值:{{ printf "%.2f" $value }}
+```
+
+使用 `if` 做条件判断:
+
+```gotemplate
+{{- if eq $status "firing" }}
+告警已触发。
+{{- else }}
+告警已恢复。
+{{- end }}
+```
+
+使用 `range` 遍历列表:
+
+```gotemplate
+{{- range $row := $relates.R1 }}
+- 日志内容:{{ $row.Fields._msg }}
+{{- end }}
+```
+
+如果 map 的 key 包含 `.`, `/`, `-`, `$` 等特殊字符,应使用 Go template 内置的 `index` 函数读取:
+
+```gotemplate
+{{ index $labels "service.name" }}
+{{ index $values "$A.latency" }}
+{{ index $row.Fields "log.message" }}
+```
+
+## 内置变量
+
+以下短变量会在用户模板渲染前自动注入。
+
+| 变量 | 类型 | 说明 |
+| --- | --- | --- |
+| `$labels` | `map[string]string` | 告警数据点的标签,等价于 `.DataLabels`。 |
+| `$values` | `map[string]float64` | 告警计算中使用到的数值,等价于 `.Values`。 |
+| `$value` | `float64` | 主告警值,等价于 `.Value`。 |
+| `$appendLabels` | `map[string]string` | 规则上配置的附加标签,已完成标签变量替换,等价于 `.AppendLabels`。 |
+| `$annotations` | `map[string]string` | 规则上配置的自定义字段,已完成标签变量替换,等价于 `.Annotations`。 |
+| `$dsType` | `string` | 数据源类型,等价于 `.DataSourceType`。 |
+| `$dsName` | `string` | 数据源名称,等价于 `.DataSourceName`。 |
+| `$dsAddress` | `string` | 数据源地址,不包含认证信息,等价于 `.DataSourceAddress`。 |
+| `$checkMode` | `string` | 检测模式,例如 `threshold`、`anydata`、`nodata`,等价于 `.CheckMode`。 |
+| `$relates` | `map[string][]*ResultRow` | 关联查询结果,key 是关联查询名称,等价于 `.Relates`。 |
+| `$status` | `string` | 事件状态:`firing` 或 `recovered`,等价于 `.Status`。 |
+| `$severity` | `string` | 告警级别,例如 `Critical`、`Warning`、`Info`,等价于 `.Severity`。 |
+
+示例:
+
+```gotemplate
+{{- if eq $status "firing" }}
+{{ $dsName }} 触发 {{ $severity }} 告警,当前值为 {{ printf "%.2f" $value }}。
+{{- else }}
+{{ $dsName }} 告警已恢复。
+{{- end }}
+```
+
+```gotemplate
+实例:{{ index $labels "instance" }}
+A 查询值:{{ getvalue $values "$A" "%.2f" }}
+```
+
+## 根对象字段
+
+模板的根对象是完整的告警事件,可以通过 `.FieldName` 访问字段。
+
+| 字段 | 类型 | 说明 |
+| --- | --- | --- |
+| `.Hash` | `string` | 稳定的事件 hash。同一个事件的告警和恢复使用相同 hash。 |
+| `.DataSourceType` | `string` | 数据源类型。 |
+| `.DataSourceName` | `string` | 数据源名称。 |
+| `.DataSourceAddress` | `string` | 数据源地址,不包含认证信息。 |
+| `.RuleName` | `string` | 告警规则名称。 |
+| `.RuleID` | `uint64` | 告警规则 ID。 |
+| `.Queries` | `[]Query` | 规则查询定义。 |
+| `.RelateQueries` | `[]RelateQuery` | 关联查询定义。 |
+| `.CheckMode` | `string` | 检测模式。 |
+| `.DataLabels` | `map[string]string` | 告警标签。 |
+| `.AppendLabels` | `map[string]string` | 规则上配置的附加标签。 |
+| `.EnrichLabels` | `map[string]string` | enrichment 返回的标签。通常在渲染 `Description` 时为空,因为 enrichment 发生在描述渲染之后。 |
+| `.Values` | `map[string]float64` | 告警计算中使用到的数值。 |
+| `.Annotations` | `map[string]string` | 规则自定义字段。 |
+| `.Relates` | `map[string][]*ResultRow` | 关联查询结果行。 |
+| `.Status` | `string` | `firing` 或 `recovered`。 |
+| `.Severity` | `string` | 告警级别。 |
+| `.EvalTime` | `int64` | 本次评估时间,Unix 秒级时间戳。 |
+| `.Description` | `string` | 渲染后的描述。该字段在模板执行完成后才设置。 |
+| `.DescriptionType` | `string` | 描述类型,例如 `text` 或 `markdown`。 |
+| `.Value` | `float64` | 主告警值。 |
+| `.TitleRule` | `string` | edge 上配置的标题规则。 |
+| `.DebugLogEnabled` | `bool` | 当前规则是否启用调试日志。该字段主要用于内部诊断。 |
+| `.LogPrefix` | `string` | 本次评估的内部日志前缀。该字段主要用于内部诊断。 |
+
+示例:
+
+```gotemplate
+规则 {{ .RuleID }} / {{ .RuleName }} 在 {{ .DataSourceName }} 上触发。
+```
+
+`.Queries` 中的 `Query` 对象包含以下字段:
+
+| 字段 | 类型 | 说明 |
+| --- | --- | --- |
+| `.Name` | `string` | 查询名称,通常是 `A`、`B`、`C` 等。 |
+| `.Expr` | `string` | 查询表达式。 |
+| `.LabelFields` | `[]string` | 作为标签使用的字段。 |
+| `.ValueFields` | `[]string` | 作为数值使用的字段。 |
+| `.Args` | `map[string]string` | 部分数据源需要的额外查询参数。 |
+
+`.RelateQueries` 中的 `RelateQuery` 对象包含以下字段:
+
+| 字段 | 类型 | 说明 |
+| --- | --- | --- |
+| `.Name` | `string` | 关联查询名称,例如 `R1`。 |
+| `.Expr` | `string` | 关联查询表达式。 |
+| `.Args` | `map[string]string` | 部分数据源需要的额外查询参数。 |
+
+## 关联查询结果行
+
+关联查询结果通过 `$relates` 访问。map 的 key 是关联查询名称,例如 `R1`。
+
+每一行包含以下字段和方法:
+
+| 字段或方法 | 类型 | 说明 |
+| --- | --- | --- |
+| `$row.Fields` | `map[string]interface{}` | 关联查询返回的非数值字段或展示字段。 |
+| `$row.Values` | `map[string]float64` | 关联查询返回的数值字段。 |
+| `$row.Field "name"` | `interface{}` | 从 `$row.Fields` 读取一个字段。 |
+| `$row.Value` | `float64` | 返回 `$row.Values` 中的第一个数值;如果没有数值则返回 `NaN`。 |
+| `$row.Value "name"` | `float64` | 从 `$row.Values` 读取一个数值;如果 key 不存在则返回 `NaN`。 |
+| `$row.String` | `string` | 返回该行的调试字符串。 |
+
+示例:
+
+```gotemplate
+{{- range $row := $relates.R1 }}
+- 日志:{{ $row.Fields._msg }}
+- 次数:{{ printf "%.0f" ($row.Value "count") }}
+{{- end }}
+```
+
+```gotemplate
+{{- range $row := $relates.R1 }}
+ {{- $msg := printf "%v" ($row.Field "_msg") }}
+ {{- if sprig_contains "Unknown column" $msg }}
+ {{- $field := sprig_regexReplaceAll ".*Unknown column '([^']+)'.*" $msg "$1" }}
+- 缺失字段:{{ $field }}
+ {{- end }}
+{{- end }}
+```
+
+## Go Template 内置函数
+
+以下函数由 Go `text/template` 提供。
+
+| 函数 | 说明 | 示例 |
+| --- | --- | --- |
+| `and` | 逻辑 AND。结果确定后停止继续求值。 | `{{ if and $a $b }}yes{{ end }}` |
+| `or` | 逻辑 OR。结果确定后停止继续求值。 | `{{ if or $a $b }}yes{{ end }}` |
+| `not` | 逻辑 NOT。 | `{{ if not $ok }}failed{{ end }}` |
+| `eq` | 等于。 | `{{ if eq $status "firing" }}...{{ end }}` |
+| `ne` | 不等于。 | `{{ if ne $severity "Info" }}...{{ end }}` |
+| `lt` | 小于。 | `{{ if lt $value 10.0 }}...{{ end }}` |
+| `le` | 小于等于。 | `{{ if le $value 10.0 }}...{{ end }}` |
+| `gt` | 大于。 | `{{ if gt $value 10.0 }}...{{ end }}` |
+| `ge` | 大于等于。 | `{{ if ge $value 10.0 }}...{{ end }}` |
+| `index` | 从 map、slice 或 array 中读取元素。 | `{{ index $labels "instance" }}` |
+| `slice` | 对字符串、slice 或 array 做切片。 | `{{ slice "abcdef" 0 3 }}` |
+| `len` | 返回长度。 | `{{ len $relates.R1 }}` |
+| `printf` | 使用 `fmt.Sprintf` 语法格式化文本。 | `{{ printf "%.2f" $value }}` |
+| `print` | 使用默认格式拼接多个值。 | `{{ print $dsName ":" $status }}` |
+| `println` | 类似 `print`,但会追加换行。 | `{{ println $dsName }}` |
+| `call` | 调用函数值。Description 中通常很少使用。 | `{{ call .SomeFunc }}` |
+| `html` | 按 HTML 规则转义文本。 | `{{ html $text }}` |
+| `js` | 按 JavaScript 规则转义文本。 | `{{ js $text }}` |
+| `urlquery` | 按 URL query 规则转义文本。 | `{{ urlquery $text }}` |
+
+## monit-edge 自定义函数
+
+以下函数由 monit-edge 注册,使用时不需要前缀。
+
+| 函数 | 说明 | 示例 |
+| --- | --- | --- |
+| `pathEscape text` | 对 URL path 做转义。 | `{{ pathEscape "a/b c" }}` |
+| `queryEscape text` | 对 URL query 做转义。 | `{{ queryEscape "level=error msg" }}` |
+| `getvalue values key [format]` | 从 `map[string]float64` 中读取数值并格式化。默认格式是 `%.4f`。如果 key 为空或不存在,会返回 `template_function_error: ...` 文本。 | `{{ getvalue $values "$A" "%.2f" }}` |
+| `getfvalue values key` | 从 `map[string]float64` 中读取数值。如果 key 为空或不存在,返回 `NaN`。 | `{{ if gt (getfvalue $values "$A") 10.0 }}high{{ end }}` |
+| `trunc count text` | `truncRune` 的别名。按 Unicode 字符截断,不按字节截断。`count` 为负数时从末尾保留字符。 | `{{ trunc 10 $msg }}` |
+| `truncRune count text` | 按 Unicode 字符截断。 | `{{ truncRune -8 "abcdef你好" }}` |
+| `runeCount text` | 统计 Unicode 字符数。 | `{{ runeCount "你好abc" }}` |
+| `args ...` | 构造一个 map,key 为 `arg0`、`arg1` 等。主要用于组合 helper 调用。 | `{{ args "a" 1 }}` |
+| `reReplaceAll pattern repl text` | 正则替换。参数顺序是 `pattern`、`replacement`、`text`。正则非法时会导致模板渲染失败。 | `{{ reReplaceAll ".*id=([0-9]+).*" "$1" $msg }}` |
+| `safeHtml text` | 将文本标记为 HTML 安全文本。普通 text 或 markdown 描述不建议使用,除非明确需要 HTML 输出。 | `{{ safeHtml "OK" }}` |
+| `match pattern text` | 正则匹配,等价于 Go `regexp.MatchString`。正则非法时会导致模板渲染失败。 | `{{ if match "Unknown column" $msg }}...{{ end }}` |
+| `toUpper text` | 转成大写。 | `{{ toUpper $severity }}` |
+| `toLower text` | 转成小写。 | `{{ toLower $status }}` |
+| `stripPort hostPort` | 从 `host:port` 中去掉端口。如果解析失败,返回原始值。 | `{{ stripPort "example.com:9100" }}` |
+| `stripDomain hostPort` | 去掉主机名中的域名后缀,并保留端口。IP 地址会原样返回。 | `{{ stripDomain "node01.prod.local:9100" }}` |
+| `humanize value` | 使用 SI 单位格式化数字。 | `{{ humanize 12345 }}` |
+| `humanize1024 value` | 使用 1024 进制单位格式化数字。 | `{{ humanize1024 1048576 }}` |
+| `humanizeDuration seconds` | 将秒数格式化为可读时长。 | `{{ humanizeDuration 3661 }}` |
+| `humanizePercentage value` | 将比例格式化为百分比。`0.1234` 会变成 `12.34%`。 | `{{ humanizePercentage 0.95 }}` |
+| `humanizeTimestamp seconds` | 将 Unix 秒级时间戳转为 UTC 时间文本。 | `{{ humanizeTimestamp .EvalTime }}` |
+| `toTime seconds` | 将 Unix 秒级时间戳转为 `time.Time`。 | `{{ (toTime .EvalTime).Format "2006-01-02 15:04:05" }}` |
+| `nanoTime value [tzOffset]` | 将 Unix 纳秒级时间戳转为 `time.Time`。可选时区偏移单位为小时。 | `{{ (nanoTime $row.Fields.__time__ 8).Format "2006-01-02 15:04:05" }}` |
+| `timeFormat value format [tzOffset]` | 格式化 `time.Time`、`*time.Time`、RFC3339 字符串或 RFC3339Nano 字符串。可选时区偏移单位为小时。 | `{{ timeFormat "2026-01-06T11:48:12Z" "2006-01-02 15:04:05" 8 }}` |
+| `parseDuration duration` | 解析时长字符串并返回秒数。支持的单位遵循 monit-edge 的 duration 解析规则。 | `{{ parseDuration "5m" }}` |
+| `add a b` | 数值加法。 | `{{ add 1 2 }}` |
+| `sub a b` | 数值减法。 | `{{ sub 10 3 }}` |
+| `mul a b` | 数值乘法。 | `{{ mul $value 100 }}` |
+| `div a b` | 数值除法。除零会导致模板渲染失败。 | `{{ div $value 1024 }}` |
+| `now` | 当前时间,类型为 `time.Time`。 | `{{ now.Format "2006-01-02 15:04:05" }}` |
+| `toString value` | 使用 `fmt.Sprint` 将值转为字符串。 | `{{ toString $row.Fields._msg }}` |
+
+## Sprig 函数
+
+monit-edge 也注册了 Sprig 函数,但所有 Sprig 函数都必须带 `sprig_` 前缀。
+
+例如:
+
+```gotemplate
+{{ sprig_contains "error" $msg }}
+{{ sprig_regexMatch "Unknown column" $msg }}
+{{ sprig_regexFind "Unknown column '[^']+'" $msg }}
+```
+
+不要使用不带前缀的 Sprig 函数名,例如 `contains`、`regexMatch`、`regexFind`;这些名字没有注册。
+
+正则使用注意事项:`sprig_regexFind` 返回的是完整匹配文本,不返回捕获组。如果要提取捕获组,请使用 `sprig_regexReplaceAll`:
+
+```gotemplate
+{{- $msg := "Unknown column 'community_posts.comment_count' in 'field list'" }}
+{{- sprig_regexReplaceAll ".*Unknown column '([^']+)'.*" $msg "$1" }}
+```
+
+结果是:
+
+```text
+community_posts.comment_count
+```
+
+### 常用 Sprig 函数
+
+| 函数 | 说明 | 示例 |
+| --- | --- | --- |
+| `sprig_contains substr text` | 判断 `text` 是否包含 `substr`。 | `{{ if sprig_contains "Unknown column" $msg }}...{{ end }}` |
+| `sprig_hasPrefix prefix text` | 判断前缀。 | `{{ sprig_hasPrefix "prod-" $name }}` |
+| `sprig_hasSuffix suffix text` | 判断后缀。 | `{{ sprig_hasSuffix ".log" $file }}` |
+| `sprig_regexMatch pattern text` | 正则匹配。 | `{{ sprig_regexMatch "error|failed" $msg }}` |
+| `sprig_regexFind pattern text` | 返回第一个完整正则匹配。 | `{{ sprig_regexFind "trace_id=[a-z0-9]+" $msg }}` |
+| `sprig_regexFindAll pattern text n` | 返回最多 `n` 个完整正则匹配。`-1` 表示全部返回。 | `{{ sprig_regexFindAll "id=[0-9]+" $msg -1 }}` |
+| `sprig_regexReplaceAll pattern text repl` | 正则替换。参数顺序是 `pattern`、`text`、`replacement`。 | `{{ sprig_regexReplaceAll ".*id=([0-9]+).*" $msg "$1" }}` |
+| `sprig_trim text` | 去掉首尾空白字符。 | `{{ sprig_trim $msg }}` |
+| `sprig_lower text` | 转小写。 | `{{ sprig_lower $severity }}` |
+| `sprig_upper text` | 转大写。 | `{{ sprig_upper $severity }}` |
+| `sprig_default default value` | 当 `value` 为空时使用默认值。 | `{{ sprig_default "unknown" (index $labels "instance") }}` |
+| `sprig_toJson value` | 将值转为 JSON。 | `{{ sprig_toJson $labels }}` |
+| `sprig_dict ...` | 创建字典。 | `{{ sprig_dict "name" $dsName "status" $status }}` |
+| `sprig_list ...` | 创建列表。 | `{{ sprig_list "a" "b" "c" }}` |
+
+### 完整 Sprig 函数名列表
+
+当前 monit-edge 构建中可使用以下函数名:
+
+```text
+sprig_abbrev
+sprig_abbrevboth
+sprig_add
+sprig_add1
+sprig_add1f
+sprig_addf
+sprig_adler32sum
+sprig_ago
+sprig_all
+sprig_any
+sprig_append
+sprig_atoi
+sprig_b32dec
+sprig_b32enc
+sprig_b64dec
+sprig_b64enc
+sprig_base
+sprig_bcrypt
+sprig_biggest
+sprig_buildCustomCert
+sprig_camelcase
+sprig_cat
+sprig_ceil
+sprig_chunk
+sprig_clean
+sprig_coalesce
+sprig_compact
+sprig_concat
+sprig_contains
+sprig_date
+sprig_dateInZone
+sprig_dateModify
+sprig_date_in_zone
+sprig_date_modify
+sprig_decryptAES
+sprig_deepCopy
+sprig_deepEqual
+sprig_default
+sprig_derivePassword
+sprig_dict
+sprig_dig
+sprig_dir
+sprig_div
+sprig_divf
+sprig_duration
+sprig_durationRound
+sprig_empty
+sprig_encryptAES
+sprig_env
+sprig_expandenv
+sprig_ext
+sprig_fail
+sprig_first
+sprig_float64
+sprig_floor
+sprig_fromJson
+sprig_genCA
+sprig_genCAWithKey
+sprig_genPrivateKey
+sprig_genSelfSignedCert
+sprig_genSelfSignedCertWithKey
+sprig_genSignedCert
+sprig_genSignedCertWithKey
+sprig_get
+sprig_getHostByName
+sprig_gt
+sprig_gte
+sprig_has
+sprig_hasKey
+sprig_hasPrefix
+sprig_hasSuffix
+sprig_hello
+sprig_htmlDate
+sprig_htmlDateInZone
+sprig_htpasswd
+sprig_indent
+sprig_initial
+sprig_initials
+sprig_int
+sprig_int64
+sprig_isAbs
+sprig_join
+sprig_kebabcase
+sprig_keys
+sprig_kindIs
+sprig_kindOf
+sprig_last
+sprig_list
+sprig_lower
+sprig_lt
+sprig_lte
+sprig_max
+sprig_maxf
+sprig_merge
+sprig_mergeOverwrite
+sprig_min
+sprig_minf
+sprig_mod
+sprig_mul
+sprig_mulf
+sprig_mustAppend
+sprig_mustChunk
+sprig_mustCompact
+sprig_mustDateModify
+sprig_mustDeepCopy
+sprig_mustFirst
+sprig_mustFromJson
+sprig_mustHas
+sprig_mustInitial
+sprig_mustLast
+sprig_mustMerge
+sprig_mustMergeOverwrite
+sprig_mustPrepend
+sprig_mustPush
+sprig_mustRegexFind
+sprig_mustRegexFindAll
+sprig_mustRegexMatch
+sprig_mustRegexReplaceAll
+sprig_mustRegexReplaceAllLiteral
+sprig_mustRegexSplit
+sprig_mustRest
+sprig_mustReverse
+sprig_mustSlice
+sprig_mustToDate
+sprig_mustToJson
+sprig_mustToPrettyJson
+sprig_mustToRawJson
+sprig_mustUniq
+sprig_mustWithout
+sprig_must_date_modify
+sprig_nindent
+sprig_nospace
+sprig_now
+sprig_omit
+sprig_osBase
+sprig_osClean
+sprig_osDir
+sprig_osExt
+sprig_osIsAbs
+sprig_pick
+sprig_pluck
+sprig_plural
+sprig_prepend
+sprig_push
+sprig_quote
+sprig_randAlpha
+sprig_randAlphaNum
+sprig_randAscii
+sprig_randBytes
+sprig_randInt
+sprig_randNumeric
+sprig_regexFind
+sprig_regexFindAll
+sprig_regexMatch
+sprig_regexQuoteMeta
+sprig_regexReplaceAll
+sprig_regexReplaceAllLiteral
+sprig_regexSplit
+sprig_repeat
+sprig_replace
+sprig_rest
+sprig_reverse
+sprig_round
+sprig_semver
+sprig_semverCompare
+sprig_seq
+sprig_set
+sprig_sha1sum
+sprig_sha256sum
+sprig_sha512sum
+sprig_shuffle
+sprig_slice
+sprig_snakecase
+sprig_sortAlpha
+sprig_split
+sprig_splitList
+sprig_splitn
+sprig_squote
+sprig_sub
+sprig_subf
+sprig_substr
+sprig_swapcase
+sprig_ternary
+sprig_title
+sprig_toDate
+sprig_toDecimal
+sprig_toJson
+sprig_toPrettyJson
+sprig_toRawJson
+sprig_toString
+sprig_toStrings
+sprig_trim
+sprig_trimAll
+sprig_trimPrefix
+sprig_trimSuffix
+sprig_trimall
+sprig_trunc
+sprig_tuple
+sprig_typeIs
+sprig_typeIsLike
+sprig_typeOf
+sprig_uniq
+sprig_unixEpoch
+sprig_unset
+sprig_until
+sprig_untilStep
+sprig_untitle
+sprig_upper
+sprig_urlJoin
+sprig_urlParse
+sprig_uuidv4
+sprig_values
+sprig_without
+sprig_wrap
+sprig_wrapWith
+```
+
+部分 Sprig 函数可以读取环境变量、生成随机数据、执行网络解析或生成加密材料。它们之所以可用,是因为 monit-edge 以 `sprig_` 前缀原样注册了 Sprig 函数。告警描述中通常建议优先使用确定性的字符串、正则、数学、日期、JSON、字典和列表函数。
+
+## 完整示例:提取 MySQL Unknown Column 字段名
+
+以下模板从关联日志行中提取缺失字段名。
+
+```gotemplate
+{{- if eq $status "firing" }}
+在过去5分钟的时间内,数据库操作出现缺失字段错误 {{ $value | printf "%.0f" }} 次;
+{{- range $x := $relates.R1 }}
+ {{- $msg := printf "%v" $x.Fields._msg }}
+ {{- if sprig_contains "Unknown column" $msg }}
+ {{- $field := sprig_regexReplaceAll ".*Unknown column '([^']+)'.*" $msg "$1" }}
+
+- 缺失字段:{{ $field }}
+- 查看地址:https://example.com/logs?query={{ queryEscape "Unknown column" }}
+ {{- end }}
+{{- end }}
+{{- else }}
+数据库缺字段错误已恢复
+{{- end }}
+```
+
+## 常见问题
+
+如果渲染失败并提示:
+
+```text
+function "contains" not defined
+```
+
+说明模板使用了未加前缀的 Sprig 函数。请改用 `sprig_contains`。
+
+如果渲染失败并提示:
+
+```text
+function "regexFind" not defined
+```
+
+请改用 `sprig_regexFind`。
+
+如果提取结果包含完整匹配文本,而不是只包含捕获组,请将 `sprig_regexFind` 改为 `sprig_regexReplaceAll`,并在 replacement 中使用 `$1`、`$2` 等捕获组引用。
+
+如果 map key 无法通过点语法读取,请使用 `index`:
+
+```gotemplate
+{{ index $labels "service.name" }}
+{{ index $x.Fields "_msg" }}
+```
diff --git "a/flashduty/zh/5. \345\271\263\345\217\260\345\212\237\350\203\275/1. \345\233\242\351\230\237\345\222\214\346\210\220\345\221\230.md" "b/flashduty/zh/5. \345\271\263\345\217\260\345\212\237\350\203\275/1. \345\233\242\351\230\237\345\222\214\346\210\220\345\221\230.md"
index f715d1cb..66c1b509 100644
--- "a/flashduty/zh/5. \345\271\263\345\217\260\345\212\237\350\203\275/1. \345\233\242\351\230\237\345\222\214\346\210\220\345\221\230.md"
+++ "b/flashduty/zh/5. \345\271\263\345\217\260\345\212\237\350\203\275/1. \345\233\242\351\230\237\345\222\214\346\210\220\345\221\230.md"
@@ -50,7 +50,7 @@ url: "https://docs.flashcat.cloud/zh/flashduty/teams-and-members"
### 邀请方式
- 控制台仅支持邮件邀请,用户昵称默认为邮箱前缀,可在激活后进入账户设置页面修改
-- 您可以通过 [Open API](https://developer.flashcat.cloud/api-110655699) 进行邀请,支持手机号邀请
+- 您可以通过 [Open API](https://docs.flashcat.cloud/zh/api-reference/platform/members/member-invite) 进行邀请,支持手机号邀请
- 系统会向被邀请的同事发送短信或邮件,每天邀请数量上限为 200 人,单次邀请至多 10 人
- 除了以上方式,您也可以联系组织管理员配置单点登录,新成员登录自动创建账号
- 向对方发生邀请后,对方登录即可激活账号,未激活之前账号无法接收告警相关通知
diff --git a/src/en.ts b/src/en.ts
index 3ad9fb93..7c9b7945 100644
--- a/src/en.ts
+++ b/src/en.ts
@@ -58,6 +58,7 @@ import UcloudCloudWatch from "../flashduty/en/1. On-call/8. Integrations/8.1 Ale
import Nagios from "../flashduty/en/1. On-call/8. Integrations/8.1 Alerts integration/8.1.57 Nagios Integration.md?raw";
import JDCloudMonitor from "../flashduty/en/1. On-call/8. Integrations/8.1 Alerts integration/8.1.58 JD Cloud Monitoring Integration.md?raw";
import AliyunPrometheus from "../flashduty/en/1. On-call/8. Integrations/8.1 Alerts integration/8.1.59 Alibaba Cloud Prometheus Integration.md?raw";
+import HttpPull from "../flashduty/en/1. On-call/8. Integrations/8.1 Alerts integration/8.1.60 Http Pull Alert Integration.md?raw";
/** ⬆️⬆️⬆️⬆️ 告警集成 ⬆️⬆️⬆️⬆️ */
/** ⬇️⬇️⬇️⬇️ 变更事件 ⬇️⬇️⬇️⬇️ */
import CustomChange from "../flashduty/en/1. On-call/8. Integrations/8.2 Change integration/8.2.1 Standard Change Event.md?raw";
@@ -169,6 +170,7 @@ const docs = {
UcloudCloudWatch,
Nagios,
JDCloudMonitor,
- AliyunPrometheus
+ AliyunPrometheus,
+ HttpPull
};
export default docs;
diff --git a/src/zh.ts b/src/zh.ts
index 9a10c24a..da5d5daf 100644
--- a/src/zh.ts
+++ b/src/zh.ts
@@ -58,6 +58,7 @@ import UcloudCloudWatch from "../flashduty/zh/1. On-call/5. 集成引导/8.1 告
import Nagios from "../flashduty/zh/1. On-call/5. 集成引导/8.1 告警集成/8.1.57 Nagios 告警集成指引.md?raw";
import JDCloudMonitor from "../flashduty/zh/1. On-call/5. 集成引导/8.1 告警集成/8.1.58 京东云监控告警集成指引.md?raw";
import AliyunPrometheus from "../flashduty/zh/1. On-call/5. 集成引导/8.1 告警集成/8.1.59 阿里云 Prometheus 监控告警集成指引.md?raw";
+import HttpPull from "../flashduty/zh/1. On-call/5. 集成引导/8.1 告警集成/8.1.60 Http Pull 告警集成.md?raw";
/** ⬆️⬆️⬆️⬆️ 告警集成 ⬆️⬆️⬆️⬆️ */
/** ⬇️⬇️⬇️⬇️ 变更事件 ⬇️⬇️⬇️⬇️ */
import CustomChange from "../flashduty/zh/1. On-call/5. 集成引导/8.2 变更集成/8.2.1 自定义事件集成指引.md?raw";
@@ -167,6 +168,7 @@ const docs = {
UcloudCloudWatch,
Nagios,
JDCloudMonitor,
- AliyunPrometheus
+ AliyunPrometheus,
+ HttpPull
};
export default docs;