---
name: wuling-overseas-dealer-expansion
description: 为五菱汽车海外经销商拓展提供端到端自动化能力：使用 AdsPower/Playwright 搜索海外经销商线索，去重和评分，回写及汇总建联表，生成邮件和社交建联预览，执行经确认的建联，并读取匹配的 Facebook Messenger 对话、翻译成中文、分析合作意向和跟进动作。Use when Codex needs to find overseas Wuling dealer leads, assess dealer fit, prepare/send confirmed outreach, synchronize Facebook replies, translate customer conversations, assess cooperation intent, or update the outreach workbook and dashboard.
---

# 五菱汽车海外经销商拓展

## 文件边界

这个目录是独立 skill 包，只放可复用文件：

- `SKILL.md`：入口说明和任务路由。
- `references/`：搜索策略、字段规范、品牌/OEM 规则、AdsPower、飞书同步和建联风控说明。
- `assets/`：邮件模板、邮件主题、邮件图片、社交话术库、全新环境兜底用空白建联表模板、飞书同步配置示例。
- `scripts/`：采集、去重、Excel、邮件预览/发送、社交预览/执行脚本。
- `references/artifact-policy.md`: run artifact, backup, preview, send-log, and cleanup retention policy.
- `references/encoding-and-excel-writeback.md`: mandatory text encoding and Excel write-back rules to prevent repeated-question-mark text corruption.
- `references/feishu-sync.md`: WorkBuddy/Lark Sheets post-write sync rules for keeping the Feishu online spreadsheet aligned with the local workbook.
- `references/dashboard.md`: customer dashboard generation rules, KPI definitions, dashboard artifact locations, and optional Feishu metric-sync boundary.
- `references/facebook-conversation-sync.md`: matched Messenger collection, Chinese translation, five-level intent analysis, workbook write-back, and reply-dashboard rules.

不要把真实客户表、JSON 预览、采集结果、发送日志、截图、缓存、`__pycache__`、临时文件或任何账号/SMTP 授权码放进 skill 包。唯一允许放进 `assets/` 的 Excel 是空白模板 `assets/blank_customer_outreach_workbook.xlsx`。

## 任务路由

| 任务 | 使用文件 | 状态 |
|---|---|---|
| Facebook 经销商搜索 | `scripts/scraper/search_active_dealers.py` | 已实现，默认预览 |
| Facebook 轻量搜索 | `scripts/scraper/search_facebook.py` | 已实现 |
| Facebook 单页采集 | `scripts/scraper/scrape_single_page.py` | 已实现 |
| LinkedIn 公司页搜索 | `scripts/scraper/search_linkedin.py` | 已实现，默认预览 |
| Google Maps 搜索和公开邮箱提取 | `scripts/scraper/search_google_maps.py` | 已实现，邮箱需 `--deep-scrape` |
| 当地汽车网站搜索 | `scripts/scraper/search_auto_websites.py` | 已实现，覆盖 OtoMoto、Wandaloo、Kerix、Kompass、Maroc Annuaire、Telecontact |
| 客户信息汇总大表 | `scripts/common/build_customer_summary.py` | 已实现，完成各平台查找后统一汇总/覆盖 `客户信息汇总表` |
| 客户中台看板 | `scripts/dashboard/build_dashboard.py` | 已实现，读取 `客户信息汇总表` 生成 HTML 看板和指标 JSON，不写 Excel |
| 飞书云表格同步 | `references/feishu-sync.md` + WorkBuddy `lark-sheets` plugin | 写表后强制检查项目配置并同步 |
| TikTok 搜索 | `scripts/scraper/search_tiktok.py` | 占位，暂缓开发 |
| 邮件预览 | `scripts/email_outreach/prepare_outreach_emails.py` | 已实现 |
| 邮件发送 | `scripts/email_outreach/send_outreach_emails.py` | 已实现，必须人工确认 |
| 社交话术生成 | `assets/social_outreach_library.md` | 已实现，Facebook 主语言为英文 |
| Facebook 社交建联预览 | `scripts/social/prepare_facebook_outreach.py` | 已实现，输出中文判断 + 英文话术 JSON 预览 |
| Facebook Follow + Messenger 建联总控 | `scripts/social/run_facebook_follow_dm.py` | 已实现，输出整批聊天框预览；确认后批量执行；不断开 Playwright 连接，浏览器保持打开 |
| Facebook 社交建联执行 | `scripts/social/send_facebook_outreach.py` | 已实现，默认 dry-run；支持 `--action follow_dm`；真实执行必须 `--confirm --batch-confirmed`，不逐条确认 |
| Facebook 对话采集 | `scripts/social/collect_facebook_conversations.py` | 已实现，只读；首次全量、后续增量；始终保持浏览器打开 |
| Facebook 对话翻译/意向写回 | `scripts/social/write_facebook_conversations.py` + `references/facebook-conversation-sync.md` | 已实现，先聊天框预览，再显式写表 |

