Skip to content

feat: 智能配图 + 支持随机选择样式模板#595

Open
Meloyg wants to merge 5 commits intoxpzouying:mainfrom
Meloyg:feat/add-GenerateCover-publish-post
Open

feat: 智能配图 + 支持随机选择样式模板#595
Meloyg wants to merge 5 commits intoxpzouying:mainfrom
Meloyg:feat/add-GenerateCover-publish-post

Conversation

@Meloyg
Copy link
Contributor

@Meloyg Meloyg commented Mar 21, 2026

描述

在智能配图(generate_cover)流程中,新增随机选择样式模板的能力。会从可用的样式卡片中随机选取一个,使生成的封面更加多样化。

同时优化了 waitAndSelectGeneratedCover 的流程控制逻辑,修复了选择模板后"下一步"按钮未被正确点击的问题。

新增

  • randomSelectTemplate(page) 函数:通过 go-rod CSS 选择器 div.cover-list-container div.cover-item-container 查找所有样式卡片,过滤可见元素后随机点击其中一个

优化

  • waitAndSelectGeneratedCover() 重构:
    • 在首次发现"下一步"按钮时,先调用 randomSelectTemplate 随机选择模板
    • 选择模板后等待 2s 预览重新加载,再重新进入循环获取新的按钮引用
    • 使用 templateSelected 标志位确保模板只选择一次
    • 点击失败时通过 continue 重试,而非直接退出

