---
name: lov-publish-wechat-channels
description: >-
  通过已登录的视频号助手网页预检、上传并发布本地视频，按用户明确的标题、描述、话题、封面和原创设置逐项回读，并从内容列表核验草稿、定时、审核与发布状态。Use when the user asks“发布视频号”“保存草稿”“定时发布”或“核验状态”；不用于公众号文章。
license: MIT
compatibility: >-
  Requires Python 3.8+ for the read-only media preflight and a user-visible,
  already logged-in browser session that can open channels.weixin.qq.com. It
  uses the visible web workflow only and does not require WeChat credentials or
  private API access.
metadata:
  author: lovstudio
  version: "0.0.2"
  tags:
    - wechat
    - channels
    - video-publishing
    - browser-automation
---

# 发布微信视频号内容

只操作 `https://channels.weixin.qq.com` 下的视频号助手可见网页，新建入口为 `https://channels.weixin.qq.com/platform/post/create`。把页面当作动态界面：每一步重新读取当前页面，按语义定位控件，不依赖历史 CSS 选择器或坐标。

## Triggers

### Activate when

- 用户要求发布微信视频号视频或保存视频号草稿。
- 用户要求安排视频号定时发布或核验视频号发布状态。
- 用户在同一会话中要求基于上一版内容重发本地视频。

### Do not activate when

- 用户只要求发布微信公众号文章或调用公众号接口。
- 用户只要求本地媒体预检，不涉及视频号页面发布。

## 读取输入

开始前取得以下输入：

- 必填：目标动作 `draft` / `schedule` / `publish` / `status`，以及预期视频号名称。
- `draft` / `schedule` / `publish` 必填：本地视频路径；`schedule` 还需带时区的发布时间。
- `status` 必填：条目链接、条目 ID，或足以唯一定位的文案前缀、文件名和提交时间窗口。
- 可选：文案、话题、封面图片或封面帧、位置、合集、原创声明、评论等当前页面支持的设置。

只填写用户给出的可选项。把当前会话中用户已经确认的主题、标题、描述、话题、封面和原创要求视为本次输入；用户说“基于上一版”或“重新发一遍”时，沿用本会话最后一版已确认的内容设置，不把这些字段静默留空。不要补写与主题无关的事实或宣传语。

原创声明、广告、可见范围、位置、合集和评论都属于会改变发布语义的选项：用户明确提出时执行，未提出时保持平台默认。用户明确说“原创需要”“声明原创”时，完成平台出现的原创须知/使用条款勾选，并在提交前再次读取原创复选框的已选状态。

如果用户只说“我的视频号”，且页面仅展示一个清晰的已登录账号名称，记录该名称并在提交前回报；出现账号选择器、多个账号或模糊头像时先确认。若用户要求的标题、描述、话题或原创声明在页面回读中缺失，停在提交前，指出具体缺失字段，不点击发布。

## 执行流程

1. 对 `draft` / `schedule` / `publish`，先读 [平台约束](references/platform-constraints.md)，再从 `SKILL.md` 所在目录解析脚本路径，运行只读预检：

   ```bash
   python3 <本 Skill 目录>/scripts/check_video.py <视频路径> --json
   ```

   硬错误出现时停在预检阶段并回报；警告不阻断，但需在上传前明确列出。若当前页面明确显示账号已开放 20 GiB / 8 小时，可记录页面原文后以 `--max-gb 20 --max-hours 8` 重跑。实时页面限制更低时，服从更低限制。`status` 是只读查询，跳过视频预检与上传。