## 必读规则

- 先生成预览，再写表或发送。
- 查找客户默认面向用户指定国家全国范围，不局限单一城市；当前摩洛哥只是本项目默认市场。
- 表里已有同名、同主页、同电话或同邮箱的客户，直接跳过或补充资料，不重复新建。
- 跳过 OEM 官方品牌国家页或当地分公司，例如 `BYD Maroc`、`BMW Maroc`、`JAC Morocco`、`Changan Maroc`、`FOTON Maroc`。
- Customer segmentation uses `客户属性` as the broad class and `客户类型` as the subtype. Classification must follow the five-attribute taxonomy. Main focus is `汽车渠道合作伙伴` and `平台与行业渠道`; `批量采购与运营客户`, `二手车转型候选`, and `生态支持资源` remain supported for full segmentation. `主营业务` is only the business-description field.
- 邮箱只使用公开页面、`mailto:` 或官网 Contact/About 页面中能追溯的邮箱，不猜测、不生成。
- 不保存 SMTP 授权码，不把授权码写入日志、JSON、skill 文件或脚本默认值。
- 所有涉及浏览器的操作必须使用 Playwright 执行，包括 AdsPower 连接、Facebook/LinkedIn/Google Maps/当地汽车网站采集、官网深搜、页面点击、输入、滚动、截图验证和 Messenger 私信。不得使用截图坐标、系统级鼠标键盘模拟、浏览器扩展脚本或人工猜测 DOM 位置作为默认实现；除非用户明确要求人工操作，否则浏览器自动化入口必须通过 Playwright 的 DOM/locator/CDP 能力完成。所有脚本必须保持 AdsPower 指纹浏览器打开，禁止调用 AdsPower stop 或关闭用户浏览器窗口。

## Facebook 英文建联流程

Facebook 建联必须按半自动、低频、可审计的合规流程执行。优化目标是降低账号操作风险和骚扰风险，不允许写成规避官方风控、绕过验证、换指纹规避或模拟异常人类行为的方案。

1. 从 `Facebook` Sheet 筛选 `未联系`、非 OEM 官方页、有主页链接的客户。
2. 运行 `scripts/social/prepare_facebook_outreach.py` 生成预览，必须在聊天框展示整批 Markdown 预览，包含中文客户判断、英文私信话术、主页链接和风险提示。
3. 人工一次性复核整批客户名单和英文话术；不再逐条确认。
4. 推荐运行 `scripts/social/run_facebook_follow_dm.py` 做总控流程：先生成并打印整批预览，再调用 AdsPower/Playwright dry-run 或确认执行。
5. 用户在聊天框明确确认整批预览后，才允许加 `--confirm-send` 真实执行；总控脚本会传入 `--confirm --batch-confirmed`。执行前必须展示本轮预计节奏、当天 Follow/DM 已用额度、剩余额度和停止规则。
6. 默认不写表；只有用户明确传 `--write-workbook`，才写回 `Facebook` Sheet 的建联状态和备注。
7. 一轮结束后，再用 `scripts/common/build_customer_summary.py --write-summary` 刷新 `客户信息汇总表`。

禁止跳过预览直接真实发送。禁止把法语作为 Facebook 默认发送语言；中文只用于内部判断和复核，不发送给客户。

示例预览命令：

