Token导航 LogoToken导航TokenDH.com
开发敏感数据clawhub未标认证来源可访问clear审计通过

mailgo-coldmail-marketingmailgo 冷邮件营销

Agent Skill

mailgo-coldmail-marketing 用于辅助前端页面、组件、样式和交互逻辑开发,适合在 OpenClaw 中需要维护前端项目、生成组件或检查界面实现时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

3,018

周安装

127

GitHub Stars

公开资料未说明

下载量

1,057
OpenClaw

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

MIT-0

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:mailgo-coldmail-marketing(mailgo 冷邮件营销)
来源仓库:https://github.com/leadsnavideveloper/mailgo-coldmail-marketing
安装命令:
openclaw skills install mailgo-coldmail-marketing
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 OpenClaw 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

ClawHubOpenClaw
openclaw skills install mailgo-coldmail-marketing

简介

针对 Mailgo 的冷邮件营销套件,覆盖收件人验证到生命周期管理。

  • 适合需要批量发送个性化邮件、追踪互动或调整投放策略的场景。
  • 支持模板定制、联系人清洗和实时数据看板查看。
  • 应遵守反垃圾邮件法规,避免高频发送导致账号受限。
  • mailgo-coldmail-marketing 属于开发类 Skill,可作为该场景下的辅助能力补充。

SKILL.md

name
mailgo-campaign-suite
description
Complete cold email campaign suite for Mailgo — verify recipients, claim free mailbox, generate & optimize content, create campaigns, manage lifecycle, and view reports. All-in-one skill that handles the full outreach pipeline end-to-end. Use when a user wants to send cold emails, launch outreach campaigns, or manage existing campaigns.
env
MAILGO_API_KEY
required
true
description
>
dependencies
python
>=3.7
optional

Mailgo Campaign Suite

One skill, complete cold email pipeline. From recipient verification to campaign reporting — everything runs through bundled scripts with zero third-party dependencies.


Step 0 — Authentication Setup

Required: MAILGO_API_KEY environment variable must be set before any other step.

Quick check

# Confirm the variable is set (shows first 5 characters only)
echo "${MAILGO_API_KEY:0:5}"

If output is non-empty → proceed to Step 1. If empty → follow the setup flow below.

Setup Flow

Sub-step 0.1 — Register or Log In

New users:

  1. Go to https://app.mailgo.ai
  2. Click "Sign Up" and complete registration

Existing users:

  1. Go to https://app.mailgo.ai
  2. Log in with your credentials

Sub-step 0.2 — Create Personal Token

Once logged in:

  1. Click your avatar in the bottom-left corner
  2. Select Personal Tokens from the menu
  3. Click Create Token
  4. Give your token a descriptive name (e.g., "Claude Code")
  5. Copy the generated token
SECURITY: Never paste the token into chat. It must only be set as a local environment variable.

Sub-step 0.3 — Set Environment Variable

# macOS / Linux (permanent)
echo 'export MAILGO_API_KEY="YOUR_TOKEN"' >> ~/.zshrc && source ~/.zshrc

# Windows PowerShell (permanent)
[System.Environment]::SetEnvironmentVariable('MAILGO_API_KEY', 'YOUR_TOKEN', 'User')

Replace YOUR_TOKEN with the copied value.

Sub-step 0.4 — Verify

# macOS / Linux — shows first 5 characters to confirm without exposing the token
echo "${MAILGO_API_KEY:0:5}"

# Windows PowerShell
$k = $env:MAILGO_API_KEY; if ($k) { $k.Substring(0, [Math]::Min(5, $k.Length)) } else { "" }

If output is non-empty, you're ready. If empty, run source ~/.zshrc or open a new terminal.

Key Facts

ItemValue
Token sourceapp.mailgo.ai → Avatar → Personal Tokens
Env variable nameMAILGO_API_KEY
API headerX-API-Key: {MAILGO_API_KEY}
Token scopeYour Mailgo account (mailboxes, campaigns, reports)
Revoke tokenapp.mailgo.ai → Avatar → Personal Tokens → Delete

Auth Error Handling

IssueFix
Empty after source ~/.zshrcOpen a new terminal window
401 UnauthorizedToken may be invalid or deleted — create a new one in Personal Tokens
403 ForbiddenEnsure User-Agent header is set (scripts handle this automatically)

Step 0.5 — Upfront Information Gathering