2. 读 [浏览器工作流](references/browser-workflow.md)，打开创建页。优先复用用户已允许控制的前台可见浏览器；不要争夺不在前台的 Yoda 或其他浏览器控制权。
3. 若出现登录二维码，把浏览器交给用户扫码和选账号；等待用户完成后重新读取页面。不要代填凭据或绕过登录。
4. 读取页面展示的视频号名称并与预期账号逐字核对。只有一个清晰账号且用户说“我的视频号”时记录该名称；账号不符、出现多个候选或页面仅显示模糊头像时停下确认。
5. 汇总当前会话中已确认的字段，形成提交前字段表：短标题、描述、话题、封面、位置、合集、原创、评论和可见范围。账号、目标动作及该动作所需输入均明确后，把状态记为 `prepared`。
6. `status` 直接打开内容管理列表并执行第 9 步。其他动作通过当前上传区域关联的文件选择控件提交原视频。观察到上传进度后记为 `uploading`；进度到 100% 后仍等待平台转码、缩略图或素材解析，记为 `processing`。
7. 只在素材解析完成且页面未显示视频错误后填写文案、封面与可选项。逐项回读字段表中的已确认值：短标题和描述要读取实际文本，话题要读取已添加的话题标签，原创要读取复选框/原创弹窗的最终状态。封面未指定时保留平台默认封面。任何用户明确要求的字段未持久化时，停在提交前。
8. 按目标动作进入对应分支：
   - `draft`：选择“保存草稿”语义的动作，确认完成后进入内容管理的草稿列表并重载。
   - `schedule`：启用“定时发布”，核对页面时区、日期和时间，确认提交后进入内容列表并重载。
   - `publish`：选择“发布/发表”语义的主动作，核对确认弹窗、账号、内容字段和原创状态后只提交一次，再进入内容列表并重载。
   - `status`：不修改条目；打开与目标标识匹配的内容列表并重载，读取平台状态原文。
9. 用账号及当前可用的条目 ID、链接、视频文件名、文案前缀、提交时间、封面等组合指纹查找唯一条目。记录列表状态、条目链接或 ID、回读时间与页面 URL。

## 状态契约

状态只使用下列值；出错时保留最后一个已确认状态，把错误另列：

| 状态 | 成立证据 |
| --- | --- |
| `prepared` | 账号核对和动作所需输入均完成；写入动作也已通过只读预检 |
| `uploading` | 页面出现本次文件的实际上传进度 |
| `processing` | 上传完成，平台仍在转码、解析或生成封面 |
| `draft_saved` | 草稿列表重载后找到唯一匹配条目 |
| `scheduled` | 内容列表重载后找到匹配条目和正确定时时间/状态 |
| `platform_pending` | 内容列表重载后找到唯一条目，状态明确为转码、审核或发布处理中 |
| `published` | 内容列表重载后找到匹配条目，且列表明确显示已发布/已发表状态 |
| `publish_failed` | 内容列表重载后找到唯一条目，且列表明确显示失败、拒绝或终止状态 |

成功提示、按钮消失、请求返回或创建页跳转都不单独证明 `published`。没有列表重载回读时，停留在最后一个已证实状态。

## 收口错误

- 提交后超时或页面状态不明时，不要再次点击发布；先去内容列表重载回读，防止重复内容。
- 上传或处理失败时记录页面原文、文件名、预检摘要、账号、当前 URL、最后状态与发生时间；保留源视频不变。
- 页面结构变化时重新获取页面快照，以角色、可见名称、标签和邻近文案定位；存在多个候选时停止点击并报告候选。
- 上传区可能位于子 frame 或 shadow DOM 中，标准 CSS 选择器找不到关联文件输入时，先重新读取当前 frame tree/DOM（使用可穿透子 frame/shadow root 的只读定位），再对当前上传区的文件控件提交路径；不复用旧的节点 ID、句柄或坐标。
- 列表若显示“原创审核中”“审核中”“转码中”或其他处理中原文，状态使用 `platform_pending`，即使创建页出现成功提示或已经跳转列表，也不要写成 `published`。只有列表明确显示“已发布/已发表”才使用 `published`。
- 最终回报目标动作、账号、最后状态、平台状态原文、列表回读证据、警告和未完成项。只有满足状态契约时才使用 `draft_saved`、`scheduled`、`platform_pending`、`published` 或 `publish_failed`。