```bash
python scripts/social/prepare_facebook_outreach.py --excel "<建联表路径>" --sheet Facebook --sample 5 --output facebook_social_preview.json
```

示例总控预览命令：

```bash
python scripts/social/run_facebook_follow_dm.py --excel "<建联表路径>" --sheet Facebook --profile-id "<AdsPower配置ID>" --max-contacts 3 --review-only
```

示例总控节奏预览命令：

```bash
python scripts/social/run_facebook_follow_dm.py --excel "<建联表路径>" --sheet Facebook --profile-id "<AdsPower配置ID>" --max-contacts 3 --dry-run-schedule
```

示例总控 dry-run 命令：

```bash
python scripts/social/run_facebook_follow_dm.py --excel "<建联表路径>" --sheet Facebook --profile-id "<AdsPower配置ID>" --max-contacts 3 --use-open-page --risk-profile very_conservative
```

示例 dry-run 命令：

```bash
python scripts/social/send_facebook_outreach.py --preview facebook_social_preview.json --profile-id "<AdsPower配置ID>" --action follow_dm --keep-browser-open --no-write-workbook
```

示例真实执行命令：

```bash
python scripts/social/send_facebook_outreach.py --preview facebook_social_preview.json --profile-id "<AdsPower配置ID>" --action follow_dm --risk-profile very_conservative --daily-follow-limit 20 --daily-dm-limit 20 --session-max 3 --keep-browser-open --no-write-workbook --confirm --batch-confirmed
```

## 社交话术规则

社交话术用于 Facebook 和 LinkedIn。Facebook 主语言为英文，输出结构为：中文内部判断 + 英文加好友话术 + 英文私信话术。话术目标是判断客户是否具备评估、采购、消化或分销一批五菱车型的能力。

首轮话术优先使用“真实客户信号 + 利润机会 + 首批小批量试单”切入：先引用 showroom、used-car stock、rental、fleet、importation、官网、WhatsApp、近期帖子等真实信号，再提出商业假设和低压力价值物。`prepare_facebook_outreach.py` 必须输出 `recommended_message`，并同时给出 `direct_profit_hook`、`stock_gap_hook`、`soft_research_hook` 三个备选版本，方便人工挑选。不要写成泛泛合作介绍。

禁止编造具体价格、MOQ、车型清单、利润率、库存数量、政府关系或未经确认的合作条件。

## Facebook 回复同步流程

当用户要求查看 Facebook 回复、同步 Messenger 对话、翻译客户消息或判断下一步合作意向时，必须读取 `references/facebook-conversation-sync.md`。

1. 使用 `collect_facebook_conversations.py` 只读取建联表中可可靠匹配的客户线程；首次用 `--initial-full`，后续用 `--incremental`。
2. 保留双方原文并把非中文内容翻译成中文；仅对有效客户回复进行五级合作意向判断。
3. 在聊天框展示回复摘要、意向分布和高意向客户，不生成英文回复、不自动发送。
4. 用户明确要求写表后，使用 `write_facebook_conversations.py --write-workbook --refresh-summary --refresh-dashboard`。
5. 对话逐条写入 `Facebook对话记录`；Facebook 客户行只更新最新中文摘要、合作意向、状态和下次跟进。
6. 写表后校验乱码、刷新总表/看板，并按飞书配置同步。


## Customer Attribute Taxonomy

All workbook rows and scraper outputs must use exactly one customer attribute and one matching customer type from the table below. Do not write combined attributes, multi-line categories, custom labels, or fallback values such as pending/unknown into the official workbook. Keep business descriptions in `主营业务`; do not mix them into classification fields.

| Customer attribute | Allowed customer types |
|---|---|
| `汽车渠道合作伙伴` | `汽车进口商` ; `全国代理商` ; `全国分销商` ; `区域分销商` ; `多品牌经销商` ; `商用车渠道商` ; `中国品牌经销商` ; `新能源或小型车渠道商` |
| `批量采购与运营客户` | `汽车租赁公司` ; `长期租赁公司` ; `企业车队` ; `物流配送企业` ; `政府或机构采购方` |
| `二手车转型候选` | `连锁二手车企业` ; `实体二手车企业` ; `进口二手车企业` ; `新车与二手车综合企业` |
| `平台与行业渠道` | `汽车交易平台` ; `汽车协会` ; `商会` ; `车商联盟` ; `经销商资源引荐机构` |
| `生态支持资源` | `售后服务网络` ; `备件供应与仓储企业` ; `进口认证与上牌机构` ; `金融保险机构` ; `车辆物流企业` |

