# Outreach Rules

Use this reference before sending social messages, emails, or any operation that changes outreach status.

## Human Confirmation

Always generate a preview before outreach.

- Email: generate JSON preview with `prepare_outreach_emails.py` first.
- Facebook social: generate JSON preview with `prepare_facebook_outreach.py` first.
- Browser outreach must run dry-run before real execution.
- Do not send or click unless the user explicitly confirms and the command uses the required confirmation flag.



## 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.

## Email Workflow

Email identity is fixed to `Chris Chen`. Email templates, preview bodies, and SMTP From display names should use Chris Chen by default. Do not ask for a dynamic social account name before email sending; `{{sender_name}}` is social-only.

Current default email template is for 客户属性=汽车渠道合作伙伴: use assets/email_template.md, subject assets/email_subject.txt, and inline image assets/wuling-channel-margin-comparison.png. The actual sending renderer must convert Markdown bold/list/link syntax into HTML, strip Markdown from the plain-text fallback, and constrain the inline image to width=300 with inline styles. The same body is stored at assets/email_templates/汽车渠道合作伙伴.md for future customer-attribute template selection. The preview step must replace [PICTURE] with the inline image reference and choose {{capability_phrase}} from the customer business evidence, rather than leaving the bracketed generic phrase in the final email.

1. Filter target records, normally `建联状态=未联系` and `邮箱` is not empty.
2. Generate preview JSON with `scripts/email_outreach/prepare_outreach_emails.py`.
3. Review `summary.ready_to_send` and `summary.skipped`.
4. Send with `scripts/email_outreach/send_outreach_emails.py` only when the user provides SMTP details and confirms sending.
5. After successful sending, update the workbook row `建联状态` to `已发送邮件`.
6. Keep send logs, but do not store SMTP authorization codes.

Already-sent statuses include `已发送邮件`, `已发邮件`, `邮件已发送`, and `邮件发送成功`.

## Facebook Social Workflow

Facebook outreach uses English as the customer-facing language. Chinese is only used for internal reasoning and preview review.

1. **Prepare preview**: `scripts/social/prepare_facebook_outreach.py` reads the Facebook sheet, filters uncontacted non-OEM targets, classifies each customer by business signal, and writes a JSON preview with Chinese judgment plus English connect/DM copy.
2. **Review preview**: Check `summary.ready_to_send`, `summary.skipped`, customer fit, and rendered English messages. Edit the workbook or re-run if a message is too generic.
3. **Recommended module-2 entrypoint**: use `scripts/social/run_facebook_follow_dm.py` to generate preview and then run AdsPower/Playwright dry-run or confirmed execution in one controlled workflow.
4. **Dry-run in AdsPower**: without `--confirm-send`, `run_facebook_follow_dm.py` calls `send_facebook_outreach.py --action follow_dm --keep-browser-open --no-write-workbook`, opens/checks each Facebook Page, prints the Page-header Follow/Message targets and Messenger target, and performs no real clicks. It must not ask for per-customer confirmation.
5. **Confirm and execute**: Add `--confirm-send` only after the full Markdown preview has been shown in chat and the user confirms the whole batch once. The executor sends with `--confirm --batch-confirmed` and does not ask per customer.
6. **Write back status**: Default is no workbook write. Only update the Facebook sheet when the user explicitly uses `--write-workbook`.
7. **Refresh summary**: After a completed Facebook outreach round, rebuild `客户信息汇总` with `scripts/common/build_customer_summary.py --write-summary`.
8. **Log**: Every action is appended to `logs/facebook_social_<date>.jsonl` with profile_id, target URL, action, timestamp, result, and error.

## Facebook Page Follow + Messenger Targeting Rules

