Skip to content

feat: 增强 Webhook POST 请求配置 - #305

Open
DoSerZBlock wants to merge 5 commits into
MistEO:mainfrom
DoSerZBlock:agent/fixed-post-webhook
Open

feat: 增强 Webhook POST 请求配置#305
DoSerZBlock wants to merge 5 commits into
MistEO:mainfrom
DoSerZBlock:agent/fixed-post-webhook

Conversation

@DoSerZBlock

@DoSerZBlock DoSerZBlock commented Jul 31, 2026

Copy link
Copy Markdown

概述

  • 将内置 Webhook 从仅支持 URL 的 GET 请求扩展为固定 POST + JSON 配置
  • 支持 {title}{content}{time} 消息模板变量
  • 支持最多两组可选自定义请求头,并忽略未完整填写的请求头槽位
  • 增加超时、非成功状态码处理与敏感 URL 日志脱敏

问题与原因

原有 MXU_WEBHOOK_ACTION 只能发送 GET 请求,无法直接适配 Discord、企业通知服务等要求 POST JSON 的 Webhook。初版实现还将 JSON 模板作为普通字符串替换,通知内容包含引号或反斜杠时可能生成无效 JSON;自定义请求头只填写一组时,也会发送另一组空凭据。

本 PR 先将模板解析为 JSON 结构,再替换变量并交由 serde_json 序列化,同时过滤名称或值为空白的请求头配置。