Rules:

- `客户属性` is the broad class; `客户类型` is the subtype. The pair must match the same row in the taxonomy table.
- Main search focus: `汽车渠道合作伙伴` first, then `平台与行业渠道`. The other three classes are still kept for complete segmentation and later operations.
- If evidence is insufficient, continue public-source deep search before writing. Preview files may explain uncertainty, but the official summary sheet must not contain fake or unsupported classes.

## 人工确认标记边界

以下内容是人工确认/风险标记，不是客户分类。禁止写入 `客户属性` 或 `客户类型`，只能写入候选预览 JSON 的 `risk_flags`、`备注` 或人工复核预览中：

- `主体归属待确认`：汽车渠道线索中，无法判断是独立公司，还是品牌官方主体、进口商直营网点或普通分店。
- `新车业务待确认`：汽车渠道线索中，无法判断主营新整车，还是二手车、维修、配件、轮胎等业务。
- `平台与行业渠道主体待确认`：平台与行业渠道线索中，无法确认是否为真实机构主体，还是普通个人页、内容号或非正式资源页。
- `平台与行业渠道作用待确认`：平台与行业渠道线索中，无法确认是否具备汽车行业资源、渠道引荐、媒体传播或行业活动组织作用。
- `仅电话/WhatsApp待人工确认`：线索已有目标价值信号，但只有电话或 WhatsApp，缺少官网、Facebook、LinkedIn、Google Maps 等可复核资料，需要人工联系确认主体和实际业务。
- `详细信息待确认`：当 AI 因登录限制、页面屏蔽、地区限制或网站无法访问，不能读取 Facebook、LinkedIn、官网等内容时填写。

客户分类仍必须严格保持五大客户属性和表内细分客户类型；不要用上述风险标记作为兜底分类值。

人工复核不是低质线索兜底池。只有已经显示出渠道价值、但缺少一个关键确认点的客户，才标记为需人工复核。

输出人工复核名单时，不要输出通用复核规则；只列出那些已经值得推进、但需要人工确认一个关键点的客户。低价值或无关客户应写为跳过/低优先级，不要包装成“建议人工复核”。

### 两段式人工复核标准

人工复核必须先看客户是否有目标价值，再看是否缺少需人工确认的关键点。只有两部分同时成立，才能列为需人工复核。

第一部分：客户属性信号至少满足其一。

- 汽车渠道合作伙伴信号：新车销售、汽车进口、分销、授权经销、汽车展厅、showroom、库存、dealer network 等。
- 平台与行业渠道信号：汽车协会、商会、汽车行业平台、汽车媒体、行业活动组织、车商联盟、经销商资源平台或引荐机构等。

第二部分：人工复核条件至少满足其一。

- 汽车渠道类：主体归属待确认，或新车业务待确认。
- 平台与行业渠道类：真实机构主体待确认，或汽车行业资源/渠道作用待确认。
- 只有电话或 WhatsApp：线索已有目标价值信号，但缺少官网、Facebook、LinkedIn、Google Maps 等可复核资料，需要人工联系确认其主体和实际业务。

不要把“只有电话/WhatsApp”单独作为人工复核理由。如果客户没有汽车渠道价值或平台行业价值，应跳过或标记低优先级，不列入人工复核名单。


- 可进入人工复核的前提：至少有一个明确正向价值信号，例如汽车渠道、进口/分销、多品牌、showroom/展厅、库存/stock、中国品牌经验、商用车/车队场景、平台/协会/商会资源或可建联入口。
- 人工复核的典型原因：看起来有渠道价值，但独立主体待确认、新整车业务待确认、或因页面/登录/地区限制导致详细信息无法读取。
- 不进入人工复核的情况：纯维修/配件/轮胎/保险/洗车、个人卖家、OEM 官方主页/当地分公司、无汽车渠道价值信号且无可建联入口的记录。这些应该跳过或标记低优先级，而不是写成“需人工复核”。

