Gmail Skill
Send, read, search, reply, and manage Gmail directly from OpenClaw.
Setup
Option 1: OAuth2 Access Token (recommended)
- 1. Create OAuth2 credentials at https://console.cloud.google.com/apis/credentials
- Enable the Gmail API at https://console.cloud.google.com/apis/library/gmail.googleapis.com
- Obtain an access token via OAuth2 flow with scopes:
-
https://www.googleapis.com/auth/gmail.send
-
https://www.googleapis.com/auth/gmail.readonly
-
https://www.googleapis.com/auth/gmail.modify
- 4. Set the environment variable:
CODEBLOCK0
Option 2: Refresh Token (long-lived)
If you have a refresh token, set these additional variables:
CODEBLOCK1
All API calls use Bearer auth:
CODEBLOCK2
Token Refresh
If GMAIL_REFRESH_TOKEN is set, refresh the access token before any API call:
CODEBLOCK3
Commands
Send an Email
Parse the user's request for:
| Field | Required | Description |
|---|
| to | yes | Recipient email address(es), comma-separated |
| subject |
yes | Email subject line |
| body | yes | Email body (plain text or HTML) |
| cc | no | CC recipients |
| bcc | no | BCC recipients |
| attachments | no | File paths to attach |
| research | no | Topic to web-search for enriching the email body |
Web Research (if applicable)
If the user wants research-informed content:
- 1. Use
web_search to find relevant information. - Fetch key pages with
xurl or curl for details. - Incorporate findings into the email body naturally.
Compose and Send
Build a raw RFC 2822 message and base64url-encode it:
CODEBLOCK4
Extract the message ID from the response and report success.
Read / Check Inbox
List recent messages:
CODEBLOCK5
For each message, fetch full details:
CODEBLOCK6
Extract and display:
- - From: sender
- Subject: subject line
- Date: when received
- Snippet: preview text
- Body: decoded from base64 (plain text part preferred)
Decode the body:
CODEBLOCK7
Search Emails
CODEBLOCK8
Gmail query examples:
- -
from:user@example.com — from a specific sender - INLINECODE8 — subject contains "invoice"
- INLINECODE9 — unread messages
- INLINECODE10 — date range
- INLINECODE11 — PDFs attached
- INLINECODE12 — labeled important
Fetch and display matching messages using the same read flow above.
Reply to an Email
- 1. Fetch the original message to get
threadId, Message-ID header, and sender. - Build the reply with proper headers:
CODEBLOCK9
Draft an Email
Create a draft without sending:
CODEBLOCK10
Report the draft ID so the user can review it in Gmail before sending.
Manage Labels
CODEBLOCK11
Network Policy
To use this skill inside NemoClaw's sandbox, add a Gmail network policy preset. Create or add to your sandbox policy:
CODEBLOCK12
Notes
- - Gmail API rate limit: 250 quota units per second per user.
- Sending has a daily limit of 2,000 messages for Google Workspace, 500 for free Gmail.
- Access tokens expire after ~1 hour. Use refresh token flow for long-running sessions.
- Attachments require multipart MIME encoding — for large files, use the resumable upload endpoint.
Examples
CODEBLOCK13
Gmail 技能
直接从 OpenClaw 发送、阅读、搜索、回复和管理 Gmail。
设置
选项 1:OAuth2 访问令牌(推荐)
- 1. 在 https://console.cloud.google.com/apis/credentials 创建 OAuth2 凭据
- 在 https://console.cloud.google.com/apis/library/gmail.googleapis.com 启用 Gmail API
- 通过 OAuth2 流程获取访问令牌,作用域包括:
- https://www.googleapis.com/auth/gmail.send
- https://www.googleapis.com/auth/gmail.readonly
- https://www.googleapis.com/auth/gmail.modify
- 4. 设置环境变量:
bash
export GMAIL
ACCESSTOKEN=your-access-token
选项 2:刷新令牌(长期有效)
如果您有刷新令牌,请设置以下额外变量:
bash
export GMAILCLIENTID=your-client-id
export GMAILCLIENTSECRET=your-client-secret
export GMAILREFRESHTOKEN=your-refresh-token
所有 API 调用均使用 Bearer 认证:
bash
curl -s -H Authorization: Bearer $GMAILACCESSTOKEN \
https://gmail.googleapis.com/gmail/v1/users/me/...
令牌刷新
如果设置了 GMAILREFRESHTOKEN,则在任何 API 调用前刷新访问令牌:
bash
GMAILACCESSTOKEN=$(curl -s -X POST https://oauth2.googleapis.com/token \
-d clientid=$GMAILCLIENT_ID \
-d clientsecret=$GMAILCLIENT_SECRET \
-d refreshtoken=$GMAILREFRESH_TOKEN \
-d granttype=refreshtoken | jq -r .access_token)
命令
发送邮件
解析用户的请求,提取以下字段:
| 字段 | 必需 | 描述 |
|---|
| to | 是 | 收件人邮箱地址,多个地址用逗号分隔 |
| subject |
是 | 邮件主题行 |
| body | 是 | 邮件正文(纯文本或 HTML) |
| cc | 否 | 抄送收件人 |
| bcc | 否 | 密送收件人 |
| attachments | 否 | 要附加的文件路径 |
| research | 否 | 用于丰富邮件正文的网络搜索主题 |
网络调研(如适用)
如果用户希望内容基于调研结果:
- 1. 使用 web_search 查找相关信息。
- 使用 xurl 或 curl 获取关键页面的详细信息。
- 将调研结果自然地融入邮件正文。
撰写并发送
构建原始 RFC 2822 消息并进行 base64url 编码:
bash
构建原始消息
RAW_MESSAGE=$(cat <
From: me
To: recipient@example.com
Subject: Email subject
Content-Type: text/html; charset=UTF-8
MIME-Version: 1.0
Email body here.
MSGEOF
)
Base64url 编码(无填充,URL 安全)
ENCODED=$(echo -n $RAWMESSAGE | base64 -w 0 | tr +/ - | tr -d =)
发送
curl -s -X POST \
-H Authorization: Bearer $GMAILACCESSTOKEN \
-H Content-Type: application/json \
https://gmail.googleapis.com/gmail/v1/users/me/messages/send \
-d {\raw\: \$ENCODED\}
从响应中提取消息 ID 并报告成功。
阅读 / 查看收件箱
列出最近的邮件:
bash
列出最新消息(默认 10 条)
curl -s -H Authorization: Bearer $GMAILACCESSTOKEN \
https://gmail.googleapis.com/gmail/v1/users/me/messages?maxResults=10&labelIds=INBOX
对于每条消息,获取完整详情:
bash
curl -s -H Authorization: Bearer $GMAILACCESSTOKEN \
https://gmail.googleapis.com/gmail/v1/users/me/messages/{MESSAGE_ID}?format=full
提取并显示:
- - 发件人:发送者
- 主题:主题行
- 日期:接收时间
- 摘要:预览文本
- 正文:从 base64 解码(优先使用纯文本部分)
解码正文:
bash
从 payload 部分提取纯文本正文
BODY=$(echo $RESPONSE | jq -r
.payload.parts[]? |
select(.mimeType == text/plain) |
.body.data | base64 -d 2>/dev/null)
备用方案:单部分消息
if [ -z $BODY ]; then
BODY=$(echo $RESPONSE | jq -r .payload.body.data | base64 -d 2>/dev/null)
fi
搜索邮件
bash
使用 Gmail 查询语法搜索
curl -s -H Authorization: Bearer $GMAILACCESSTOKEN \
https://gmail.googleapis.com/gmail/v1/users/me/messages?q=QUERY&maxResults=10
Gmail 查询示例:
- - from:user@example.com — 来自特定发件人
- subject:invoice — 主题包含invoice
- is:unread — 未读消息
- after:2026/01/01 before:2026/03/01 — 日期范围
- has:attachment filename:pdf — 附件为 PDF
- label:important — 标记为重要
使用上述相同的阅读流程获取并显示匹配的消息。
回复邮件
- 1. 获取原始消息以获取 threadId、Message-ID 标头和发件人。
- 使用正确的标头构建回复:
bash
RAW_REPLY=$(cat <
From: me
To: original-sender@example.com
Subject: Re: Original subject
In-Reply-To:
References:
Content-Type: text/plain; charset=UTF-8
MIME-Version: 1.0
Reply body here.
MSGEOF
)
ENCODED=$(echo -n $RAWREPLY | base64 -w 0 | tr +/ - | tr -d =)
curl -s -X POST \
-H Authorization: Bearer $GMAILACCESSTOKEN \
-H Content-Type: application/json \
https://gmail.googleapis.com/gmail/v1/users/me/messages/send \
-d {\raw\: \$ENCODED\, \threadId\: \THREAD_ID\}
草稿邮件
创建草稿而不发送:
bash
ENCODED=$(echo -n $RAWMESSAGE | base64 -w 0 | tr +/ - | tr -d =)
curl -s -X POST \
-H Authorization: Bearer $GMAILACCESSTOKEN \
-H Content-Type: application/json \
https://gmail.googleapis.com/gmail/v1/users/me/drafts \
-d {\message\: {\raw\: \$ENCODED\}}
报告草稿 ID,以便用户在发送前可以在 Gmail 中查看。
管理标签
bash
列出所有标签
curl -s -H Authorization: Bearer $GMAILACCESSTOKEN \
https://gmail.googleapis.com/gmail/v1/users/me/labels | jq .labels[] | {name, id}
为消息添加标签
curl -s -X POST \
-H Authorization: Bearer $GMAILACCESSTOKEN \
-H Content-Type: application/json \
https://gmail.googleapis.com/gmail/v1/users/me/messages/{MESSAGE_ID}/modify \
-d {addLabelIds: [LABEL_ID]}
移除标签
curl -s -X POST \
-H Authorization: Bearer $GMAILACCESSTOKEN \
-H Content-Type: application/json \
https://gmail.googleapis.com/gmail/v1/users/me/messages/{MESSAGE_ID}/modify \
-d {removeLabelIds: [LABEL_ID]}
标记为已读
curl -s -X POST \
-H Authorization: Bearer $GMAILACCESSTOKEN \
-H Content-Type: application/json \
https://gmail.googleapis