消费医疗加白adhome

👤 user_1994fdeb 📦 v1.0.3 ⭐ 4.4 ⬇️ 341 下载
📈 商业运营 免费

📖 技能介绍


name: adhome-whitelist-v3 description: 消费医疗加白V3。当用户提到「加白」「加白第N行」「ADHome」「adhome」「白名单」「机构准入」「消费医疗加白」时触发。支持企微文档+腾讯文档双源读取,自动下载附件(优先docx,禁止静默降级PDF),智能填表提交,分类级联选择器修复,信号文件确认机制,审批状态追踪,企微Webhook通知。 dependencies: [] allowed-tools: disable: false


ADHome 广告账户加白自动化 v2

概述

自动完成 ADHome(adhome.woa.com)广告账户加白(机构准入评估)申请的全流程。经过 10+ 次实战迭代优化,具备信号文件确认机制确保安全提交。

核心能力: - 双源文档读取:企微文档(Playwright)+ 腾讯文档(MCP 导出 xlsx) - 智能附件下载:优先 docx 导出(企微文档菜单导出 / 腾讯文档 Chrome profile 登录导出),下载失败时提醒用户而非静默降级 - 自动填写 ADHome 表单(Playwright 浏览器自动化) - 分类级联选择器精确匹配(三列独立选择,叶子节点 radio) - 信号文件机制:填表→截图→用户按钮确认→提交(防误操作) - ADHome Cookie 自动刷新(iOA 验证)+ 每次登录后必须保存 Cookie - 企微 Webhook 通知(两层:脚本层+Agent层)+ 审批状态定时追踪


⚡ 执行流程总览

重要:严格按此流程执行,不要添加额外步骤。

可跳过的步骤(永久跳过)

  • ❌ 不需要安装 agent-browser / wecom-doc skill
  • ❌ 不需要运行 precheck.py 预审
  • ❌ 不需要 dry-run 确认
  • ❌ 不需要检查 Node/Python/Playwright 依赖(已安装就绪)
  • ❌ 不需要每次手动传 webhook 地址

单行任务:6 步流程

用户: "加白第N行" + 文档链接
         │
    ┌────┴────┐
    │  前置检查  │
    └────┬────┘
         │
   0️⃣ Webhook 配置检查(首次触发)
      ├─ user_config.json 存在? → YES → 读取 webhook
      └─ NO → 引导用户配置 → 保存
         │
   ① 识别文档类型并读取第N行数据
      ├─ doc.weixin.qq.com → Playwright + 企微Cookie
      └─ docs.qq.com → MCP export_file 导出 xlsx + openpyxl
      ⚠️ 必须先读表头确认列映射
         │
   ② 定位/下载素材文件(⚠️ 附件格式优先级:docx > 图片 > PDF)
      ├─ 本地搜索 ~/Desktop/加白/
      ├─ 企微文档 → Playwright 菜单导出 docx
      ├─ 腾讯文档 → Chrome profile 登录态 + 菜单导出 docx
      ├─ ⚠️ 下载失败/只能PDF?→ 暂停,提醒用户检查权限和登录态
      │   ├─ 🛑 用户选停止 → 关闭浏览器,终止当前行
      │   └─ 🔄 用户选继续 → 关闭浏览器,修复后重新下载,成功后继续
      └─ 禁止静默降级为 PDF(除非用户明确允许)
         │
   ③ 构建 Config → 后台运行填表脚本(auto_submit: false 必须!)
      → 脚本填完表 → 截图 → 写信号文件 → 轮询等待
         │
   ④ 对话框确认
      → 展示填写内容汇总表格 + 表单截图
      → ✅ 提交 / ❌ 撤回
         │
   ⑤ 验证 + 企微通知(两层)

多行任务:批量准备 + 串行提交

