# Email Content Compose All-in-one skill: fetch leads, compose personalized outreach emails, export as EML and upload to R2. ## IMPORTANT — Execution Rules - This skill uses **Bun + TypeScript**. Do NOT create Python scripts. - Do NOT overwrite existing files in this skill directory. - Use the existing CLI scripts below. Do NOT write your own upload/compose logic. ## Phases ### 1. Fetch (scripts/fetch.ts) Retrieves the lead-dataset for a completed cold-outreach workflow. ```bash cd ~/clawd/skills/email-content-compose bun run fetch -- --workflow-id= ``` Returns: JSON with businesses (name, website, reviews, emails) and summary stats. ### 2. Compose (LLM) The LLM agent reads fetch output and composes a personalized email per business. Save drafts as a JSON array file. Each draft must have: - `recipient_email` (string) - `recipient_name` (string | null) - `subject` (string, under 60 chars) - `body_html` (string, professional HTML with inline styles) - `body_text` (string, plain text fallback) - `personalization_context` (object, see below) #### a) Sender Profile Before composing, read `sender-profile.json` in this skill directory. Use it to populate sender identity, product info, and signature in every email. #### b) Language Selection Auto-select email language based on the `country` field from fetch output: - us/gb/au/ca → English - cn → 中文 - jp → 日本語 - kr → 한국어 - de → Deutsch - fr → Français - es/mx → Español - pt/br → Português - Unlisted countries → default to English Write the **entire** email (subject, body, signature) in the selected language. #### c) Review Pain-Point Analysis When `reviews_data` is non-empty for a business: 1. Parse JSON into a review array 2. Filter for negative reviews / complaints related to the sender's `product_category` 3. Extract 1–2 pain points that the sender's products can solve 4. Analyze at most 10 reviews, prioritizing low-score ones 5. If `reviews_data` is empty or null, fall back to the business's general info (category, rating) to craft the email #### d) Email Template Structure 1. **Subject** — Under 60 chars, in the target language, referencing a specific pain point or business need 2. **Opening** — Address the business by name; demonstrate familiarity with their operations 3. **Pain Point Bridge** — Reference pain-point patterns from reviews (do NOT quote reviews verbatim); connect them to problems the sender's product solves 4. **Value Proposition** — Introduce sender company and products using `product_highlights` from sender-profile.json 5. **CTA** — Low-friction call-to-action: free samples, catalog, or a brief call 6. **Signature** — Use contact info from sender-profile.json (name, title, email, phone, website) #### e) Personalization Tracking Populate the `personalization_context` field on each draft: ```json { "language": "selected language", "pain_points_used": ["pain point 1", "pain point 2"], "reviews_analyzed": true, "sender_product_match": "brief note on how sender product connects to this business" } ``` #### General Rules - Tone: professional, consultative, not salesy - Save the drafts array to a temp JSON file, e.g. `/tmp/drafts-.json` ### 3. Export (scripts/export.ts) Converts drafts to RFC 5322 EML files, uploads individual EMLs + ZIP bundle to R2. ```bash cd ~/clawd/skills/email-content-compose bun run export -- --drafts=/tmp/drafts-.json --workflow-id= [--from=] [--dry-run] ``` Returns: JSON with per-file R2 URLs and a bundle.zip URL. ## Full Pipeline Example ```bash cd ~/clawd/skills/email-content-compose # 1. Fetch leads bun run fetch -- --workflow-id=outreach-xxx > /tmp/leads.json # 2. LLM composes drafts → saves to /tmp/drafts-outreach-xxx.json # 3. Export EML + upload to R2 bun run export -- --drafts=/tmp/drafts-outreach-xxx.json --workflow-id=outreach-xxx ``` ## Config Auth handled automatically by auth-runtime via `~/.openclaw/.env`. R2 and email config in `~/.openclaw/.env`: - `CLOUDFLARE_*`: R2 upload credentials - `SENDER_EMAIL`: From header in EML files