## 汽车渠道合作伙伴筛选与评分规则

- 汽车渠道合作伙伴必须有实际新整车销售或分销业务证据：展厅、新车销售、进口、经销、分销、库存或 dealer network。纯维修、配件、轮胎、个人卖家不纳入汽车渠道合作伙伴。纯租车公司转入 `批量采购与运营客户 / 汽车租赁公司`。
- 必须能识别独立经营主体：优先独立公司名称、注册主体、集团、经销商或进口商；排除品牌当地分公司、官方主页、进口商直营网点及普通分店，例如 `BYD Maroc`、`BMW Maroc` 等品牌官方主体。
- 必须存在新增品牌的可能性：进口商、分销商、多品牌经销商优先；独立单品牌新车经销商可以保留，但备注和风险标记必须写 `排他协议及新增品牌权限待确认`。
- 必须具有可建联入口：至少有一个有效电话、WhatsApp、邮箱、Facebook、LinkedIn 或负责人入口。页面活跃度、粉丝互动、近期帖子只作为辅助参考，不作为必须条件。

评分准则写入候选预览的 `score_reasons` 和 `risk_flags`：

- `+3` 实际新整车销售、showroom、库存、concessionnaire 或 véhicules neufs 信号。
- `+3` 进口、分销、代理、集团、réseau、dealer network 等渠道能力信号。
- `+2` 多品牌经营、multimarque、multi-brand 或多品牌 showroom 信号。
- `+2` 有可建联入口，例如电话、WhatsApp、邮箱、Facebook、LinkedIn、官网 Contact。
- `+1` 中国品牌、商用车、车队或摩洛哥本地相关信号；仅作为辅助，不单独构成汽车渠道合作伙伴。
- `-10` 品牌当地分公司、官方主页、进口商直营网点或普通品牌分店，推荐动作设为 `skip_brand_branch`。
- `-6` 纯维修、配件、轮胎、洗车、保险、诊断等非整车销售服务，推荐动作设为 `skip_non_channel`。
- `-5` 个人卖家或个人资料页，推荐动作设为 `skip_non_channel`。
- 纯租赁/车队线索不作为汽车渠道合作伙伴加分，需转入 `批量采购与运营客户 / 汽车租赁公司`。
- 没有新整车销售、进口、分销或 showroom 证据时扣分，并要求继续深搜或人工复核。

## 客户信息汇总流程

各平台客户资料必须先写入各自的渠道 Sheet，例如 `Facebook`、`LinkedIn`、`Google Maps`、`本地汽车网站`、`汽车网站精选线索`。采集、浏览、深度补充和去重完成前，不要把新客户直接写入 `客户信息汇总表`。

完成一轮平台查找后，再运行 `scripts/common/build_customer_summary.py` 统一生成或覆盖 `客户信息汇总表`。总表是可重建结果，不是原始采集表；表头必须对齐重点客户参考表：`公司姓名、国家、城市、客户类型、官网链接、联系人、职位、个人邮箱、联系人电话、Facebook主页链接、linkined主页链接、google map链接、公共电话/WhatsApp、公共邮箱、客户属性、建联状态、下次跟进、备注`。重复客户在总表中合并为一行，电话、邮箱、联系人、平台链接、官网链接和备注作为补充资料去重追加；合并来源数量、客户来源和来源 Sheet 写入 `备注`，不再单独增加 `重复来源数` 列，避免列错位或把序号当次数。

默认只预览汇总统计，不保存工作簿：

```bash
python scripts/common/build_customer_summary.py --excel "<建联表路径>"
```

用户明确要求更新总表时，才写入：

```bash
python scripts/common/build_customer_summary.py --excel "<建联表路径>" --write-summary
```

## 客户中台看板

当用户提到中台、看台、看板、客户统计、建联率、客户数量、渠道分布或邮件发送统计时，读取 `references/dashboard.md`，并使用 `scripts/dashboard/build_dashboard.py` 生成本地 HTML 看板和指标 JSON。

