Skip to content

feat(messaging/feishu): AskUserQuestion 按钮交互 + docs 同步更新#474

Merged
hrygo merged 8 commits into
hrygo:mainfrom
aaronwong1989:feat/feishu-question-action-buttons
May 22, 2026
Merged

feat(messaging/feishu): AskUserQuestion 按钮交互 + docs 同步更新#474
hrygo merged 8 commits into
hrygo:mainfrom
aaronwong1989:feat/feishu-question-action-buttons

Conversation

@aaronwong1989
Copy link
Copy Markdown
Contributor

@aaronwong1989 aaronwong1989 commented May 21, 2026

Summary

  • AskUserQuestion 卡片使用 JSON 1.0 action 按钮替代 markdown 列表,支持 copy_text 一键复制选项
  • 修复 buildV1Card 结构错误(body 包装 → 根级 elements,符合 JSON 1.0 规范)
  • 始终显示编号选项列表作为 fallback(按钮可能在部分客户端不渲染)
  • 合并 docs/patrol-2026-05-22 文档更新(admin API、飞书交互、安全模型)

Changes

代码 (3 files):

  • card_template.go — 新增 buildV1Card (JSON 1.0) + buildQuestionElements
  • interaction.gosendQuestionRequest 改用 v1 card builder
  • card_template_test.go — 新增 TestBuildV1Card + TestBuildQuestionElements 覆盖