- For Facebook Page outreach, use `--action follow_dm`: follow the Page first, then send a Messenger DM.
- Follow must be detected in the Page header. `追蹤中`, `Following`, or equivalent means already active and must not be clicked again.
- Message must start from the Page header `發送訊息 / Message` button, not from a post, comment box, or floating compose button.
- A DM textbox is valid only when it is inside a right-side Messenger dialog whose title matches the dealer name.
- Never use a global `contenteditable` textbox or the bottom-most page textbox as a message target.
- If the candidate textbox is near `Comment / 留言 / Reply / 回覆`, stop and output `Blocked: detected comment composer, not Messenger dialog`.
- If the Messenger dialog title does not match the target customer, stop and do not send.
- Always keep the already logged-in AdsPower browser open. `--keep-browser-open` is a compatibility flag; scripts must not close or stop AdsPower even after errors or risk prompts.
- If the Page-header Message button does not open the right-side Messenger dialog, the executor may fall back to `https://www.facebook.com/messages/t/<page_slug>`, but only after validating that the Messenger page contains the target customer name and a valid DM textbox.

## Facebook Reply Synchronization

When the user asks to inspect replies, synchronize Messenger history, translate conversations, or judge cooperation intent, read `references/facebook-conversation-sync.md`.

- The reply workflow is read-only in Facebook: it may navigate, scroll, and read matched Messenger threads, but it must not type, send, react, or change the account state.
- First sync uses `--initial-full`; later syncs use `--incremental`.
- Preserve both directions and translate all non-Chinese text to Chinese. Analyze intent only for effective customer replies.
- Before workbook write-back, show the reply summary, five-level intent distribution, and high-intent customers in chat.
- Do not generate or send an English reply. Output only a Chinese next-step recommendation.
- Write conversation rows to `Facebook对话记录`; update the matched Facebook customer row status, follow-up date, and replaceable reply-analysis note block.
- Preserve existing email, WhatsApp, and outreach evidence in the customer status and notes.
- After write-back, refresh the summary and dashboard, then check the Feishu sync configuration.

## Facebook Message Content Rules

- Use English for customer-facing Facebook connect and DM text. Chinese is only for internal judgment and preview review. Do not use French as the default Facebook message language.
- Country and city rendering must be market-adaptive: use the workbook country or user-selected target country, and only use city names when they are real customer-facing city names. Blank, nationwide, multi-city, or Chinese internal city notes must render as `in <country>`.
- Required preview format: `客户判断`、`推荐切入点`、`英文加好友话术`、`英文首轮私信`、`风险提示`.
- Produce Chinese internal judgment that explains customer type, the exact real signal used, why the customer is or is not worth contacting, and whether it has batch purchase/distribution potential.
- Treat the social objective as batch-sales qualification: first get a reply, then identify whether the customer can evaluate, purchase, digest, or distribute a first small batch of Wuling vehicles.
- Generate copy with the signal-driven structure: `specific signal -> commercial hypothesis -> light offer -> one question`.
- Every sendable message must cite at least one real customer signal from the workbook, Facebook page, About text, website, public contact data, or remarks. If the signal is weak, use a low-pressure role-confirmation message instead of a strong sales pitch.
- Do not use `We want to cooperate`, `We are an exporter`, or similar self-introduction as the first sentence. Lead from the customer's likely business opportunity.
- Produce `recommended_message` plus three alternatives: `direct_profit_hook`, `stock_gap_hook`, and `soft_research_hook`. Keep `english_connect` and `english_first_dm` as backward-compatible aliases for the recommended version.
- Facebook Page DM may be more direct about profit, inventory gap, total cost, fleet cost, and first-batch fit. LinkedIn connection notes should be lighter and less sales-heavy.
- Use only 1-2 Wuling value points per first touch: low-cost new vehicle line, small first-batch test, low stock pressure, price-sensitive local customers, complement current stock or brands, model and price-range overview, export support, spare-parts support, or possible volume potential.
- Use only one core question in the first DM. Do not ask for a meeting in the first touch.
- Mention Huatu Overseas only after the hook or in a compact sentence when needed.
- Do not discuss brand authorization, territory rights, regional rights, sole-right arrangements, or similar channel-right topics.
- Do not invent exact prices, MOQ, delivery dates, model lists, profit margins, available stock, government relationships, or unsupported cooperation terms.
- If real data is unavailable, use soft wording such as `model and price-range overview`, `small first-batch evaluation`, or `export-support information`.
- If the lead appears to be an official brand-country page, mark `建议跳过` and do not generate sendable copy.

## Facebook Status Mapping

- Preview only: keep `未联系`.
- Add friend only success: `已加好友,待私信`.
- Add friend plus message success: `已加好友,已发私信`.
- Message only success: `已发私信`.
- Add friend failure: `加好友失败` plus reason in `备注`.
- Message failure: `发送失败` plus reason in `备注`.
- Already emailed and now messaged on Facebook: append the social status in `备注`; do not erase the existing email evidence.

## Batch Limits

Use small batches by default:

| Action | Recommended limit |
|--------|-------------------|
| Scrape search results | `--max-results` no more than 20 per run unless the user asks otherwise. |
| Facebook Page Follow | 3 per real run, no more than 20 per account per day. |
| Facebook direct messages | 3 per real run, no more than 20 customer outreach DMs per account per day. |
| Email sending | Start with a small test batch before larger sends. |

Use bounded pacing waits for browser actions to throttle the workflow and reduce accidental rapid-fire operations. These waits are not for bypassing platform detection. Increase waits or stop if the account shows risk signals.

## Facebook Compliant Risk Reduction

- Do not design or describe Facebook automation as anti-detection, verification bypass, fingerprint rotation, or evasion of platform enforcement.
- Use `--risk-profile very_conservative` by default. Keep Facebook outreach small, relevant, and auditable.
- Use the account ledger `logs/facebook_account_ledger_<profile_id>_<YYYYMMDD>.json` to enforce daily limits before opening AdsPower.
- Default daily outreach cap: 20 customers per AdsPower profile. Follow <= 20 and Messenger DM <= 20; session max remains <= 3 by default. Operators may lower these caps, but should not raise them for cold outreach without a separate review.
- `--dry-run-schedule` must print the customer list, estimated pacing, used quota, remaining quota, stop rules, and staged wait ranges without opening the browser.
- Stop the entire batch immediately on verification, rate-limit, suspicious activity, identity confirmation, temporary block, exhausted quota, or repeated failures. Keep the browser open.
- Same-batch message previews should not use identical first sentences; weak-signal leads should receive low-pressure role-confirmation copy.
- Use layered browser pacing instead of one long interval for every action. Major steps use 90-200 seconds; minor page-level steps use 30-90 seconds; technical waits stay short at roughly 0.5-8 seconds.
- Major steps: switching to the next customer, opening a new customer page/company page/Google Maps detail/website homepage, waiting after a search query, waiting after successful Follow, waiting after successful DM send, and moving from a Facebook Page to website deep scraping.
- Minor steps: About/contact/services tab changes, scrolling, expanding more content, opening the Messenger dialog, waiting before pressing Enter, and switching between website Contact/About pages.
- Technical waits: Playwright locator readiness, DOM load, popup appearance, textbox availability, and similar element checks. Do not stretch technical waits to 30 seconds or more unless the site is genuinely slow.
- Session cooldown remains an extra post-run recommendation. These waits throttle the workflow and reduce accidental rapid-fire operations; they are not for bypassing platform detection.
- When a risk prompt or repeated failure is recorded, write `cooldown_until` in the account ledger and refuse additional confirmed Facebook outreach for that profile until the cooldown ends.

## Compliance And Risk

- Use collected public business contact data only for relevant B2B outreach.
- Do not scrape or store unnecessary personal data.
- Do not bypass platform restrictions or security checks.
- Stop immediately when Facebook shows verification, rate-limit, suspicious activity, identity confirmation, or temporary block prompts.
- Do not send to OEM local brand-country pages such as `BYD Maroc`, `BMW Maroc`, `JAC Motors Maroc`, `Changan Maroc`, `FOTON Maroc`, or similar official branches.
- Do not continue follow-up more than twice without a reply.
- Do not store account passwords, cookies, SMTP authorization codes, or other sensitive secrets in skill files, JSON previews, or logs.

## Audit Trail

Record these fields for browser outreach when possible:

- `profile_id`
- target URL or account
- action type
- timestamp
- result
- error reason when failed
- whether the run was dry-run or confirmed

For email, keep JSONL send logs with recipient, dealer name, subject, sender, and timestamp. Never log SMTP auth codes.