看板以 `客户信息汇总表` 为客户主数据，并在存在 `Facebook对话记录` 时读取它计算唯一客户回复率、五级意向分布、高意向客户和最近 30 天回复趋势。消息行不得计作客户行。看板不直接写入 Excel，不触发飞书同步，也不保存真实客户数据到 skill 包。

正式视觉模板固定为 `assets/dashboard_template.html`。每次生成中台都必须通过 `build_dashboard.py` 将运行时 JSON 注入 `{{dashboard_json}}` 占位符；不得把已生成 HTML 中的真实客户 JSON 复制回模板或 Skill 包。

如果本轮刚完成渠道采集、邮件状态写回、社交状态写回或其他 Excel 写入，必须先运行 `scripts/common/build_customer_summary.py --write-summary` 刷新 `客户信息汇总表`，再生成看板。预览、dry-run、搜索未写表时，不强制刷新看板。

示例命令：

```bash
python scripts/dashboard/build_dashboard.py --excel "<建联表路径>" --run-id "<run_id>" --latest-dir "dashboards/latest"
```

## 飞书云表格同步

飞书同步是所有写表流程写表后的强制后置步骤。每次本地 Excel 成功执行 `--write-excel`、`--write-summary`、`--write-workbook`、邮件状态写回或社交状态写回后，agent 必须读取 `references/feishu-sync.md` 并检查项目根目录 `feishu_sync_config.json`。

- 如果配置存在且 `enabled=true`，必须调用 WorkBuddy 的 `lark-sheets` 插件同步飞书电子表格，不再询问是否同步。
- 默认同步 `客户信息汇总表`；渠道 Sheet 只有在用户明确要求整本工作簿同步，或配置 `sync_scope=all_configured_sheets` 时同步。
- 如果配置缺失、插件不可用或未授权，必须在最终结果中说明飞书同步未执行/失败原因，但不能回滚本地 Excel 写入。
- 飞书表格只作为在线镜像；本地建联表仍是主数据源。禁止把真实飞书链接、token、cookie、账号密码或授权信息写进 skill 包。
- 示例配置见 `assets/feishu_sync_config.example.json`；真实配置应放在项目根目录 `feishu_sync_config.json`。

## 工作簿优先级

写表脚本必须按同一顺序解析建联表：

1. 用户显式传入 `--excel` 时，优先使用该路径。
2. 未传 `--excel` 时，先在当前运行目录和上级目录查找项目建联表，例如 `摩洛哥客户建联表-按渠道分类.xlsx` 或带空格版本。
3. 查找时排除 `~$`、`_backup_`、`backup_before`、`_with_`、`sent_`、`preview`、`candidate`、`filtered` 等临时、备份、预览或过滤文件。
4. 只有用户明确使用写表模式且项目内找不到建联表时，才从 `assets/blank_customer_outreach_workbook.xlsx` 复制一份到运行目录后再写入。该模板由当前正式表 `摩洛哥客户建联表-按渠道分类.xlsx` 生成，保留 Sheet、表头、列宽和基础格式，不包含真实客户数据。
5. 预览模式不强制创建建联表。禁止直接写入 skill 内的空白模板文件。

## 邮件规则

当前默认邮件模板面向 `客户属性=汽车渠道合作伙伴`，正式发送正文使用 `assets/email_template.md`，邮件主题使用 `assets/email_subject.txt`。同一模板也保存在 `assets/email_templates/汽车渠道合作伙伴.md`。`客户属性=平台与行业渠道` 使用 `assets/email_templates/平台与行业渠道.md`，邮件主题使用 `assets/email_subjects/平台与行业渠道.txt`，图片资源使用 `assets/wuling-platform-industry-channel.png`。后续按客户属性增加新模板时，应继续放入 `assets/email_templates/`，并在发送前明确选择对应客户属性模板。

发送前必须生成并展示最终预览。除非用户明确要求修改模板，否则不要改模板正文。邮件模板中的图片文件必须放在 `assets/` 内。当前汽车渠道合作伙伴模板使用 `assets/wuling-channel-margin-comparison.png`，发送脚本会把 Markdown 图片转成 HTML 内嵌图片，并同时保留纯文本备用正文。

平台与行业渠道模板可使用 `{{platform_resource_phrase}}` 变量，根据客户主营业务和备注自动选择 `automotive industry traffic`、`dealer members and industry resources`、`corporate customers and procurement resources`、`dealer and importer resources` 或 `automotive industry resources`，禁止编造具体会员数量、流量规模或已确认项目资源。

邮件发送脚本必须把 Markdown `**加粗**`、列表和 `mailto:` / Website 链接转换成真实 HTML；纯文本备用正文必须去掉 Markdown 符号。邮件图片必须同时设置 `width="300"` 和内联 `style="width:300px;max-width:300px;height:auto"`，避免邮箱客户端把图片放大。

## 浏览器自动化硬规则

凡是需要打开、连接、控制或读取浏览器页面的任务，必须使用 Playwright：

- AdsPower 只负责提供指纹浏览器环境和 CDP websocket；实际页面访问、搜索、点击、滚动、输入、读取 DOM、截图校验和下载均由 Playwright 完成。
- Facebook、LinkedIn、Google Maps、当地汽车网站、企业官网深搜、Facebook Follow + Messenger 私信都属于浏览器操作，必须走 Playwright 脚本。
- 官网识别必须通过 Playwright 读取 `a[href]`、链接可见文本、aria、按钮链接和页面正文；不得靠截图圈选、坐标点击或人工猜测链接位置作为默认采集逻辑。
- 私信发送必须使用 Playwright 定位 Messenger 小窗或 Messenger 页面输入框，并通过 Playwright 键盘事件发送；禁止把帖子评论框、页面底部任意输入框或截图位置当作发送目标。
- 如果 Playwright 无法定位目标元素，脚本应停止并输出人工处理原因，不允许降级为不可靠的全局输入框或坐标操作。

## Facebook 合规降风险规则

- 默认使用 `--risk-profile very_conservative`，真实发送每轮最多 3 个客户；可用 `--session-max` 进一步降低本轮数量。
- 每个 AdsPower `profile_id` 每日建联客户默认上限为 20；Follow 和 Messenger DM 均按 20 封顶，可通过 `--daily-follow-limit` 和 `--daily-dm-limit` 调低。单轮默认仍为 3 个客户，建议分多轮完成每日 20 个客户。
- 执行脚本按 `logs/facebook_account_ledger_<profile_id>_<YYYYMMDD>.json` 记录当天 Follow、DM、失败、风险提示、`last_run_at` 和 `cooldown_until`；超过额度或出现风险事件后，当天停止该账号继续建联。
- 分层级节流：大层级操作间隔从 90-200 秒随机取值，小层级/页面内操作间隔从 30-90 秒随机取值，技术等待 technical 保持 0.5-8 秒短等待；轮次冷却仍作为额外冷却建议。等待只用于节流和降低误操作风险，不用于规避平台检测。
- 大层级操作包括：切换到下一个客户、打开新的客户主页/公司页/Google Maps 商家页/官网首页、提交搜索关键词后等待结果、Follow 成功后、DM 发送成功后、从 Facebook 主页跳到官网深搜前。
- 小层级操作包括：打开 About/联系资料/Services/Contact 等二级页面、页面滚动、展开更多、切换 tab、打开 Messenger 小窗后等待、输入话术后发送前等待、官网 Contact/About 页面之间切换。
- 技术等待 technical 只用于 Playwright locator、DOM 加载、弹窗出现、输入框可用等元素检测，不作为对外行为节奏，不强制拉长。
- `--dry-run-schedule` 只输出本轮预计节奏、客户列表和额度，不打开 AdsPower、不点击、不发送、不写表。
- 同一批预览会尽量避免完全相同的英文私信首句；信息不足客户自动使用低压确认型话术。

## 运行原则