Collect all required information in a single interaction before starting the pipeline.

Ask all questions at once. Do not ask in separate rounds. The user fills in what they know; mark anything skipped as "not provided".

When to run: Only when the user intends to create a new campaign. Skip for report/manage/replies tasks.

Group A — Your Information (for email signature & credibility)

Ask all of these together in one message:

#QuestionFieldRequired?
1What is your company name?sender_companyYes
2What is your name (for the signature)?sender_nameYes
3What does your company offer (products / services)?sender_offeringsYes
4What is your job title?sender_titleRecommended
5What is your company website?sender_websiteRecommended
6Any notable clients, certifications, or metrics to mention?sender_proofOptional

Group B — Your Recipients

Ask all of these together in the same message as Group A:

#QuestionField
7Who are you sending to? Paste emails, or provide a file path (CSV / XLSX / TXT).recipients
8What is the goal of this campaign? (one sentence)campaign_purpose
9Do your recipients have names available? (column name or yes/no)has_name
10Do you have recipients' company names? (column name or yes/no)has_company
11Do you have recipients' job titles? (column name or yes/no)has_title
12Do you have recipients' company websites / domains? (column name or yes/no)has_domain
If the user provides a file, auto-detect columns after reading the file headers — then mark fields 9–12 automatically without asking again. ⚠ Header Warning: Column detection relies entirely on header names. Files without headers (e.g. a bare two-column XLSX with email + company but no row of column names) will only have col_0, col_1, … as synthetic headers — none of which match any known field name. As a result, only the email column can be identified by content scanning; all other columns (company, name, title, domain) will be silently discarded. Whenever a user provides a headerless file and you can see that extra columns exist (e.g. "two-column spreadsheet"), proactively warn them: _"Your file appears to have no header row. Only email addresses were imported — company names and other fields were not recognized. Add a header row (e.g. email, company, name) and re-upload to include that data."_

Auto-Derive Name from Email Prefix (CRITICAL)

Immediately after receiving the recipient list, check whether name data is available. If has_name is false (no name column detected, no names provided inline):

  1. Extract name from each email's local-part (the portion before @):

- Split on ., -, _ → capitalize each segment → join with space - Examples: alice.smith@co.com"Alice Smith", john_doe@co.com"John Doe", jdoe@co.com"Jdoe"

  1. Store the derived name into each recipient entry in session_context.recipients
  2. Set recipient_fields.name = true with source noted as "auto-derived from email prefix"
  3. Do this silently — do not ask the user, do not announce it; just note it in the Step 3 change summary

This ensures #{Name} is always available as long as there are valid email addresses.


Handling Partial Answers

SituationAction
User skips a required field (1, 2, 3, 7, 8)Ask once more specifically for that field only
User skips a recommended field (4, 5)Mark as not provided, do not ask again
User skips an optional field (6)Mark as not provided, move on
User says "I'll send to a file I haven't uploaded yet"Ask for file path, then detect columns
User provides inline recipients with no extra dataAuto-derive names from email prefixes (see above); mark fields 10–12 as not provided
User provides a file without a header row and extra columns are presentWarn: only emails were imported; other columns were discarded. Ask user to add a header row (email, company, name, etc.) and re-upload

Carry Forward

Store all answers as session context. Every subsequent step uses this context directly — never ask for the same information again.

session_context = {
  sender_company:   "...",   # or null
  sender_name:      "...",   # or null
  sender_title:     "...",   # or null
  sender_website:   "...",   # or null
  sender_offerings: "...",   # or null
  sender_proof:     "...",   # or null
  recipients: [              # each entry always has a name (user-provided or auto-derived)
    { email: "...", name: "...", company: "...", title: "...", domain: "..." },
    ...
  ],
  campaign_purpose: "...",
  recipient_fields: {
    name:    true,           # ALWAYS true — either user-provided or auto-derived from email prefix
    company: true/false,
    title:   true/false,
    domain:  true/false,
  }
}

Step 1 — Verify Recipient Emails

Always verify before sending to >10 recipients.

Use the bundled script (MANDATORY)

source ~/.zshrc

# Option A: inline emails
python3 scripts/verify_emails.py alice@example.com bob@gmail.com

# Option B: from file (TXT/CSV/JSON)
python3 scripts/verify_emails.py --file leads.csv