文档 (3 files, from #475):

  • docs/reference/admin-api.md — admin API cron paths, restart endpoint
  • docs/tutorials/feishu-integration.md — CardKit v2 交互按钮说明
  • docs/explanation/security-model.md — 安全模型更新

Closes #475

🤖 Generated with Claude Code

Sisyphus 🏔️ and others added 4 commits May 21, 2026 23:13
…tion options

Replace markdown bullet list with CardKit v2 `action` elements containing
`copy_text` buttons. Users tap a button to copy the option label, then
paste it in chat to respond. Options with descriptions show a numbered
reference list above the buttons for context.

Fixes hrygo#457

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ion + copy_text

JSON 2.0 does not support tag:"action" interactive modules or copy_text
click behavior (confirmed by official Feishu docs). Question cards now use
buildV1Card which omits the schema field, defaulting to JSON 1.0 where
action + copy_text buttons work correctly.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Options are now always rendered as a numbered list in the markdown element,
regardless of whether descriptions exist. This ensures options remain visible
if the action buttons fail to render on any client.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ildV1Card

JSON 1.0 cards use "elements" at root level, not "body":{"elements":...}.
Also fix misleading "CardKit v2" comments to accurately reflect JSON 1.0 usage.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
hotplex-ai
hotplex-ai previously approved these changes May 22, 2026
Copy link
Copy Markdown
Owner

@hotplex-ai hotplex-ai left a comment

Choose a reason for hiding this comment

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

审查摘要

飞书 AskUserQuestion 交互改造,3 个文件,+252/-25。

审查通过项

  • buildV1Card() 正确构建 JSON 1.0 卡片(无 schema/body wrapper),测试验证通过
  • buildQuestionElements() 实现完整:编号列表作为按钮 fallback(良好 UX 决策),copy_text 按钮组逻辑清晰
  • sendQuestionRequest() 从手工字符串拼接重构为声明式元素构建,代码可读性显著提升
  • 5 组 table-driven 测试覆盖:有/无 description、无选项、多问题、空 header、完整 round-trip
  • 使用 JSON 1.0 的决策合理(action + copy_text 不支持 JSON 2.0)

亮点

  • 编号列表 fallback 确保不支持按钮的客户端仍可正常使用
  • t.Parallel() 全覆盖
  • 元素构建与组装分离,便于单元测试

Fixes #457

…l docs

- admin-api.md: fix cron paths /api/cron/ → /admin/cron/, add restart
  endpoint, add API Key User Management section (5 endpoints)
- feishu-integration.md: update Q&A interaction to describe CardKit v2
  copy_text buttons instead of text-only response
- security-model.md: add APIKeyResolver enterprise multi-user session
  isolation to Layer 2 description

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@aaronwong1989 aaronwong1989 changed the title feat(messaging/feishu): AskUserQuestion 选项使用 CardKit v2 按钮渲染 feat(messaging/feishu): AskUserQuestion 按钮交互 + docs 同步更新 May 22, 2026
…recated soul field

- admin-api.md: /api/cron/* → /admin/cron/* (7 routes, scope table, descriptions, curl example)
- admin-api.md: /admin/health/ready exempted from Bearer token auth for k8s probes
- configuration.md: remove per-bot soul field (removed from SlackBotConfig and FeishuBotConfig)
hotplex-ai
hotplex-ai previously approved these changes May 22, 2026
Copy link
Copy Markdown
Owner

@hotplex-ai hotplex-ai left a comment

Choose a reason for hiding this comment

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

PR #474 审查报告 — hotplex-ai 三维度自动审查

裁决: APPROVE

代码质量: PASS

  • DRY/SOLID/命名/错误处理/风格均通过
  • buildQuestionElements 纯函数提取,消除 sendQuestionRequest 内联重复
  • WARN (低): buildQuestionElements vs buildQuestionFallbackText 的 header 默认值和 option 格式化存在概念重复

非功能性: PASS

  • 性能: strings.Builder + 预分配 slice,无 DB 查询/锁竞争
  • 安全: copy_text 按钮为纯客户端操作,无 XSS/SSRF 向量。Worker 数据经 JSON encoder 转义
  • 并发: 新代码为纯函数无共享状态,无 goroutine/channel/mutex 引入

集成与防腐: PASS

  • 文档: 直接变更的 admin-api.md 与代码一致(cron 路由、health 认证豁免)
  • 测试: 7 个子测试覆盖正常/边界场景,t.Parallel + testify/require
  • API 兼容性: 无破坏性变更,新函数均为 unexported
  • 依赖: 零新增依赖

非阻塞性建议

  1. docs/specs/AI-Native-Cronjob-Spec.md 等 3 个文档仍有旧 /api/cron/ 路径,建议后续批量更新
  2. buildQuestionElements 按钮文本未调用 SanitizeText()(与现有 buildInteractionCard 模式一致,但与文本消息处理不一致)
  3. events.Question.MultiSelect 字段被静默忽略(新旧代码均如此)

…x docs paths

- buildQuestionElements: call SanitizeText() on all user-facing text
  (header, question, label, description) to match text message pattern
- MultiSelect: show "(可多选)" in card, dynamic footer hint, fallback
  text multi-select prompt — previously silently ignored
- Docs: /api/cron/ → /admin/cron/ in AI-Native-Cronjob-Spec and
  Turns-Materialized-Table-Spec to match actual routes.go

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
hotplex-ai
hotplex-ai previously approved these changes May 22, 2026
Copy link
Copy Markdown
Owner

@hotplex-ai hotplex-ai left a comment

Choose a reason for hiding this comment

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

三维度审查报告

代码质量: PASS (8.5/10)

  • DRY: buildV1CardbuildCard 分离合理,V1/V2 差异明确
  • SOLID: buildQuestionElements / questionFooterHint / buildV1Card 职责分离清晰
  • 所有用户输入经 messaging.SanitizeText() 清洗
  • 错误处理 %w 包装规范,卡片发送失败有 text fallback

非功能性(安全+性能+并发): PASS (9/10)

  • 安全: copy_text 按钮无服务端回调,天然无注入风险;owner 验证防跨用户响应
  • 性能: button slice 预分配,strings.Builder 使用合理
  • 并发: 所有新增函数为纯函数,无共享可变状态,线程安全

集成与防腐: PASS (8.5/10)

  • 文档与代码行为一致(feishu-integration.md、admin-api.md)
  • 测试覆盖充分(7 个子测试 + round-trip)
  • V1/V2 卡片隔离正确,无向后兼容问题
  • 无新增外部依赖

WARN 项(建议后续处理):

  1. buildQuestionFallbackText 未调用 SanitizeText(预存在问题,本 PR 扩大了不一致)
  2. questionFooterHint() MultiSelect 路径缺少直接测试
  3. SanitizeText 调用存在冗余(3N vs 2N),可预计算一次
  4. 测试风格与既有 table-driven 模式不完全一致

结论:代码质量高,安全设计合理(copy_text 无回调),变更范围可控。WARN 项均为低优先级改进,不阻塞合并。

…t, table-driven tests

- Pre-compute sanitized options slice in buildQuestionElements (2N vs 3N)
- Add SanitizeText calls to buildQuestionFallbackText (was missing)
- Add TestQuestionFooterHint table-driven test (4 cases: nil/single/multi/mixed)
- Convert multi_select subtests to table-driven style matching project conventions

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@hrygo hrygo merged commit 66a21d2 into hrygo:main May 22, 2026
6 checks passed
@aaronwong1989 aaronwong1989 deleted the feat/feishu-question-action-buttons branch May 22, 2026 05:23
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.

3 participants