- 默认只输出 JSON/Markdown 预览。
- 只有用户明确说“写入表”时，才使用写表选项。
- 只有用户明确提供发件邮箱、SMTP 授权码并确认发送时，才发送邮件。
- 只有用户完成 Facebook 整批聊天框预览并明确确认后，脚本显式使用 `--confirm --batch-confirmed`，才执行 Facebook 关注/私信；不再逐条确认，私信必须命中 Messenger 小窗或 Messenger 页面，禁止帖子留言。
- 写表前确认 Excel 没有打开；如果保存失败，先输出结果文件，等用户关闭 Excel 后再写回。
- 采集和发送结果应保存到项目运行目录或用户指定目录，不要保存到 skill 包目录。
- 任何本地建联表写入成功后，都必须按 `references/feishu-sync.md` 检查项目根目录 `feishu_sync_config.json`。如果 `enabled=true` 且 WorkBuddy 已安装/授权 `lark-sheets` 插件，agent 必须自动同步飞书电子表格，不需要用户再次强调；预览、dry-run、review-only 和 schedule-only 不触发飞书同步。

## Facebook 采集与官网深搜规则

Facebook 客户采集在 `--deep-scrape` 阶段必须执行“Facebook 主页联络资料 -> About -> 公司官网 -> 官网公开页面”的补充流程：

- `主页/链接` 继续保存 Facebook 主页，用于去重、私信和状态追踪。
- 打开 Facebook 主页后，必须先读取主页顶部/侧栏/联络资料区域，提取官网、电话、邮箱、WhatsApp、地址、简介和主页按钮链接；随后再进入 About。主页已确认的官网、电话、邮箱不被 About 或官网深搜覆盖，只能补空字段或追加证据。不要把 Instagram、WhatsApp、YouTube、Google Maps 或其他平台链接当作公司官网。
- 发现 `公司官网` 后，进入官网首页、Contact、About、Nous contacter、A propos、Services、Vehicules、Occasion、Location 等公开页面，提取公开邮箱、电话和业务证据。
- `主营业务` 必须综合 Facebook 简介、About、近期帖子和官网正文判断；没有证据时写“汽车渠道线索，需人工确认”，不编造业务、价格、MOQ、库存或合作条件。
- `备注` 使用中文结构化摘要，格式围绕：来源线索、Facebook证据、官网证据、主营业务判断、批量采购能力判断、联系方式证据、风险/待确认项。专业词如 showroom、importation、fleet、location、vehicules neufs 可保留原文。








## Run Artifact Management

- Store previews, scraper outputs, retry manifests, send logs, and reports under `runs/YYYYMMDD/<run_id>/` by default; do not scatter runtime files in the project root.
- Create Excel backups only before a write-enabled operation changes the official workbook. Store backups under `backups/YYYYMMDD/` and reuse one backup for the same run/purpose.
- Keep HTML previews lightweight by referencing image files by path; only embed/base64 assets when the user explicitly asks for standalone offline HTML.
- Store durable ledgers such as Facebook daily account limits under `logs/`. Do not write SMTP authorization codes to any artifact.
- Clear `.tmp` after tasks. Run cleanup in dry-run mode first and keep the latest 10 workbook backups plus 30 days of JSON/HTML/log artifacts by default.



## Sender Identity And Name Replacement

- Email and social outreach identities are separate.
- Official email templates and email sending use the fixed sender name `Chris Chen`. Do not ask the user for a per-account sender name when preparing or sending email.
- Facebook and LinkedIn social outreach use the runtime variable `{{sender_name}}` only when the message needs the current social account/persona name. Different AdsPower/Facebook/LinkedIn accounts may use different sender names.
- If the user changes social account/profile_id, ask for the sender role/account/persona name again unless it was explicitly provided in the same run request.
- Template updates should be made only inside the project workspace and the official skill directories. Do not modify WeChat cache copies or external received-file directories unless the user explicitly asks for that exact file to be edited.
- Customer name is `{{customer_name}}`. It must be filled from the workbook contact/customer/company name. If no contact person exists, use the customer/company name.
- Final previews and sent messages must never contain `[Name]`, `[name]`, `{{customer_name}}`, or `{{sender_name}}`.
- Email templates must not contain `{{sender_name}}`; legacy email templates containing it should be updated to `Chris Chen` before use.
