email-content-compose/SKILL.md

4.0 KiB
Raw Blame History

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.

cd ~/clawd/skills/email-content-compose
bun run fetch -- --workflow-id=<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 12 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:

{
  "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-<workflow-id>.json

3. Export (scripts/export.ts)

Converts drafts to RFC 5322 EML files, uploads individual EMLs + ZIP bundle to R2.

cd ~/clawd/skills/email-content-compose
bun run export -- --drafts=/tmp/drafts-<workflow-id>.json --workflow-id=<id> [--from=<email>] [--dry-run]

Returns: JSON with per-file R2 URLs and a bundle.zip URL.

Full Pipeline Example

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