用户: "加白第6行和第7行"
         │
   ① 一次 Playwright/MCP 实例读取所有行数据
         │
   ② 批量下载附件(MCP 可并行导出)
         │
   ③ 逐行串行:
      ├─ 构建 config → 后台填表 → 等待信号
      ├─ 展示确认按钮 → 用户确认
      ├─ 提交 → 验证
      └─ 下一行...
         │
   ④ 一条企微通知汇总所有行结果

第 0 步:Webhook 配置检查(首次使用触发)

说明
配置文件 {SKILL_DIR}/scripts/user_config.json
格式 {"notify_webhook": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY"}
首次引导 检测不到 webhook → 提示用户提供企微群机器人 Webhook 地址 → 写入持久化
后续运行 自动读取,无需重复配置
⚠️ 规则 不同用户有不同 webhook,严禁硬编码

第 1 步:读取文档数据

判断文档类型

URL 域名 文档类型 读取方式
doc.weixin.qq.com 企微文档 Playwright + 企微 Cookie
docs.qq.com 腾讯文档 MCP 导出 xlsx + openpyxl

方式 A:企微文档(Playwright)

7w4.net小葱技能。

  • Cookie:~/.wecom-doc-cookies.json,格式 { "cookies": [...] }
  • 兼容加载:const cookies = Array.isArray(raw) ? raw : raw.cookies || []
  • Name box:input.bar-label | Formula bar:.formula-input
  • ⚠️ 旧选择器 .formula-bar-content .ql-editor 已失效

方式 B:腾讯文档(MCP 导出)

# 1. 导出 xlsx
mcporter call tencent-docs manage.export_file --args '{"file_id":"DSWhDdm5zY1hkeUxq"}'
# 2. 轮询进度(5s)
mcporter call tencent-docs manage.export_progress --args '{"task_id":"xxx"}'
# 3. curl 下载 xlsx → openpyxl 解析

⚠️ smartsheet API 不支持普通 sheet,只支持智能表格 ⚠️ 企微 Cookie 访问 docs.qq.com 时部分列显示"此单元格已开启填写内容隐藏"

⚠️ 列结构不固定

不同文档的列结构可能不同: - 标准格式:A→S 直接对应 19 个字段 - 扩展格式:前 3 列为日期/代理/提报人(A-C),实际数据从 D 列开始,扩展到 V 列

必须先读表头(第 1 行)确认列映射!

标准列映射 A→S

字段
A 选择行业
B 主体名称
C 账户ID(多个用换行分隔)
D 广告主产业身份
E 广告主资本背景
F 资质信息附件
G 品牌名+产品名
H 产品链接方式
I 产品链接
J 外层素材
K 素材落地页方式
L 素材落地页链接
M 投放链路
N 分类
O 投放机构名称
P 竞媒投放消耗
Q 消耗预算
R 保证金豁免
S 备注

扩展列映射(前3列偏移)

字段
A 提报时间
B 提报代理
C 提报人
D→V 同标准 A→S

第 2 步:定位/下载素材文件

⚠️ 支持的文件类型

ADHome 资质附件和素材附件支持多种格式,搜索和下载时必须识别所有以下类型

类别 支持格式
文档 .pdf .doc .docx
图片 .jpg .jpeg .png .bmp .gif

扫描规则: - 搜索本地文件时,按扩展名匹配上述所有格式,不要只找 pdf/doc - 下载附件时,根据原始文件的实际类型保存(文档→保留原格式,图片→保留原格式) - 图片文件直接作为附件路径传入 config 的 qualification_filesmaterial_files 数组 - 脚本 uploadFiles() 通过 input[type="file"] 上传,不限制格式,按实际文件类型上传即可 - ⚠️ 不限制文件数量:有几个文件就传几个,全部放入数组。严禁人为截断或限制为 3 个

搜索顺序

  1. ~/Desktop/加白/ 下按主体名称关键词匹配子目录,扫描所有支持格式的文件
  2. ~/Downloads/附件下载_冀豫-消费医疗2026年/附件/
  3. 找不到 → 自动下载附件

自动下载附件(3种方案)

方案 A:MCP 导出(公开腾讯文档)

mcporter call tencent-docs manage.export_file --args '{"file_id":"xxx"}'
# → export_progress → file_url → curl 下载
# 导出格式取决于原文档类型(docx/xlsx/pdf)

方案 B:腾讯文档 docx 导出(需 Chrome profile 登录态)

⚠️ 关键规则:遇到腾讯文档未登录时,不要直接跳过或降级 PDF,必须先尝试用现有 Cookie 登录!

下载流程: 1. 先用 Chrome profile(~/.workbuddy/chrome-profile-docs)persistent context 打开文档 2. 检查是否已登录(是否有"登录腾讯文档"按钮) 3. 如果已登录 → 直接菜单导出 docx 4. 如果未登录 → 尝试用 Chrome profile 的 Cookie 自动登录(profile 里应该有持久登录态) 5. 登录成功 → 导出 docx 6. Cookie 也失效 → 暂停流程,提醒用户重新登录腾讯文档,不要静默降级 PDF

// 使用 Chrome profile persistent context 获取登录态
const tempBrowser = await chromium.launchPersistentContext(CHROME_PROFILE, {
  headless: false, acceptDownloads: true
});
// 打开文档 → 检查登录状态 → 菜单 → 导出为 → 本地Word文档(.docx)

⚠️ 如果没有登录态(看到"登录腾讯文档"按钮),禁止静默降级 PDF 必须暂停流程,提醒用户检查权限/登录问题,等用户选择继续或停止

方案 C:图片附件直接下载

当附件链接指向图片(jpg/png 等)时:
1. 直接 curl/wget 下载图片到本地临时目录
2. 不需要转 PDF,直接传原始图片文件
3. 文件名保持原始名称或用 "主体名_资质.jpg" 格式

方案 D:docs.qq.com 表格附件(收集表附件)

1. Chrome profile(`~/.workbuddy/chrome-profile-docs`) 获取 Cookie
2. 新浏览器实例 + addCookies(不用 persistent context)
3. 点击附件单元格 → card-group 弹窗 → "打开链接"
4. 判断链接类型:
   - 文档链接 → 方案 B page.pdf() 导出
   - 图片链接 → 方案 C 直接下载

⚠️ persistent context 中 getBoundingClientRect 返回 0,0,必须用新浏览器实例 + addCookies

// 导航到附件单元格 → 点击 formula bar → 触发 alloy-link-block
const fbBox = await formulaBar.boundingBox();
await page.mouse.click(fbBox.x + 50, fbBox.y + fbBox.height / 2);
// 提取链接
const linkData = await page.evaluate(() => {
  const block = document.querySelector('.alloy-link-block.wecom');
  if (block) {
    const detail = block.getAttribute('data-link-detail');
    if (detail) return JSON.parse(detail);
  }
  return null;
});
// linkData.url → 文档 URL

第 3 步:构建 Config + 后台填表

命令

NODE_PATH=/Users/zhanglei/.workbuddy/binaries/node/workspace/node_modules \
/Users/zhanglei/.workbuddy/binaries/node/versions/22.12.0/bin/node \
{SKILL_DIR}/scripts/adhome_fast_apply.js --config <json_path> --headed

Config JSON 模板

{
  "mdm_name": "主体名称(搜索用,名称过长时用前半部分)",
  "account_ids": ["账户ID1", "账户ID2"],
  "industry": "医疗健康-XXX",
  "industry_data_value": "21474838626",
  "advertiser_identity": "品牌商",
  "capital_background": "非上市公司",
  "qualification_files": ["资质文件绝对路径(支持 pdf/doc/docx/jpg/png)"],
  "other_qualification_files": [],
  "brand_product_name": "品牌名+产品名",
  "product_url": "产品链接URL",
  "product_url_type": "URL连接",
  "material_files": ["素材文件绝对路径(支持 pdf/doc/docx/jpg/png)"],
  "material_landing_url": "落地页URL",
  "material_landing_type": "URL连接",
  "release_links": ["原生推广页"],
  "category_path": ["消费医疗", "口腔", "口腔美容"],
  "institution_name": "投放机构名称",
  "competitive_consumption": "5000",
  "cost_budget": "5000",
  "is_deposit_free": "true",
  "auto_submit": false
}

⚠️ auto_submit 必须为 false:填表完成后截图给用户确认,用户说OK后再提交

执行方式

后台运行(nohup)→ 脚本填表 → 截图 → 写 /tmp/adhome_waiting.json → 轮询等待信号

第 4 步:对话框确认(信号文件机制)⭐

信号文件流程

脚本填表完成
     │
     ▼
写 /tmp/adhome_waiting.json ──→ Agent 检测到 → 展示确认界面
     │
     │  轮询 /tmp/adhome_signal.json(每1秒,最多5分钟)
     │
     ▼
收到信号文件
  ├─ {"action":"submit"} → 点击提交 → 截图 → 关闭浏览器
  ├─ {"action":"cancel"} → 关闭浏览器
  └─ 超时(5分钟)      → 关闭浏览器
     │
     ▼
清理信号文件 → 发企微通知 → 退出

Agent 侧操作

  1. 轮询读取 /tmp/adhome_waiting.json 确认填表完成
  2. 读取填表日志确认所有字段状态
  3. 展示截图 + 内容汇总表格
  4. 展示两个按钮供用户选择:
  5. ✅ 提交 → 写 {"action":"submit"}/tmp/adhome_signal.json
  6. ❌ 撤回 → 写 {"action":"cancel"}/tmp/adhome_signal.json
  7. 等待脚本执行完成,查看结果日志

撤回分支

  • 关闭浏览器 → 引导用户说明哪里要改 → 修正 config → 重新走第3步

第 5 步:验证 + 通知

验证

  • 读取提交后截图,确认申请列表中出现新申请号
  • ⚠️ 脚本报"已提交"不代表真成功,必须看截图

通知(两层)

层级 谁发 什么时候 内容
第1层 脚本 adhome_fast_apply.js 流程结束时 主体、账户、耗时、状态
第2层 Agent(主流程) 任务结束时 申请号、成功/失败、关键信息汇总

通知状态说明

状态 含义
✅已自动提交 auto_submit: true 模式直接提交成功
✅已确认提交 信号文件模式,用户确认后提交成功
❌提交失败 提交时 ADHome 返回错误
🔙用户撤回 用户选择撤回,未提交
⏰等待超时 5分钟内未收到信号

清理

  • pkill -f "ms-playwright/chromium" 清理残留 Chromium 进程

📋 数据清洗规则

原始值 清洗后 说明
"5K" "5000" K = 1000
"1000/日" "1000" 去掉 "/日" 后缀
"2000/日" "2000" 同上
D列值 = 主体名称 "品牌商" 填表人误填,默认品牌商
主体名称过长 取公司名前半部分 搜索太长会超时
多个账户ID(换行分隔) 数组 按 \n 分割

🗺️ 行业映射速查

文档中的值 ADHome industry data-value
门诊部 医疗健康-门诊部 21474838626
诊所 医疗健康-诊所 21474838605
专业型医院 医疗健康-专业型医院 21474838627
综合型医院 医疗健康-综合型医院 21474838628
体检机构 医疗健康-体检机构 21474838597

🗂️ 分类映射速查

文档中的值 ADHome 分类路径
综合卡 消费医疗 > 轻医美 > 综合卡
针剂类 消费医疗 > 轻医美 > 针剂类
口腔美容 消费医疗 > 口腔 > 口腔美容
植发养发 消费医疗 > 毛发 > 植发养发
视力矫正 消费医疗 > 眼科 > 视力矫正
生活美容 消费医疗 > 生活美容 > 生活美容
情绪管理 专业医疗 > 心理健康 > 情绪管理
青少年心理 专业医疗 > 心理健康 > 青少年心理
种植牙 专业医疗 > 口腔 > 口腔治疗
口腔治疗 专业医疗 > 口腔 > 口腔治疗

⚠️ 分类级联选择器(重要)

分类是三列级联选择器,不是树形展开: - 第一列:大类(消费医疗/专业医疗...) - 第二列:子类(口腔/轻医美/生活美容...) - 第三列:叶子节点,有 radio 按钮

选择逻辑: 1. 前两级用 .first() 匹配(展开下一列) 2. 最后一级用 .last() 匹配(级联选择器同名节点,最后一个是最深列) 3. 叶子节点需点击整个 li 元素(包含 radio),不是只点文本 4. 必须用 Playwright 原生 locator.click(),不能用 evaluate 内的 el.click()(Vue 事件不触发)


🐛 踩坑经验(必读)

主体名称搜索

  • 全名太长会搜不到 → 用公司名前半部分
  • 例:"秦皇岛蓝温天医院管理有限公司建设大街口腔诊所" → "秦皇岛蓝温天医院管理有限公司"

文档读取

  • 企微文档 Cookie 格式 {cookies:[...]} 非纯数组,加载时兼容
  • formula bar 选择器 .formula-input(非 .formula-bar-content .ql-editor
  • 腾讯文档 MCP 不支持企微文档(doc.weixin.qq.com)
  • docs.qq.com 文档的"填写内容隐藏"列只能通过 MCP 导出 xlsx 获取数据

附件下载

  • 附件格式优先级: docx > 图片 > PDF(禁止静默降级 PDF)
  • 企微文档导出 docx:三横线菜单 → 导出为 → hover → "本地Word文档(.docx)"
  • 腾讯文档导出 docx:需 Chrome profile (~/.workbuddy/chrome-profile-docs) 登录态
  • 下载失败时必须暂停提醒用户,不能静默降级
  • xlsx 导出时附件超链接丢失(只有文件名)
  • docs.qq.com 附件需 Chrome profile Cookie + 新浏览器实例
  • persistent context 中 getBoundingClientRect 返回 0,0 → 必须用新实例
  • 每次 iOA 手动登录成功后,必须立即保存 Cookie 到 adhome_auth.json
  • 尽量避免重复手动登录,Cookie 有效期内复用
  • 刷新脚本:refresh_adhome_cookie.js
  • 附件可能是图片(jpg/png)而非文档 → 扫描本地文件时必须包含图片扩展名
  • 图片附件不需要转 PDF,直接上传原始图片文件
  • uploadFiles() 函数通过 input[type="file"] 上传,不限制格式

ADHome 表单

  • 诊所行业表单没有"产品链接"字段(脚本自动跳过)
  • ADHome Cookie 过期需 iOA 手机验证
  • 提交后必须验证申请列表(脚本报成功不代表真成功)
  • auto_submit: false — 填表后截图给用户确认再提交
脚本报错:waitForSelector timeout on .form-item-industry_id
     │
     ▼
检查错误截图 → 发现 iOA 登录页面
     │
     ▼
运行 Cookie 刷新脚本:
  • 打开 adhome.woa.com → 等 iOA 验证
  • 提示用户在手机上确认
  • waitForURL 回 adhome → 保存新 Cookie
     │
     ▼
重新运行填表脚本

浏览器进程

  • --headed 模式脚本退出后浏览器窗口保留
  • 无法从外部 reconnect 到独立实例
  • 任务完成后检查并清理残留 Chromium 进程:pkill -f "ms-playwright/chromium"

📢 企微通知

Webhook 配置(用户级)

Webhook 地址保存在 {SKILL_DIR}/scripts/user_config.json

{
  "notify_webhook": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY"
}

首次使用引导流程: 1. 检查 user_config.json 是否存在且包含 notify_webhook 2. 如果不存在 → 提示用户提供企微群机器人 Webhook 地址 3. 用户提供后 → 写入 user_config.json 持久化保存 4. 后续运行自动读取,无需重复配置

⚠️ 不同用户有不同的 webhook,严禁硬编码默认值

通知时机(两层)

脚本内通知(adhome_fast_apply.js): - 脚本完成时自动读取 user_config.json 中的 webhook 发送通知 - 通知内容包含:主体名称、账户ID列表、耗时、最终状态

主流程通知(Agent 调用方): - 每次加白任务结束后,Agent 必须发送一条结果通知到 webhook - 包含:成功/失败、申请号、主体名称、账户等关键信息 - 多行任务完成后发送一条汇总通知


📊 投放类目速查

消费医疗
├── 口腔:口腔美容 / 儿童口腔
├── 眼科:视力矫正 / 眼部护理
├── 毛发:植发养发
├── 生活美容:生活美容
├── 轻医美:刷酸 / 光电类 / 针剂类 / 综合卡 / 线雕 / 无创减脂
├── 中医美容:中医减肥 / 中医美容
├── 重医美:手术美容
├── 体检:常规体检
└── 宠物医院:宠物医疗服务

专业医疗
├── 口腔:口腔治疗
├── 心理健康:情绪管理 / 青少年心理
├── ...

完整分类树见 references/adhome_category_tree.json


🗂️ 关键路径

文件 路径
ADHome 登录态 {SKILL_DIR}/scripts/adhome_auth.json
用户配置(webhook等) {SKILL_DIR}/scripts/user_config.json
填表脚本 {SKILL_DIR}/scripts/adhome_fast_apply.js
企微文档 Cookie ~/.wecom-doc-cookies.json
腾讯文档 Cookie ~/.workbuddy/chrome-profile-docs/
素材文件目录 ~/Desktop/加白/{主体关键词}/
码表 {SKILL_DIR}/references/adhome_codebook.json
分类树 {SKILL_DIR}/references/adhome_category_tree.json
截图输出 {SKILL_DIR}/scripts/output/
信号文件(等待) /tmp/adhome_waiting.json
信号文件(指令) /tmp/adhome_signal.json
mcporter /Users/zhanglei/.workbuddy/binaries/node/workspace/node_modules/.bin/mcporter
Node.js /Users/zhanglei/.workbuddy/binaries/node/versions/22.12.0/bin/node

🤖 AI 评测

质量很好,是一款成熟可靠的企业级自动化工具。优点:文档详细、流程清晰、安全确认机制完善(不会误操作)、错误处理到位(出问题会提醒而不是悄悄失败)。不足:首次使用需要配置一些账号权限,上手稍微麻烦一点。总体推荐使用。

📊 多维度评分

适应性4.8
规范性4.5
有效性4.4
可靠性4.3
可信度4.5

📁 包含文件 (24 个)

📄 README_SKILL.md 2.3 KB
📄 SKILL.md 20.7 KB
📄 _skillhub_meta.json 89 B
📄 references/adhome_admission_rules.json 20.9 KB
📄 references/adhome_category_l4_cpv.json 8.6 KB
📄 references/adhome_category_tree.json 13 KB
📄 references/adhome_codebook.json 19.5 KB
📄 references/adhome_preferred_rules.json 3.3 KB
📄 references/config_sample.json 985 B
📄 references/flow_guide.md 10.2 KB
📄 references/input_template.json 869 B
📄 references/knowledge_base_config.json 4.3 KB
📄 scripts/adhome_auth.json 5.3 KB
📄 scripts/adhome_fast_apply.js 39.9 KB
📄 scripts/check_debug.js 1.5 KB
📄 scripts/check_diag.js 1.4 KB
📄 scripts/check_page_status.js 1.1 KB
📄 scripts/check_status_push_v7.js 2.5 KB
📄 scripts/check_status_v8.js 3.4 KB
📄 scripts/diag_page.js 1.1 KB
📄 scripts/drive_auth.json 5.5 KB
📄 scripts/package.json 56 B
📄 scripts/precheck.py 18.2 KB
📄 scripts/user_config.json 116 B