主要变更

  • src-tauri/src/mxu_actions.rs
    • 支持请求方法、请求头、JSON 请求体模板、超时与失败策略
    • 对日志中的 Webhook URL 进行脱敏
    • 正确转义模板变量内容
    • 忽略未使用的自定义请求头槽位
    • 增加模板转义与单请求头配置的回归测试
  • src/types/specialTasks.ts
    • 增加固定 POST、消息模板与可选请求头配置
  • src/i18n/locales/*
    • 补充简体中文、繁体中文、英文、日文和韩文界面文本

验证

  • pnpm build
  • cargo test --manifest-path src-tauri/Cargo.toml --all-targets(8 个测试全部通过)
  • Rustfmt 检查
  • Prettier 检查
  • git diff --check
  • Fork GitHub Actions:Windows、Linux、macOS 的 x86_64/aarch64 构建均通过

风险与回滚

  • 风险主要集中在 Webhook 请求体序列化和自定义请求头组合
  • 保留无请求体时默认 GET 的后端兼容行为
  • 如需回滚,可直接撤销本 PR,不涉及配置迁移或持久化数据变更

QA 说明

建议合并前使用至少一个真实 Webhook 服务验证默认模板、包含引号或反斜杠的通知内容,以及仅配置一组自定义请求头的场景。

Summary by Sourcery

扩展 MXU Webhook 特殊任务,使其支持可配置的 POST JSON 请求,包括可模板化的请求负载、请求头、超时时间以及更严格的错误处理,同时保持与现有行为的兼容性。

新特性:

  • 添加结构化的 Webhook 配置,支持选择 HTTP 方法、使用包含 {title}{content}{time} 占位符的 JSON 请求体模板、可选的自定义请求头、请求超时时间,以及对非成功状态码的处理。
  • 在前端暴露新的 Webhook 请求选项,包括 URL 校验、通知字段、JSON 请求体模板输入,以及通过开关控制的 UI(最多支持两个自定义请求头)。

改进:

  • 在日志中对 Webhook URL 中的敏感部分进行脱敏,避免泄露令牌或凭据。
  • 改进 Webhook 请求头处理逻辑,跳过不完整的请求头槽位,并校验请求头名称和值。
  • 为增强后的 Webhook 配置添加多语言文案,包括英语、日语、韩语、简体中文和繁体中文。

测试:

  • 添加 Rust 单元测试,用于验证 Webhook 请求体模板中的 JSON 转义是否正确,以及未使用的自定义请求头槽位是否被省略。
Original summary in English

Summary by Sourcery

Extend the MXU webhook special task to support configurable POST JSON requests with templated payloads, headers, timeouts, and stricter error handling while keeping compatibility with existing behavior.

New Features:

  • Add structured webhook configuration supporting HTTP method selection, JSON body templates with {title}, {content}, and {time} placeholders, optional custom headers, request timeout, and non-success status handling.
  • Expose new webhook request options in the frontend, including URL validation, notification fields, JSON body template input, and a switch-driven UI for up to two custom headers.

Enhancements:

  • Mask sensitive parts of webhook URLs in logs to avoid leaking tokens or credentials.
  • Improve webhook header handling to skip incomplete header slots and validate header names and values.
  • Add locale strings for the enhanced webhook configuration in English, Japanese, Korean, Simplified Chinese, and Traditional Chinese.

Tests:

  • Add Rust unit tests to verify correct JSON escaping in webhook body templates and omission of unused custom header slots.

- Parse body templates as JSON before placeholder substitution to preserve escaping
- Restore the WinSafe API supported by the locked dependency
- Move webhook task definitions and translations into existing project registries
- Add a regression test for quoted and escaped webhook content

Affects: src-tauri/src/mxu_actions.rs, src/types/specialTasks.ts, src/i18n/locales/*

Risk: 中,調整 Webhook 請求序列化與特殊任務設定結構

Refs: PR #4

Breaking-Change: None
- Skip custom header slots whose name or value is blank
- Preserve valid header values without normalization
- Add regression coverage for one-header configuration

Affects: src-tauri/src/mxu_actions.rs

Risk: 低,仅过滤无法使用的空白请求头配置

Refs: None

Breaking-Change: None
@DoSerZBlock
DoSerZBlock marked this pull request as ready for review July 31, 2026 07:19
Copilot AI review requested due to automatic review settings July 31, 2026 07:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我发现了 1 个问题。

供 AI 代理使用的提示
请解决本次代码审查中的以下评论:

## 逐条评论

### 评论 1
<location path="src/types/specialTasks.ts" line_range="386-387" />
<code_context>
+      label: 'specialTask.webhook.headerNameLabel',
+      default: 'Authorization',
+      pipeline_type: 'string',
+      verify: '^[A-Za-z0-9-]+$',
+      pattern_msg: 'specialTask.webhook.headerNameError',
+      placeholder: 'specialTask.webhook.headerNamePlaceholder',
+    },
</code_context>
<issue_to_address>
**suggestion (bug_risk):** 头名称的校验正则比 HTTP 规范更严格,可能会拒绝一些合法的头名称。

当前 `header_1_name` / `header_2_name` 使用的模式 `^[A-Za-z0-9-]+$` 会排除掉符合 RFC 7230 的部分 `tchar`(例如下划线),因此某些合法的头名称会被前端界面拦截,而后端仍然可以接受它们。建议将正则与 RFC 允许的字符集对齐,或者将验证逻辑下放到 `build_webhook_headers`,以避免拒绝合法的头名称。

建议实现:

```typescript
      // RFC 7230 header field-name: 1*("!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
      //                            "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA)
      // This regex allows the full tchar set while still preventing whitespace and control chars.
      verify: "^[!#$%&'*+\\-.^_`|~0-9A-Za-z]+$",

```

1. 请在其他头名称输入(例如 `header_2_name`)上也应用相同的正则更新,只要它们目前使用的是 `^[A-Za-z0-9-]+$`,以确保所有头名称字段的行为一致。
2. 如果后端在 `build_webhook_headers` 中已经执行了更严格或不同的验证,请仔细检查此客户端正则模式不会与后端规则冲突;如果你决定完全依赖后端验证,则可以从这些头名称输入中移除 `verify`/`pattern_msg` 属性。
</issue_to_address>

Sourcery 对开源项目免费——如果你觉得我们的审查有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点击 👍 或 👎,我会根据这些反馈改进后续的审查。
Original comment in English

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="src/types/specialTasks.ts" line_range="386-387" />
<code_context>
+      label: 'specialTask.webhook.headerNameLabel',
+      default: 'Authorization',
+      pipeline_type: 'string',
+      verify: '^[A-Za-z0-9-]+$',
+      pattern_msg: 'specialTask.webhook.headerNameError',
+      placeholder: 'specialTask.webhook.headerNamePlaceholder',
+    },
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Header name validation regex is stricter than HTTP allows and may reject some legitimate header names.

The current `^[A-Za-z0-9-]+$` pattern for `header_1_name` / `header_2_name` excludes valid RFC 7230 `tchar`s (e.g., underscores), so some legitimate header names will be blocked by the UI while the backend can still accept them. Consider aligning the regex with the RFC’s allowed characters or deferring validation to `build_webhook_headers` to avoid rejecting valid headers.

Suggested implementation:

```typescript
      // RFC 7230 header field-name: 1*("!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
      //                            "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA)
      // This regex allows the full tchar set while still preventing whitespace and control chars.
      verify: "^[!#$%&'*+\\-.^_`|~0-9A-Za-z]+$",

```

1. Apply the same regex update to any other header name inputs (e.g., `header_2_name`) that currently use `^[A-Za-z0-9-]+$`, so the behavior is consistent across all header name fields.
2. If the backend already performs stricter or different validation in `build_webhook_headers`, double-check that this client-side pattern does not conflict with backend rules; if you decide to fully defer to backend validation instead, you can remove the `verify`/`pattern_msg` properties from these header name inputs.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/types/specialTasks.ts Outdated
- Align frontend validation with HTTP tchar rules to accept valid custom header names
- Apply the same validation to both header name inputs for consistent behavior

Affects: src/types/specialTasks.ts
Risk: 低,僅放寬前端格式驗證且後端仍執行 HeaderName 驗證
Refs: MistEO#305
Breaking-Change: None
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants