Agent skill
af-send-emails-gmail
Send emails from Claude/AgentFlow via Gmail API with service account authentication. Use when composing messages, adding attachments, handling replies, or automating email workflows.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/other/other/af-send-emails-gmail
SKILL.md
Email Sending Expertise
When to Use This Skill
Load this skill when you need to:
- Send an email from Claude/AgentFlow (e.g. quotation PDFs, reports, notifications)
- Compose emails with file attachments
- Send as
[email protected]
Common triggers:
- Quotation skill needs to email a PDF to a recipient
- Any workflow that produces a document for external delivery
Quick Reference
| Parameter | Value |
|---|---|
| Sender address | [email protected] |
| Sender name | Holly (AgentFlow) |
| Service account | [email protected] |
| Credentials | Doppler: gi project, prd config, GMAIL_TESTING_SERVICE_ACCOUNT |
| Required scope | https://www.googleapis.com/auth/gmail.send |
| Impersonate user | [email protected] |
| API | Gmail API v1 |
| Server docs | /srv/docs/GMAIL_TESTING.md |
Rules
- Always send as [email protected]. This is the authorised sender identity.
- Get credentials from Doppler. Never hardcode or cache service account keys.
- Clean up credential files. Delete temporary credential files after use.
- Include a clear subject line. Recipients should know what the email contains.
- Always confirm delivery to the user. Report success or failure.
Workflow: Send an Email with Attachment
When: You need to email a file (PDF, report, etc.) to a recipient.
Procedure:
Step 1: Get Credentials
sudo -u tmux-shared doppler secrets get GMAIL_TESTING_SERVICE_ACCOUNT --project gi --config prd --plain > /tmp/gmail-sa.json
Step 2: Send the Email
Use a Node.js script (googleapis is already installed, or install with npm install googleapis):
const { google } = require('googleapis');
const fs = require('fs');
const path = require('path');
async function sendEmail({ to, subject, body, attachmentPath }) {
const credentials = JSON.parse(fs.readFileSync('/tmp/gmail-sa.json', 'utf8'));
const auth = new google.auth.GoogleAuth({
credentials,
scopes: ['https://www.googleapis.com/auth/gmail.send'],
clientOptions: {
subject: '[email protected]'
}
});
const gmail = google.gmail({ version: 'v1', auth });
// Build MIME message
const attachment = fs.readFileSync(attachmentPath);
const encodedAttachment = attachment.toString('base64');
const filename = path.basename(attachmentPath);
const boundary = 'boundary_' + Date.now();
const mimeMessage = [
`From: Holly <[email protected]>`,
`To: ${to}`,
`Subject: ${subject}`,
`MIME-Version: 1.0`,
`Content-Type: multipart/mixed; boundary="${boundary}"`,
'',
`--${boundary}`,
'Content-Type: text/plain; charset="UTF-8"',
'',
body,
'',
`--${boundary}`,
`Content-Type: application/pdf; name="${filename}"`,
'Content-Transfer-Encoding: base64',
`Content-Disposition: attachment; filename="${filename}"`,
'',
encodedAttachment,
`--${boundary}--`
].join('\r\n');
const encodedMessage = Buffer.from(mimeMessage)
.toString('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
const res = await gmail.users.messages.send({
userId: 'me',
requestBody: { raw: encodedMessage }
});
return res.data;
}
Step 3: Clean Up
rm -f /tmp/gmail-sa.json
Workflow: Send a Plain Text Email
For emails without attachments, use a simpler MIME message:
const mimeMessage = [
`From: Holly <[email protected]>`,
`To: ${to}`,
`Subject: ${subject}`,
'Content-Type: text/plain; charset="UTF-8"',
'',
body
].join('\r\n');
Integration Points
Quotation skill (af-generate-quotations):
- Sends generated PDF quotations to recipients
- Subject format:
Quotation {REFERENCE} — {Project/Feature Name}
Communications (af-send-notifications):
- Zulip for team notifications, Gmail for external delivery
- Use Zulip for internal updates, email for client-facing documents
Server docs:
- Full Gmail API setup:
/srv/docs/GMAIL_TESTING.md - Google Workspace admin:
/srv/docs/GAM.md
Common Pitfalls
- Forgetting to impersonate. Must set
subject: '[email protected]'in auth options — without this, the service account can't send. - Leaving credentials on disk. Always
rm /tmp/gmail-sa.jsonafter sending. - Large attachments. Gmail API has a ~25MB limit per message. For larger files, use a download link instead.
- Missing googleapis package. Not installed globally. Create a temp directory and install:
mkdir -p /tmp/email-test && cd /tmp/email-test && npm init -y && npm install googleapis. Run scripts from that directory.
Remember:
- Send as
[email protected]via Gmail API service account - Credentials from Doppler — never hardcode
- Clean up credential files after use
- Confirm delivery success/failure to the user
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?