测试

  • 构建通过:go build
  • 使用 generate_cover: true 参数发布内容,确认随机模板选择生效(日志输出 随机选择了样式卡片 index=N total=10
  • 确认"下一步"按钮在模板选择后正确点击
  • 确认配图完成后正常回到发布页并成功发布

fixes #553

@Meloyg Meloyg requested a review from xpzouying as a code owner March 21, 2026 07:49
@kimi-agent-bot
Copy link
Contributor

🔍 Kimi Code Agent 正在自动审查此 PR...

@Meloyg Meloyg changed the title feat: 智能配图支持随机选择样式模板 feat: 智能配图 + 支持随机选择样式模板 Mar 21, 2026
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2b999a836e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +445 to +449
trimText := strings.TrimSpace(text)
slog.Info("找到红色按钮", "text", trimText)

// 确保点击的是"下一步"按钮,不是其他红色按钮
if err := btn.Click(proto.InputMouseButtonLeft, 1); err != nil {

Choose a reason for hiding this comment

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

P1 Badge Limit the selector to the cover wizard's Next button

When Xiaohongshu skips the separate cover step and returns directly to the publish page (the fallback this function already anticipates), page.Element("button.bg-red") can resolve to the normal publish button instead of a wizard “下一步” button. submitPublish later targets .publish-page-publish-btn button.bg-red, so this broad selector will hit the same control and can publish/navigate away before the正文、标签、定时等 fields are filled.

Useful? React with 👍 / 👎.

Comment on lines +460 to +464
slog.Info("配图完成,已回到发布页", "count", len(images))
return nil
}
time.Sleep(2 * time.Second)
return nil

Choose a reason for hiding this comment

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

P2 Badge Wait for the preview before treating cover generation as done

After clicking the red button, this path returns success even when no generated image preview is visible yet. On slower cover-generation or page-transition timings, callers proceed as though an image exists and only fail later in the publish flow because the post still has no uploaded cover. This should keep polling until .img-preview-area .pr appears or the timeout expires.

Useful? React with 👍 / 👎.

Copy link
Contributor

@kimi-agent-bot kimi-agent-bot bot left a comment

Choose a reason for hiding this comment

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

🔍 代码审查 — PR #595: feat: 智能配图支持随机选择样式模板

📋 概述

本 PR 为发布流程新增了"智能配图"功能:用户开启 generate_cover 参数后,系统自动点击"文字配图"按钮、输入标题、生成封面,并随机选择一个样式模板。改动涉及 4 个文件,+390/-69 行。

整体功能思路清晰,端到端打通了 MCP 参数 → 服务层 → 浏览器自动化的链路。以下是具体审查意见:


✅ 优点

  1. 参数传递链路完整GenerateCovermcp_server.gomcp_handlers.goservice.gopublish.go 一路贯通,没有遗漏。
  2. 校验逻辑合理:在 service.gopublish.go 两层都做了"图片和智能配图至少选一个"的互斥校验,错误信息也给出了可操作的提示。
  3. getContentElement 改进:将 MustDo() 改为 Do() 并妥善处理错误、增加 debug HTML 片段输出,增强了健壮性。
  4. findTextboxByPlaceholder 改进:把 MustElements 改为 Elements,避免 panic。

⚠️ 需要关注的问题

1. 🔴 titleAlreadyEntered 参数始终为 false,属于无效代码

// publish.go:107
submitPublish(page, content.Title, content.Content, tags, ..., false)

submitPublish 新增了 titleAlreadyEntered bool 参数,但唯一的调用方总是传 false。这意味着:

  • 智能配图模式下标题会被重复输入(配图时输入一次,submitPublish 里又输入一次)。
  • 如果标题不需要重复输入,应该在 content.GenerateCover 时传 true
  • 如果当前逻辑就是需要传 false,那么这个参数完全不需要添加。

建议:明确意图 —— 如果智能配图模式下标题已在配图阶段输入,调用处应改为:

submitPublish(page, ..., content.GenerateCover)

2. 🟡 clickGenerateButton 找不到按钮时静默返回 nil

// publish.go:351-353
slog.Info("未找到独立生成按钮,可能已自动触发生成")
return nil

如果生成按钮确实不存在且也没有自动触发生成,流程会静默继续但后续 waitAndSelectGeneratedCover 可能会超时等待 30s 才报错。建议至少返回一个明确的 warning 级别日志或考虑是否应该 return error。

3. 🟡 inputTextForCover 中的剪贴板方式在 headless 模式下可能不可靠

// publish.go:284-293
_, err = page.Eval(`(text) => {
    const ta = document.createElement('textarea');
    ta.value = text;
    ...
    document.execCommand('copy');
    ...
}`, text)

document.execCommand('copy') 已被标记为 deprecated,且在 headless Chrome 中可能因为安全策略而不生效。如果运行环境是 headless 模式,建议考虑使用 rodElement.Input() 或 CDP Input.insertText 等更可靠的方式。

4. 🟡 waitAndSelectGeneratedCover 中对"下一步"按钮的选择器过于宽泛

// publish.go:431
btn, err := page.Element("button.bg-red")

button.bg-red 可能匹配到页面上其他红色按钮。虽然后面有日志打印按钮文本,但没有实际校验文本内容就直接点击了。建议增加文本校验:

text, _ := btn.Text()
if !strings.Contains(strings.TrimSpace(text), "下一步") {
    continue // 不是目标按钮,跳过
}

5. 🟡 Images 字段移除了 binding:"required,min=1" 校验标签

// service.go 原来:
Images []string `json:"images" binding:"required,min=1"`
// 现在:
Images []string `json:"images"`

直接移除 binding 标签后,如果有其他调用方(如 REST API)依赖 gin 的 binding 校验,会导致校验失效。虽然代码层有互斥校验兜底,但建议确认是否有其他入口受影响。

6. 🟢 math/rand 使用方式在 Go 1.24 下没问题

Go 1.20+ 已自动做全局 seed,Go 1.24 下 rand.Intn() 无需手动 seed,这里的用法正确。

7. 🟢 硬编码的 time.Sleep 较多,但可以理解

浏览器自动化中大量 time.Sleep(2 * time.Second) 等硬编码等待是常见做法。当前阶段可以接受,后续可考虑用 rod 的 WaitStable/WaitVisible 等 API 替代部分固定等待。


💡 其他建议

  1. 日志一致性:新增函数使用 slog.Info/Warn,而已有代码使用 logrus.Infof/Warnf。建议统一日志库,或在 PR 描述中说明迁移计划。

  2. getContentElement[contenteditable='true'] 选择器过于宽泛:智能配图模式下,配图界面的 contenteditable 输入框可能也匹配到这个选择器,导致在回到发布页后错误地找到了非正文编辑器。建议配合更精确的父容器选择器。

  3. 建议补充单元测试/集成测试:当前新增了约 300 行逻辑代码,如果条件允许,建议对关键路径(如参数校验逻辑、Generate Cover 流程的状态机)编写测试。


📊 总结

维度 评价
功能完整性 ✅ 参数链路完整,核心流程可用
代码质量 ⚠️ titleAlreadyEntered 参数当前无意义,需确认意图
健壮性 ⚠️ 部分选择器宽泛、静默忽略错误
可维护性 🟡 日志库混用、缺少测试

建议:请优先解决 titleAlreadyEntered 参数的问题(第 1 点),其余为改进建议,可后续迭代处理。

@kimi-agent-bot
Copy link
Contributor

Now let me look at the full context of the changed files to better understand the code:
I need to understand the existing code in the repository xpzouying/xiaohongshu-mcp to review a PR. Please look at the following files to understand the patterns used:

  1. xiaohongshu/publish.go - read the full file to understand the existing patterns, especially removePopCover, isElementVisible, existing imports, and how submitPublish is called
  2. service.go - read the full file to understand how PublishContent validates things
  3. mcp_server.go - to see how the tool registration works

Focus on:

  • How error handling is done
  • Whether math/rand is imported/used
  • Whether removePopCover function exists
  • The function signature of submitPublish and all callers
  • How isElementVisible works
    In the repo xpzouying/xiaohongshu-mcp, I need to find all callers of submitPublish in the codebase to check if the new parameter titleAlreadyEntered bool was added correctly to all call sites. Search for "submitPublish" across all files and show the context around each usage. Also check if removePopCover exists in xiaohongshu/publish.go and if math/rand is imported.
    Now let me check the titleAlreadyEntered parameter usage - the PR always passes false, which seems unused:
    Now let me also check the Go version/build to verify the math/rand usage:
    Now I have all the information I need. Let me compose the review:
    已完成对 PR feat: 智能配图 + 支持随机选择样式模板 #595 的代码审查,审查意见已发布到 GitHub PR 页面。以下是审查要点总结:

主要发现

  1. 🔴 关键问题submitPublish 新增的 titleAlreadyEntered 参数始终传 false,智能配图模式下标题会被重复输入。应该在智能配图模式下传 true(即 content.GenerateCover)。

  2. ⚠️ 需关注

    • clickGenerateButton 找不到按钮时静默返回 nil,可能导致后续 30s 超时
    • 剪贴板方式 (document.execCommand('copy')) 在 headless 模式下可能不可靠
    • button.bg-red 选择器过于宽泛,未校验按钮文本就直接点击
    • Images 字段移除了 binding 校验标签,需确认对其他入口的影响
  3. ✅ 优点:参数传递链路完整,校验逻辑合理,getContentElementfindTextboxByPlaceholder 的错误处理改进值得肯定。

Meloyg added 3 commits March 21, 2026 22:25
- 新增 randomSelectTemplate: 从配图预览页随机选择样式卡片
- 优化 waitAndSelectGeneratedCover: 模板选择后正确重试下一步按钮
- 修复 submitPublish: 智能配图模式下始终输入标题,不再跳过
- waitAndSelectGeneratedCover: 校验按钮文本包含'下一步'再点击,避免误点发布按钮
- waitAndSelectGeneratedCover: 点击后轮询5次确认预览图出现,不再直接返回
- submitPublish: 输入正文前先Ctrl+A+Backspace清空已有内容(配图模式下XHS自动填入标题)
- submitPublish: 移除titleAlreadyEntered参数,始终输入标题
@Meloyg
Copy link
Contributor Author

Meloyg commented Mar 22, 2026

headless false not working properly, investigating

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.

期望支持小红书自带的主图生成功能

1 participant