Send and receive emails using the Resend API. Use for: (1) sending emails directly via Resend API, (2) receiving email notifications via cron, (3) drafting r...
数据来源:ClawHub。 在 ClawSkills 查看
选择你使用的 Agent
方法一:命令行安装(推荐)
推荐(无需提前安装 clawhub)
npx clawhub@latest --dir ~/.claude/skills install email-resend或使用 clawhub CLI(需提前安装)
clawhub --dir ~/.claude/skills install email-resend⚠️ 需要 Node.js 18+,没有 Node?请使用下方方法二直接下载 ZIP。 安装 Node.js →
方法二:手动下载安装(无需 Node)
下载 ZIP,解压后将文件夹放到以下路径,重启 Agent 即可:
安装路径
~/.claude/skills/email-resend/💡解压后将文件夹放到上方路径,重启 Agent 即可生效
--- license: Apache-2.0 name: email-resend version: "1.0.14" metadata: clawdbot: requires: env: - RESEND_API_KEY bins: - python3 - openclaw python: - requests - pyyaml triggers: - "send email" - "check emails" - "email me" - "email notification" - "download attachment" description: > Send and receive emails using the Resend API. Use for: (1) sending emails directly via Resend API, (2) receiving email notifications via cron, (3) drafting replies with proper threading, (4) downloading attachments from inbound emails.
Required env vars: RESEND_API_KEY (API key). Optional env vars: DEFAULT_FROM_EMAIL, DEFAULT_FROM_NAME (fall back to preferences file if not set). License: Apache-2.0 — See LICENSE file for details. ---
Apache License 2.0 — See LICENSE file for full text.
Send and receive emails using the Resend API.
No config file needed. The skill auto-discovers settings from:
memory/email-preferences.md (from_email, from_name, telegram target)export RESEND_API_KEY="re_123456789" # Resend API key (required)
# DEFAULT_FROM_EMAIL and DEFAULT_FROM_NAME are optional - loaded from preferences file if not set
The skill reads sender info from memory/email-preferences.md:
---
from_email: [email protected]
from_name: Your Name
telegram:
target: "CHAT_ID"
threadId: "THREAD_ID"
---
Scripts check env vars first, then fall back to preferences file.
When the skill is first invoked, the sub-agent should:
- context.user.email (from USER.md) - context.channel (from current session) - context.chat_id - context.thread_id (for topics)
memory_get tool: - Try: memory_get path="memory/email-preferences.md" - If not found, ask user to create memory/email-preferences.md (NO fallback scanning)
- "Which email should I send from?" (from_email) - "What's your display name for sent emails?" (from_name) - "Which channel/topic should I notify you on?" (telegram target + threadId)
Then create memory/email-preferences.md with their answers using the format above.
```bash write path="memory/email-preferences.md" content="--- from_email: $EMAIL from_name: $NAME telegram: target: \"$CHAT_ID\" threadId: \"$THREAD_ID\" ---
# Email Notification Preferences Saved auto-configured " ``` This ensures memory_get finds it in future sessions. Use MD format with YAML frontmatter.
Format (MD with YAML frontmatter):
---
from_email: [email protected]
from_name: Your Name
telegram:
target: \"123456789\"
threadId: \"334\"
---
# Email Notification Preferences
- **Updated:** 2026-01-01
- **Purpose:** Default notification channel for email alerts
Important: Store in memory/email-preferences.md (NOT MEMORY.md) - isolated cron jobs can read this file via memory_get but NOT MEMORY.md.
| Field | Source | Example | |-------|--------|---------| | user.email | USER.md | [email protected] | | user.name | USER.md | Your Name | | channel | OpenClaw | from context | | chat_id | OpenClaw | 123456789 | | thread_id | OpenClaw | 334 |
The skill uses these directly from OpenClaw context — no parsing needed.
There are two ways to configure the cron:
Use this if you always want the same delivery target:
openclaw cron add \
--name "email-resend-inbound" \
--cron "*/15 * * * *" \
--message "Follow instructions in skills/email-resend/cron-prompts/email-inbound.md exactly. If new emails found, include them in your reply." \
--session isolated \
--announce \
--channel telegram \
--to "-1003748898773:topic:334"
This reads your notification preferences from memory/email-preferences.md and configures the cron automatically.
Run:
python3 ~/.openclaw/workspace/skills/email-resend/scripts/configure-cron.py
What it does:
memory/email-preferences.md for your telegram target/threadIdemail-resend-inbound cronFirst-time setup: If preferences don't exist, it will tell you what to configure.
Parameters:
--schedule "cron /15 *" — Run every 15 minutes--session isolated — Required for agentTurn payloads--announce — Enable delivery of results to chat--channel telegram — Delivery channel--to — Telegram target (format: chat_id:topic:thread_id)Note: The cron prompt reads notification preferences from memory/email-preferences.md. On first run, if preferences are missing, it will ask you for:
python3 ~/.openclaw/workspace/skills/email-resend/scripts/inbound.py
Each new email triggers a notification with:
NEVER auto-acknowledge emails. Only the user can acknowledge by:
done / ackEmails must remain in pending state until user explicitly acknowledges.
Use draft-reply.py to compose replies with proper quoting.
Important: Always use inline replies ([[reply_to_current]]) to keep messages linked in the thread. This enables:
CRITICAL: When responding via OpenClaw message tool, use replyTo parameter (not [[reply_to_current]] tag):
message(action="send", channel="<from-context>", replyTo="<msg_id>", ...)
| Script | Purpose | |--------|---------| | inbound.py | Check emails, send notifications | | draft-reply.py | Draft reply workflow with quoting & threading | | outbound.py | Send emails directly | | download_attachment.py | Download attachments from inbound emails |
To download attachments from an inbound email:
# List attachments (shows IDs)
python3 scripts/download_attachment.py <email_id> --list
# Download all to directory
python3 scripts/download_attachment.py <email_id> --output-dir ./attachments
# Download specific attachment
python3 scripts/download_attachment.py <email_id> --attachment-id <attachment_id>
Note: The API path is /emails/receiving/{email_id}/attachments (not the standard /emails/ path).
memory/email-resend-inbound-notified.json — pending/acknowledged emailsmemory/email-message-map.json — notification message_id → email_id (legacy)memory/email-custody-chain.json — Full DAG of email → notification → actionsmemory/email-msg-to-chain.json — notification message_id → chain lookupmemory/email-draft-state.json — Active draft state (email_id, status, reply_content)See docs/custody-chain.md for DAG design.
python3 ~/.openclaw/workspace/skills/email-resend/scripts/outbound.py \
--to "[email protected]" \
--subject "Hello" \
--body "Message text"
# With attachments
python3 ~/.openclaw/workspace/skills/email-resend/scripts/outbound.py \
--to "[email protected]" \
--subject "Here's the file" \
--body "See attachment" \
--attachment ./file.pdf \
--attachment ./image.png
MANDATORY: Always use draft-reply.py for replying to emails.
This is non-negotiable. Failure to follow this rule will result in broken Gmail threading.
In-Reply-To AND References headers# Step 1: Start draft (fetches Message-ID automatically)
python3 ~/.openclaw/workspace/skills/email-resend/scripts/draft-reply.py start <email_id>
# Step 2: Set reply content
python3 ~/.openclaw/workspace/skills/email-resend/scripts/draft-reply.py content "Your reply"
# Step 3: Send
python3 ~/.openclaw/workspace/skills/email-resend/scripts/draft-reply.py send
When user approves a draft, you MUST execute the send command immediately.
The mistake to avoid:
draft-reply.py send → Then confirmCorrect workflow:
1. Show draft for approval
2. User replies "approve", "send", "yes", or "ok"
3. IMMEDIATELY run: draft-reply.py send
4. Only THEN confirm to user
Never:
NEVER use outbound.py for replies:
# WRONG - will break threading
python3 ~/.openclaw/workspace/skills/email-resend/scripts/outbound.py \
--to "[email protected]" --subject "Re: Original" --body "Reply"
NEVER manually construct --reply-to flags:
# WRONG - guessing Message-ID format never works
python3 ~/.openclaw/workspace/skills/email-resend/scripts/outbound.py \
--to "[email protected]" --subject "Re: Original" --body "Reply" \
--reply-to "<some-guess>@resend"
NEVER skip the workflow when subject starts with "Re:":
# WRONG - replying without threading headers breaks thread
python3 ~/.openclaw/workspace/skills/email-resend/scripts/outbound.py \
--to "[email protected]" --subject "Re: Previous Thread" --body "Quick reply"
outbound.py is for new emails only (not replies):
For anything that could be a reply, use draft-reply.py.
RESEND_API_KEY environment variable setrequests libraryWhen composing a reply via draft-reply.py:
> prefix so recipient knows what you're responding toIn-Reply-To and References headers using the original email's Message-IDRe: prefix to maintain thread (but avoid "Re: Re:")``` Your reply here
---
On [date] [original sender] wrote: > quoted original message > continues here ```
resume command to continue.- Email → notification → All replies/actions - DAG structure with parent links - Any message traces back to original email
| Command | Purpose | |---------|---------| | start | Start a draft reply to an email | | resume | Continue a sent thread to reply again | | content "text" | Set reply content | | send | Send the reply | | cancel | Cancel the draft | | status | Show current draft status |
After sending, use resume to reply again to the same thread — threading headers are preserved.
Run tests:
python3 skills/email-resend/tests/test_inbound.py
Expected: 43+ tests total (test_inbound.py: 37, test_threading.py: 6, test_attachments.py: varies).
If tests fail:
---
memory/email-preferences.md.The skill reads ONLY from explicit preferences file:
memory/email-preferences.md — Required for telegram target/threadIdThis restricted approach prevents information leakage from sensitive files.
The configure-cron.py script will create/delete a cron job named email-resend-inbound via OpenClaw CLI.
memory/email-preferences.md to ensure it contains only necessary fields安装 Email Resend 后,可以对 AI 说这些话来触发它
Send a Slack message to the #engineering channel about the deployment
Formats and sends the message with relevant context, tagging the right people
Summarize all unread messages in my inbox from today
Reads messages across connected channels and returns a prioritized summary
Draft a reply to this customer complaint and send it for review
Writes an empathetic, professional response and routes it to the approval queue
将技能文件夹放到 ~/.claude/skills/email-resend/ 目录(个人级,所有项目可用),或 .claude/skills/email-resend/(项目级)。重启 AI 客户端后,用 /email-resend 主动调用,或让 AI 根据上下文自动发现并使用。
Email Resend 支持 Claude、Cursor、OpenClaw,可与这些 AI 平台无缝集成,扩展其能力。
Email Resend 可免费安装使用。请查阅仓库了解许可证信息。
Send and receive emails using the Resend API. Use for: (1) sending emails directly via Resend API, (2) receiving email notifications via cron, (3) drafting r...
Email Resend 属于「Communication」分类,该分类的技能帮助 AI 智能体在此领域执行专业任务。