# Option C: override column detection
python3 scripts/verify_emails.py --file leads.csv --email-column "Email Address"

Script flags:

FlagDefaultDescription
emailsSpace-separated email addresses
--fileRead from TXT/CSV/JSON file
--email-columnauto-detectOverride email column name
--timeout180Poll timeout in seconds
--interval5Poll interval in seconds

Output: JSON on stdout with categorized results:

{
  "total": 5,
  "valid": [{"email": "...", "status": "VALID"}],
  "invalid": [...],
  "domain_error": [...],
  "unknown": [...],
  "unchecked": [...]
}

Email Status Values

StatusMeaningRecommendation
VALIDConfirmed deliverableSend
UNKNOWNCatch-all or greylistingSend with caution
DOMAIN_ERRORNo MX recordsDo not send
INVALIDMalformed or SMTP-rejectedDo not send
UNCHECKEDStill processingWait or re-poll

Filtering guidance: Conservative = VALID only. Aggressive = VALID + UNKNOWN.

Behavior Rules

  • Never report results while UNCHECKED entries remain (unless timeout)
  • Show progress during polls: "Verifying... X/total processed"
  • Ask before filtering: "Found N undeliverable addresses. Remove them?"
  • Credit error = stop immediately
  • UNKNOWN is not a hard block — explain the tradeoff

API Details (edge cases only)

  • Submit: POST /sirius/api/biz/email/verification — body: {"emails": [...]}
  • Poll: GET /sirius/api/biz/email/verification/task/{taskId}
  • Max 10,000 emails per task; script auto-batches larger lists
  • 120 req/min rate limit; on 429 wait 60s

Step 2 — Claim Free Pre-Warmed Mailbox

Run before creating any campaign. Each user gets one free mailbox (60 days, 90+ sender score).

Use the bundled script (MANDATORY)

source ~/.zshrc

# Claim (idempotent — safe to run multiple times)
python3 scripts/claim_free_mailbox.py

# JSON output for scripting
python3 scripts/claim_free_mailbox.py --json

What you get:

  • Pre-warmed mailbox with 90+ sender score
  • 60-day validity, no credit card required
  • Idempotent: re-running returns the same mailbox
  • stdout outputs just the email address (for piping)
Note: The free mailbox uses a randomly assigned domain (e.g. you@randomdomain.io) which may not match your company domain. If brand consistency matters, consider purchasing a dedicated domain at https://app.mailgo.ai.

Auto-integration

After claiming, use the returned email as --sender in Step 4:

SENDER=$(python3 scripts/claim_free_mailbox.py)
python3 scripts/run_campaign.py --sender "$SENDER" ...

API Details (edge cases only)

  • Endpoint: POST /api/biz/benefits/assign-prewarm
  • Auth: X-API-Key: {key}
  • Response: {"code": 0, "data": "email@domain.com"}
  • data: null = pool empty, contact support

Step 3 — Generate & Optimize Email Content

This is a knowledge-and-rewrite step. No API calls. No scripts.

Apply the 6-step optimization pipeline to user content, or generate from scratch.

Prerequisites for Generation — Use Session Context (CRITICAL)

All sender and recipient information was collected in Step 0.5. Do NOT ask again.

Read directly from session_context:

Context fieldUse in email
sender_nameSignature name
sender_titleSignature title (omit if null)
sender_companySignature company + body references
sender_websiteSignature website (omit if null)
sender_offeringsValue bridge paragraph
sender_proofProof point sentence (omit if null)
recipient_fields.nameAlways true — use #{Name} unconditionally (user-provided or auto-derived from email prefix in Step 0.5)
recipient_fields.companyUse #{Company Name} only if true
recipient_fields.titleUse #{Title} only if true
recipient_fields.domainUse #{Domain} only if true
If session_context is missing (e.g. user jumped directly to Step 3), collect the missing fields inline — but only the ones not yet known.

Template Variables and Placeholder Rules (CRITICAL)

Mailgo uses #{...} placeholders that are resolved server-side at send time:

PlaceholderDescriptionResolved from
#{Name}Recipient's namecontactName in leads data
#{Company Name}Company namecompanyName in leads data
#{Domain}Company websitedomain in leads data
#{Title}Job titletitle in leads data
#{Email}Email addresscontactEmail in leads data

CRITICAL — Conditional Placeholder Rule:

  • ONLY use a #{...} placeholder if the corresponding data is confirmed available (either from the file columns or user-provided inline data).
  • If a field has NO data, NEVER use its #{...} placeholder. The placeholder will resolve to empty string at send time, creating ugly output like ,您好 or 关于 的合作.
  • Exception: #{Name} is ALWAYS available. Every recipient has a name — either provided by the user or auto-derived from the email prefix in Step 0.5. Never fall back to "您好" when you have email addresses.
  • For other fields, use a generic alternative:
PlaceholderIf data availableIf data NOT available
#{Name}#{Name},您好_(never happens — always use #{Name})_
#{Company Name}关于 #{Company Name} 的合作关于贵公司的合作 / About a potential partnership
#{Domain}我浏览了 #{Domain}Omit this sentence entirely
#{Title}作为 #{Title}Omit or use generic phrasing

Log placeholder decisions in the change summary:

Placeholders used: #{Name} (data available), #{Email} (always available)
Placeholders skipped: #{Company Name} (no data), #{Title} (no data), #{Domain} (no data)

Optimization Pipeline (execute ALL 6 steps, in order)

Step 3.1 — Normalize

  • Plain text input → wrap in HTML skeleton (see below)
  • HTML input → preserve structure

Step 3.2 — Spam Trigger Scan

  • Scan subject + body against resources/spam-triggers.md
  • Replace each trigger with neutral alternative
  • Log every replacement

Key replacements (most common):

TriggerReplacement
free / free trialincluded / trial period
Click hereLearn more / See details
Act nowWhen you're ready
Limited timeWhile available
GuaranteedProven
Dear friendHi #{Name}
ALL CAPS wordsSentence case
!!! / ???Single punctuation

Full replacement table: resources/spam-triggers.md

Step 3.3 — HTML Cleanup

  • Remove: <script>, <style>, <meta>, <link>, <iframe>, <embed>, <object>
  • Remove: event handlers (onclick, onload, etc.)
  • Convert <style> blocks → inline styles, then remove block
  • Remove: HTML comments, CSS !important, base64 images
  • Ensure: all <img> have alt attributes

Step 3.4 — Structure Check

  • Text-to-image ratio > 60% text (warn if image-heavy)
  • Cold email target: < 150 words (flag if > 200)
  • One CTA only (suggest consolidation if multiple)
  • Placeholder Data Validation — scan all #{...} in the content against session_context.recipient_fields:

- #{Name} and #{Email} → always safe, never touch - #{Company Name} → if recipient_fields.company == false: replace with generic text (e.g. 贵公司 / your company); log the replacement - #{Domain} → if recipient_fields.domain == false: remove the sentence containing it entirely; log the removal - #{Title} → if recipient_fields.title == false: replace with generic phrasing or omit; log the replacement - If data IS available for a placeholder: preserve it unchanged

Step 3.5 — Link Audit

  • Replace URL shorteners (bit.ly, t.co, tinyurl, goo.gl, ow.ly) with full URLs
  • Warn if > 3 links in cold email
  • Remove javascript: and data: URLs

Step 3.6 — Final Polish

  • Add soft opt-out line if missing (see below)
  • Verify HTML is well-formed
  • Write to /tmp/email_optimized_<timestamp>.html

Content Generation (from scratch)

Generate 4 subject line variants for A/B testing. Adapt based on available data:

If #{Company Name} data IS available:

#StrategyExample
1Value propositionHow #{Company Name} can cut onboarding time by 60%
2Industry insightA shift I'm seeing in #{Company Name}'s space
3Case study / metricsHow [similar company] grew pipeline 3x in 90 days
4Curiosity / questionQuick question about #{Company Name}'s [process]

If #{Company Name} data is NOT available:

#StrategyExample
1Value propositionCutting onboarding time by 60% — here's how
2Industry insightA shift I'm seeing in the [industry] space
3Case study / metricsHow [similar company] grew pipeline 3x in 90 days
4Curiosity / questionA quick question about your [process]

Subject rules: 40-50 chars, always personalize with #{Name} (always available); use #{Company Name} only if data available. No ALL CAPS, no spam triggers, no fake Re:/Fwd:.

Body structure (adapt based on available fields):

1. Personal opener (1 sentence)
   - ALWAYS use "#{Name},您好:" — #{Name} is always available (user-provided or auto-derived)
   - WITH #{Company Name}: reference it in opener
   - WITHOUT #{Company Name}: use generic "贵公司" / "your company" or omit

2. Value bridge (1-2 sentences) — connect their situation to your offering
3. Proof point (1 sentence) — specific metric or case study (use sender_proof if available)
4. Soft CTA (1 sentence) — question, not demand
5. Signature — use actual sender_name + sender_title + sender_company (NEVER use placeholders like [Name])
6. Soft opt-out

Body rules: under 150 words, conversational tone, one CTA. All sender info in signature must be real data, not placeholders.

Select industry template from resources/industry-templates.md based on user's offerings.

HTML Skeleton

Use for plain-text wrapping or building from scratch:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body style="margin:0; padding:20px; font-family:Arial, sans-serif; font-size:14px; line-height:1.6; color:#333333;">
  <div style="max-width:600px; margin:0 auto;">

    <!-- EMAIL CONTENT HERE -->

  </div>
</body>
</html>

Soft Opt-Out Line

Always add after signature if missing:

P.S. If this isn't relevant, just reply and let me know — I won't reach out again.

Change Summary Format

Email Optimization Complete
---
Industry template: SaaS / Software (matched from "AI deployment platform")
Sender info: Zhang Wei, Sales Director, TirePro Technologies (www.tirepro.com)
Recipient data available: name (auto-derived from email prefix), company (no), title (no), domain (no)
Placeholders used: #{Name} (auto-derived from email prefix — e.g. alice.smith@co.com → "Alice Smith")
Placeholders skipped: #{Company Name}, #{Title}, #{Domain} (no data — generic wording used)
Spam triggers replaced: 3
  - "free trial" → "trial period"
  - "Click here" → "Learn more"
  - "Act now" → "When you're ready"
HTML issues fixed: 1
  - Removed <script> tag
Structure: 118 words (OK)
Links: 2 (OK)
Opt-out: Added
Subjects generated: 4 variants

Output: /tmp/email_optimized_1711468800.html
→ Use with: --body-file /tmp/email_optimized_1711468800.html

Severity Levels

LevelIssues
Critical (must fix)<script> tags, shortener URLs, base64 images, javascript: URLs, "This is not spam", #{Company Name}/#{Domain}/#{Title} placeholders with no corresponding recipient data
Warning (recommend)Spam trigger words, image-heavy, >3 links, missing opt-out
InfoWord count >150, multi-punctuation, subject line suggestions

Behavior Rules

  • Run automatically before every campaign send, even if not asked. Report "0 issues found" if clean.
  • If user says "don't change my content": scan and report only, do not modify.
  • Never change meaning. Replace words, don't rewrite paragraphs.
  • Placeholder rule differs by scenario:

- Generating content from scratch: NEVER write a #{...} placeholder unless the corresponding recipient_fields value is true. Use the generic alternatives from the Placeholder Rules table instead. - Optimizing existing content: if the content already contains a #{...} placeholder with NO data available, MUST replace it with the generic alternative (Step 3.4 Placeholder Data Validation). Do not silently preserve it — an unresolved placeholder will appear as a blank gap to the recipient. - Exception: #{Name} and #{Email} are always safe — never remove or replace them.

  • NEVER use [bracketed placeholders] like [Name], [Company], [Title] in final email output. These must be replaced with actual sender data or omitted. They are template authoring aids, not send-time variables.
  • Always use actual sender info (name, title, company, website) in the email signature — collected from the user in the Prerequisites step.
  • Write HTML to /tmp/email_optimized_<timestamp>.html and use via --body-file.

Step 4 — Create & Send Campaign

Use the bundled script (MANDATORY)

source ~/.zshrc

# Option A: inline recipients
python3 scripts/run_campaign.py \
    --sender "claimed@mailbox.com" \
    --subject "Quick question about #{Company Name}" \
    --body-file /tmp/email_optimized_1711468800.html \
    --recipients "alice@example.com,bob@test.com" \
    --campaign-name "SaaS Outreach Mar 2026" \
    --daily-limit 50

# Option B: recipients from file (CSV/XLSX/TXT/JSON)
python3 scripts/run_campaign.py \
    --sender "claimed@mailbox.com" \
    --subject "Quick question about #{Company Name}" \
    --body-file /tmp/email_optimized_1711468800.html \
    --recipients-file leads.xlsx \
    --campaign-name "SaaS Outreach Mar 2026"

Script flags:

FlagDefaultDescription
--senderrequiredSender email (from Step 2)
--subjectrequiredSubject line
--bodyHTML body (or use --body-file)
--body-fileRead body from file (from Step 3)
--recipientsComma-separated emails
--recipients-fileCSV/XLSX/TXT/JSON file
--email-columnautoOverride email column name
--name-columnautoOverride name column name
--company-columnautoOverride company column name
--title-columnautoOverride title/job column name
--domain-columnautoOverride domain/website column name
--recipient-namesauto from emailComma-separated display names
--recipient-companiesComma-separated company names
--recipient-titlesComma-separated job titles
--recipient-domainsComma-separated company websites
--campaign-name"Campaign"Display name
--timezone-idAsia/SingaporeTimezone
--timezone-offset+08:00UTC offset
--send-days1,2,3,4,5Days (1=Mon...7=Sun)
--send-hours9,18Start,end hour
--daily-limit50Daily send limit
--no-trackingoffDisable open/click tracking
--dry-runoffCreate but do not activate

Output: JSON summary with campaignId, emailContentId, lead counts, activation status.

Agent Decision Framework

All campaign inputs were collected in Step 0.5. Use session_context directly.

From session_context (never ask again):

  • Recipients — session_context.recipients
  • Purpose/goal — session_context.campaign_purpose
  • Sender info — sender_company, sender_name, sender_title, sender_website, sender_offerings, sender_proof
  • Recipient field availability — recipient_fields.{name, company, title, domain}

Auto-inferred (never ask):

  • Sender email — auto-assigned from Step 2 (free mailbox)
  • Subject — generate from campaign_purpose (Step 3), using only placeholders with confirmed recipient_fields
  • Body — generate personalized HTML (Step 3), respecting recipient_fields availability
  • Campaign name — derived from campaign_purpose + current month (e.g. "Tire Outreach Mar 2026")
  • Schedule — Mon-Fri 9am-6pm, Asia/Singapore timezone
  • Daily limit — 50 for new accounts
  • Tracking — open + click ON

Decision Flow

0.5. [Already done] All info collected upfront — use session_context throughout
1.   Verify recipients (Step 1) if > 10 emails
2.   Claim mailbox (Step 2) if no sender specified
3.   Generate & optimize content (Step 3) — use ONLY placeholders with confirmed recipient_fields
4.   Run scripts/run_campaign.py (Step 4) — pass all available recipient fields
5.   Report: campaignId, name, lead count, activation status

API Reference (edge cases only)

Campaign creation is a 4-step sequential flow handled by the script:

Step 4a — Upload content:  POST /campaign/api/biz/mailgo/email/content/upload
Step 4b — Create campaign: POST /campaign/api/biz/mailgo/campaign/save
Step 4c — Add leads:       POST /campaign/api/biz/mailgo/leads/add
Step 4d — Activate:        POST /campaign/api/biz/mailgo/campaign/operate

Fall back to raw API only for: updating existing campaigns or adding leads from contact groups.


Step 5 — Manage Campaign Lifecycle

Use the bundled script (MANDATORY)

source ~/.zshrc

# Activate / Pause / Delete
python3 scripts/campaign_control.py activate <campaignId>
python3 scripts/campaign_control.py pause    <campaignId>
python3 scripts/campaign_control.py delete   <campaignId>   # confirm with user first!

# List campaigns
python3 scripts/campaign_control.py list                    # all
python3 scripts/campaign_control.py list --status 1         # active
python3 scripts/campaign_control.py list --status 0         # paused
python3 scripts/campaign_control.py list --name "outreach"  # fuzzy search

# Get campaign detail
python3 scripts/campaign_control.py info <campaignId>

Decision Flow

User says "stop/pause/resume/delete <campaign>"

1. Know campaign ID?
   YES → run script directly
   NO  → run: scripts/campaign_control.py list --status 1,0
         show results, ask user to pick one

2. If delete → confirm: "Delete campaign '{name}'? This cannot be undone."

3. Run script, report: "Campaign '{name}' (ID: {id}) is now {STATUS}."

Campaign Status Reference

CodeNameDescription
-1DRAFTNot activated
0PAUSEPaused
1ACTIVESending
2COMPLETEAll leads processed
3ERRORError state

State transitions: DRAFT->ACTIVE, ACTIVE<->PAUSE, any->deleted

Abnormal States (abnormalType)

CodeMeaningAction
1Monthly quota exhaustedUpgrade plan
2Some sender accounts have issuesCheck account settings
4All sender accounts have issuesFix sender accounts first
9Daily sending limit reachedWait for next day
11Email quota exhaustedUpgrade plan

Step 6 — View Campaign Reports

Use the bundled script (MANDATORY)

source ~/.zshrc

# Overview stats
python3 scripts/campaign_report.py overview <campaignId>

# Per-round breakdown
python3 scripts/campaign_report.py rounds <campaignId>

# Daily progress (requires date range)
python3 scripts/campaign_report.py daily <campaignId> --start 2026-03-25 --end 2026-03-31

# List replies (metadata only)
python3 scripts/campaign_report.py replies <campaignId>

# List replies + read plain-text body of each reply
python3 scripts/campaign_report.py replies <campaignId> \
    --sender "sender@mailbox.com" \
    --read-content

# Raw JSON output
python3 scripts/campaign_report.py --json overview <campaignId>

Output Format

Always show rates, not raw numbers alone:

Campaign: "Q1 Outreach" (ID: 123456)  Status: ACTIVE
Leads: 500 total | 250 completed | 30 in progress | 200 not yet | 20 failed

  Sent:       450
  Delivered:  420  (93.3%)
  Opened:     180  (42.9%)
  Replied:     35  ( 8.3%)
  Clicked:     65  (15.5%)
  Bounced:     30  ( 6.7%)

Deliverability Health Metrics

MetricHealthyCritical
Open rate>20%<10%
Bounce rate<2%>5%
Spam complaints<0.1%>0.3%

API Reference (for advanced queries)

ReportEndpoint
OverviewPOST /campaign/api/biz/mailgo/stat/overview
Per-roundPOST /campaign/api/biz/mailgo/stat/sequence-info
Send recordsPOST /campaign/api/biz/mailgo/stat/sequence-detail
Reply listPOST /campaign/api/biz/mailgo/stat/sequence-detail-reply
Reply contentPOST /tp/api/hmail/proxyfunc: mbox:readMessage, mid: <messageId>
Reply detailPOST /campaign/api/biz/mailgo/stat/sequence-detail-reply
Click detailPOST /campaign/api/biz/mailgo/stat/sequence-detail-click
Contact historyPOST /campaign/api/biz/mailgo/stat/leads-send
Daily progressPOST /campaign/api/biz/mailgo/stat/daily-step

Behavior Rules

  • Default to overview. Drill into details only on explicit request.
  • Always show rates alongside raw counts.
  • If sent == 0: say "No emails sent yet" — do not divide by zero.
  • If no campaign ID: list campaigns first, offer to drill into one.
  • If openClick == 0: tracking was disabled — say so.
  • If replied > 0 in overview: proactively suggest reading replies:
  💬 X reply(ies) detected. Run the following to read them:
  python3 scripts/campaign_report.py replies <campaignId> \
      --sender <senderEmail> --read-content

Global Error Handling

HTTPAction
401Re-run Step 0 (token expired or invalid)
403Ensure User-Agent header is set
429Wait 60s, retry
500Retry after 10s
502/503Retry after 30-60s

Global Behavior Rules

  1. Script-first: Always use bundled scripts. Never reimplement API calls inline.
  2. Verify before send: Always run Step 1 for campaigns with >10 recipients.
  3. Optimize before send: Always run Step 3 before sending, even if not explicitly asked. Report "0 issues" if clean.
  4. Confirm destructive actions: Always confirm before delete. Campaign deletion is irreversible via API.
  5. Security: Never handle API keys in chat. User must create token in Personal Tokens and set as environment variable.
  6. Zero dependencies: All scripts use Python stdlib only (urllib, json, csv, ssl). No pip install required (except optional openpyxl for .xlsx files).

适合场景

01

OpenClaw 用户查找和安装 Skill 时

02

用户想查找某类 Agent Skill 时

03

需要根据任务场景推荐可安装能力包时

04

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

补充不同宿主或平台的使用分布数据

能力 5

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

OpenClaw

76.02%
按下载量换算804

安全审计

VirusTotal

通过

ClawScan

通过

Static analysis

通过

权限和风险

敏感数据

该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills