
Email Skill
- 8 installs
- 33 repo stars
- Updated April 26, 2026
- bighardperson/computer-science-skills-collection
Email-skill is a skill that sends, reads, searches, and organizes emails across multiple SMTP providers with attachment support.
About
This skill provides email management and automation across multiple providers. It can send emails with attachments, supports HTML and plain-text bodies, CC and BCC recipients, and secure TLS or SSL connections. A developer configures SMTP credentials via a config file or environment variables and sends mail through a Python script or API for providers like Gmail, Outlook, Yahoo, and QQ Mail.
- Send, read, search, and organize emails across providers
- Supports Gmail, Outlook, Yahoo, QQ, and custom SMTP
- Sends attachments with HTML/plain text, CC/BCC, TLS/SSL
Email Skill by the numbers
- 8 all-time installs (skills.sh)
- Ranked #1,522 of 2,719 Automation & Workflows skills by installs in the Skillselion catalog
- Data as of Jul 30, 2026 (Skillselion catalog sync)
email-skill capabilities & compatibility
- Capabilities
- email send · email automation · attachment handling
- Works with
- gmail · outlook
- Use cases
- Platforms
- macOS · Linux · Windows
What email-skill says it does
Email management and automation. Send, read, search, and organize emails across multiple providers.
Support for multiple email providers (Gmail, Outlook, Yahoo, etc.)
Send Email with Attachment
npx skills add https://github.com/bighardperson/computer-science-skills-collection --skill email-skillAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 8 |
|---|---|
| repo stars | ★ 33 |
| Last updated | April 26, 2026 |
| Repository | bighardperson/computer-science-skills-collection ↗ |
What it does
Send and automate emails with attachments across SMTP providers like Gmail and Outlook.
Who is it for?
Automating outbound email with attachments through Gmail, Outlook, or other SMTP providers.
When should I use this skill?
You want an agent to send email, including attachments, via SMTP.
What you get
- sent email with optional attachments
By the numbers
- 5+ supported providers listed (Gmail, Outlook, Yahoo, QQ, custom)
Files
Email 📧
Email management and automation with attachment support.
Features
- Send emails with attachments
- Support for multiple email providers (Gmail, Outlook, Yahoo, etc.)
- HTML and plain text email support
- CC and BCC recipients
- Test email functionality
- Secure TLS/SSL connections
Setup Instructions
1. Configure Email Credentials
Create a configuration file email_config.json in your workspace:
{
"smtp_server": "smtp.gmail.com",
"smtp_port": 587,
"username": "your-email@gmail.com",
"password": "your-app-password",
"sender_name": "OpenClaw Assistant",
"use_tls": true,
"use_ssl": false
}2. For Gmail Users (Recommended)
1. Enable 2-factor authentication on your Google account 2. Generate an App Password:
- Go to https://myaccount.google.com/security
- Under "Signing in to Google," select "App passwords"
- Generate a new app password for "Mail"
- Use this 16-character password in your config
3. Alternative: Environment Variables
Set these environment variables instead of using a config file:
# Windows
set SMTP_SERVER=smtp.gmail.com
set SMTP_PORT=587
set EMAIL_USERNAME=your-email@gmail.com
set EMAIL_PASSWORD=your-app-password
set EMAIL_SENDER_NAME="OpenClaw Assistant"
# macOS/Linux
export SMTP_SERVER=smtp.gmail.com
export SMTP_PORT=587
export EMAIL_USERNAME=your-email@gmail.com
export EMAIL_PASSWORD=your-app-password
export EMAIL_SENDER_NAME="OpenClaw Assistant"Usage Examples
Send a Simple Email
python email_sender.py --to "recipient@example.com" --subject "Hello" --body "This is a test email"Send Email with Attachment
python email_sender.py --to "recipient@example.com" --subject "Report" --body "Please find attached" --attachment "report.pdf" --attachment "data.xlsx"Send Test Email
python email_sender.py --to "your-email@gmail.com" --testUsing with OpenClaw Commands
"Send email to recipient@example.com with subject Meeting Notes and body Here are the notes from today's meeting"
"Send test email to verify configuration"
"Email the report.pdf file to team@company.com"Supported Email Providers
| Provider | SMTP Server | Port | TLS |
|---|---|---|---|
| Gmail | smtp.gmail.com | 587 | Yes |
| Outlook/Office365 | smtp.office365.com | 587 | Yes |
| Yahoo | smtp.mail.yahoo.com | 587 | Yes |
| QQ Mail | smtp.qq.com | 587 | Yes |
| Custom SMTP | your.smtp.server.com | 587/465 | As configured |
Python API Usage
from email_sender import EmailSender
# Initialize with config file
sender = EmailSender("email_config.json")
# Send email with attachment
result = sender.send_email(
to_email="recipient@example.com",
subject="Important Document",
body="Please review the attached document.",
attachments=["document.pdf", "data.csv"]
)
if result["success"]:
print(f"Email sent with {result['attachments']} attachments")
else:
print(f"Error: {result['error']}")Troubleshooting
Common Issues:
1. Authentication Failed
- Verify your username and password
- For Gmail: Use app password instead of regular password
- Check if 2FA is enabled
2. Connection Refused
- Verify SMTP server and port
- Check firewall settings
- Try different port (465 for SSL)
3. Attachment Too Large
- Most providers limit attachments to 25MB
- Consider compressing files or using cloud storage links
Security Notes
- Never commit email credentials to version control
- Use environment variables for production deployments
- Regularly rotate app passwords
- Consider using dedicated email accounts for automation
{
"email_config": {
"smtp_server": "smtp.gmail.com",
"smtp_port": 587,
"username": "your-email@gmail.com",
"password": "your-app-password",
"sender_name": "OpenClaw Assistant",
"use_tls": true,
"use_ssl": false
},
"common_services": {
"gmail": {
"smtp_server": "smtp.gmail.com",
"smtp_port": 587,
"use_tls": true
},
"outlook": {
"smtp_server": "smtp.office365.com",
"smtp_port": 587,
"use_tls": true
},
"yahoo": {
"smtp_server": "smtp.mail.yahoo.com",
"smtp_port": 587,
"use_tls": true
},
"qq": {
"smtp_server": "smtp.qq.com",
"smtp_port": 587,
"use_tls": true
}
}
}#!/usr/bin/env python3
"""
Email Sender Skill for OpenClaw
Supports sending emails with attachments via SMTP
"""
import os
import smtplib
import ssl
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
from typing import Optional, List
import json
import sys
class EmailSender:
def __init__(self, config_path: str = None):
"""Initialize email sender with configuration"""
self.config = self.load_config(config_path)
def load_config(self, config_path: str = None) -> dict:
"""Load email configuration from file or environment variables"""
config = {}
# Try to load from config file
if config_path and os.path.exists(config_path):
try:
with open(config_path, 'r') as f:
config = json.load(f)
except Exception as e:
print(f"Error loading config file: {e}")
# Fall back to environment variables
env_config = {
'smtp_server': os.getenv('SMTP_SERVER'),
'smtp_port': int(os.getenv('SMTP_PORT', '587')),
'username': os.getenv('EMAIL_USERNAME'),
'password': os.getenv('EMAIL_PASSWORD'),
'sender_name': os.getenv('EMAIL_SENDER_NAME', 'OpenClaw Assistant'),
'use_tls': os.getenv('EMAIL_USE_TLS', 'true').lower() == 'true',
'use_ssl': os.getenv('EMAIL_USE_SSL', 'false').lower() == 'true'
}
# Merge configs (environment variables override file config)
for key, value in env_config.items():
if value is not None:
config[key] = value
return config
def validate_config(self) -> bool:
"""Validate that required configuration is present"""
required = ['smtp_server', 'smtp_port', 'username', 'password']
for key in required:
if key not in self.config or not self.config[key]:
print(f"Missing required configuration: {key}")
return False
return True
def send_email(
self,
to_email: str,
subject: str,
body: str,
attachments: List[str] = None,
cc: List[str] = None,
bcc: List[str] = None,
html_body: str = None
) -> dict:
"""
Send an email with optional attachments
Args:
to_email: Recipient email address(es) - can be string or list
subject: Email subject
body: Plain text email body
attachments: List of file paths to attach
cc: List of CC email addresses
bcc: List of BCC email addresses
html_body: HTML version of email body (optional)
Returns:
Dictionary with success status and message
"""
if not self.validate_config():
return {"success": False, "error": "Invalid email configuration"}
try:
# Create message
msg = MIMEMultipart('alternative')
msg['From'] = f"{self.config.get('sender_name', 'OpenClaw')} <{self.config['username']}>"
msg['To'] = to_email if isinstance(to_email, str) else ', '.join(to_email)
msg['Subject'] = subject
if cc:
msg['Cc'] = ', '.join(cc)
# Add recipients for BCC
all_recipients = []
if isinstance(to_email, str):
all_recipients.append(to_email)
else:
all_recipients.extend(to_email)
if cc:
all_recipients.extend(cc)
if bcc:
all_recipients.extend(bcc)
# Add text body
msg.attach(MIMEText(body, 'plain'))
# Add HTML body if provided
if html_body:
msg.attach(MIMEText(html_body, 'html'))
# Add attachments
if attachments:
for attachment_path in attachments:
if os.path.exists(attachment_path):
self._add_attachment(msg, attachment_path)
else:
print(f"Warning: Attachment not found: {attachment_path}")
# Connect to SMTP server
context = ssl.create_default_context()
if self.config.get('use_ssl', False):
# SSL connection
server = smtplib.SMTP_SSL(
self.config['smtp_server'],
self.config['smtp_port'],
context=context
)
else:
# TLS connection (default)
server = smtplib.SMTP(
self.config['smtp_server'],
self.config['smtp_port']
)
if self.config.get('use_tls', True):
server.starttls(context=context)
# Login and send
server.login(self.config['username'], self.config['password'])
server.send_message(msg, from_addr=self.config['username'], to_addrs=all_recipients)
server.quit()
return {
"success": True,
"message": f"Email sent successfully to {to_email}",
"subject": subject,
"attachments": len(attachments) if attachments else 0
}
except Exception as e:
return {
"success": False,
"error": str(e),
"subject": subject
}
def _add_attachment(self, msg: MIMEMultipart, filepath: str):
"""Add a file attachment to the email"""
filename = os.path.basename(filepath)
with open(filepath, 'rb') as f:
part = MIMEBase('application', 'octet-stream')
part.set_payload(f.read())
encoders.encode_base64(part)
part.add_header(
'Content-Disposition',
f'attachment; filename="{filename}"'
)
msg.attach(part)
def send_test_email(self, to_email: str = None) -> dict:
"""Send a test email to verify configuration"""
test_to = to_email or self.config['username']
subject = "Test Email from OpenClaw"
body = """This is a test email sent from your OpenClaw assistant.
If you're receiving this, your email configuration is working correctly!
Best regards,
OpenClaw Assistant"""
return self.send_email(test_to, subject, body)
def main():
"""Command-line interface for email sending"""
import argparse
parser = argparse.ArgumentParser(description='Send email with attachments')
parser.add_argument('--to', required=True, help='Recipient email address')
parser.add_argument('--subject', required=True, help='Email subject')
parser.add_argument('--body', required=True, help='Email body text')
parser.add_argument('--attachment', action='append', help='Attachment file path (can be used multiple times)')
parser.add_argument('--config', help='Path to configuration file')
parser.add_argument('--test', action='store_true', help='Send test email')
args = parser.parse_args()
sender = EmailSender(args.config)
if args.test:
result = sender.send_test_email(args.to)
else:
result = sender.send_email(
to_email=args.to,
subject=args.subject,
body=args.body,
attachments=args.attachment
)
print(json.dumps(result, indent=2))
sys.exit(0 if result['success'] else 1)
if __name__ == '__main__':
main()OpenClaw Email Integration
This document explains how to use the email skill from within OpenClaw sessions.
Prerequisites
1. Email configuration file created (e.g., email_config.json in your workspace) 2. Python installed and accessible 3. Email skill enabled in OpenClaw config
Using Email in OpenClaw Sessions
Method 1: Direct Python Execution
You can call the email sender directly from OpenClaw:
# In an OpenClaw session
import sys
import os
# Add email skill to path (adjust path as needed)
email_skill_path = os.path.join(os.getcwd(), 'skills', 'email')
if email_skill_path not in sys.path:
sys.path.append(email_skill_path)
from email_sender import EmailSender
# Initialize with config file (adjust path as needed)
config_path = 'email_config.json' # Or full path to your config
sender = EmailSender(config_path)
result = sender.send_email(
to_email='recipient@example.com',
subject='Test from OpenClaw',
body='This email was sent from OpenClaw!',
attachments=['report.pdf'] # Relative or absolute paths
)
if result['success']:
print(f"Email sent successfully!")
else:
print(f"Failed to send email: {result['error']}")Method 2: Using exec Tool
You can use OpenClaw's exec tool to run the email sender:
# Send a simple email (from the email skill directory)
cd /path/to/openclaw-email-skill
python email_sender.py --to "recipient@example.com" --subject "Hello" --body "Message from OpenClaw"
# Send email with attachment (using absolute or relative paths)
python email_sender.py --to "recipient@example.com" --subject "Report" --body "Please review" --attachment "report.pdf"Method 3: Create Custom Commands
Add these to your AGENTS.md or create a custom skill:
## Email Commands
- `send email to <address> with subject <subject> and body <body>` - Send basic email
- `email <file> to <address>` - Send file as attachment
- `test email configuration` - Send test emailExample: Complete Email Function
Here's a complete function you can add to your OpenClaw setup:
# Add this to a custom skill or your workspace
import os
import sys
def send_email_from_openclaw(to_email, subject, body, attachments=None, config_path=None):
"""
Send email from within OpenClaw
Args:
to_email: Recipient email address
subject: Email subject
body: Email body text
attachments: List of file paths (optional)
config_path: Path to email config file (optional)
"""
# Determine config path
if config_path is None:
config_path = os.path.join(os.getcwd(), 'email_config.json')
# Add email skill to path
email_skill_dir = os.path.dirname(os.path.abspath(__file__))
if email_skill_dir not in sys.path:
sys.path.append(email_skill_dir)
try:
from email_sender import EmailSender
sender = EmailSender(config_path)
result = sender.send_email(
to_email=to_email,
subject=subject,
body=body,
attachments=attachments or []
)
return result
except Exception as e:
return {
'success': False,
'error': str(e)
}
# Example usage in OpenClaw:
# result = send_email_from_openclaw(
# to_email='recipient@example.com',
# subject='Daily Report',
# body='Here is your daily report.',
# attachments=['daily_report.pdf']
# )Common Use Cases
1. Sending Reports
# After generating a report
report_path = 'generated_report.pdf'
send_email_from_openclaw(
to_email='team@company.com',
subject='Daily Analytics Report',
body='Please find attached the daily analytics report.',
attachments=[report_path]
)2. Notification Emails
# Send notification when a task completes
send_email_from_openclaw(
to_email='user@example.com',
subject='Task Completed',
body='Your scheduled task has completed successfully.'
)3. Email with Multiple Attachments
# Send multiple files
attachments = [
'data.csv',
'chart.png',
'summary.docx'
]
send_email_from_openclaw(
to_email='manager@company.com',
subject='Weekly Data Package',
body='Attached are the weekly data files.',
attachments=attachments
)Error Handling
def safe_send_email(to_email, subject, body, attachments=None, config_path=None):
"""Send email with error handling"""
try:
result = send_email_from_openclaw(to_email, subject, body, attachments, config_path)
if result['success']:
return f"✅ Email sent to {to_email} with {len(attachments or [])} attachments"
else:
return f"❌ Failed to send email: {result['error']}"
except Exception as e:
return f"❌ Error: {str(e)}"Testing
Always test your configuration first:
# Test function
def test_email_config(config_path=None):
"""Test email configuration"""
result = send_email_from_openclaw(
to_email='your-email@gmail.com', # Send to yourself
subject='OpenClaw Email Test',
body='If you receive this, email configuration is working!',
config_path=config_path
)
if result['success']:
print("Email test successful!")
else:
print(f"Email test failed: {result['error']}")Security Best Practices
1. Never hardcode credentials - Always use config file or environment variables 2. Use app passwords for services like Gmail (not your main password) 3. Regularly rotate passwords - Update your email_config.json periodically 4. Limit attachment sizes - Most providers have 25MB limits 5. Validate recipients - Always double-check email addresses before sending
OpenClaw Email Skill 📧
A comprehensive email management and automation skill for OpenClaw, enabling seamless email sending, configuration, and integration across multiple email providers.
Features
- Multi-provider Support: Gmail, Outlook/Office365, Yahoo, QQ Mail, and custom SMTP servers
- Attachment Support: Send emails with multiple file attachments
- HTML & Plain Text: Support for both HTML and plain text email formats
- CC/BCC Recipients: Full recipient management capabilities
- Secure Connections: TLS/SSL encryption for secure email transmission
- OpenClaw Integration: Native integration with OpenClaw's skill system
- Test Functionality: Built-in test email verification
Quick Start
Installation
1. Clone the repository:
git clone https://github.com/awspace/openclaw-email-skill.git
cd openclaw-email-skill2. Install dependencies:
pip install -r requirements.txtConfiguration
Create a configuration file email_config.json:
{
"smtp_server": "smtp.gmail.com",
"smtp_port": 587,
"username": "your-email@gmail.com",
"password": "your-app-password",
"sender_name": "OpenClaw Assistant",
"use_tls": true,
"use_ssl": false
}For Gmail Users
1. Enable 2-factor authentication on your Google account 2. Generate an App Password:
- Go to https://myaccount.google.com/security
- Under "Signing in to Google," select "App passwords"
- Generate a new app password for "Mail"
- Use this 16-character password in your config
Usage Examples
Command Line
# Send a simple email
python email_sender.py --to "recipient@example.com" --subject "Hello" --body "This is a test email"
# Send email with attachment
python email_sender.py --to "recipient@example.com" --subject "Report" --body "Please find attached" --attachment "report.pdf"
# Send test email
python email_sender.py --to "your-email@gmail.com" --testOpenClaw Integration
When installed as an OpenClaw skill, you can use natural language commands:
"Send email to recipient@example.com with subject Meeting Notes and body Here are the notes from today's meeting"
"Send test email to verify configuration"
"Email the report.pdf file to team@company.com"Python API
from email_sender import EmailSender
# Initialize with config file
sender = EmailSender("email_config.json")
# Send email with attachment
result = sender.send_email(
to_email="recipient@example.com",
subject="Important Document",
body="Please review the attached document.",
attachments=["document.pdf", "data.csv"]
)
if result["success"]:
print(f"Email sent with {result['attachments']} attachments")
else:
print(f"Error: {result['error']}")Supported Email Providers
| Provider | SMTP Server | Port | TLS | Notes |
|---|---|---|---|---|
| Gmail | smtp.gmail.com | 587 | Yes | Requires App Password with 2FA |
| Outlook/Office365 | smtp.office365.com | 587 | Yes | - |
| Yahoo | smtp.mail.yahoo.com | 587 | Yes | - |
| QQ Mail | smtp.qq.com | 587 | Yes | - |
| Custom SMTP | your.smtp.server.com | 587/465 | As configured | - |
File Structure
openclaw-email-skill/
├── SKILL.md # Main skill documentation
├── email_sender.py # Core email functionality
├── config_template.json # Configuration template
├── test_email.py # Test script
├── openclaw_integration.md # OpenClaw integration guide
├── _meta.json # Skill metadata
├── requirements.txt # Python dependencies
└── README.md # This fileRequirements
- Python 3.7+
- OpenClaw (for integration)
- Required Python packages:
smtplib(standard library)email(standard library)
Troubleshooting
Common Issues
1. Authentication Failed
- Verify your username and password
- For Gmail: Use app password instead of regular password
- Check if 2FA is enabled
2. Connection Refused
- Verify SMTP server and port
- Check firewall settings
- Try different port (465 for SSL)
3. Attachment Too Large
- Most providers limit attachments to 25MB
- Consider compressing files or using cloud storage links
Error Messages
SMTPAuthenticationError: Invalid credentialsSMTPConnectError: Cannot connect to SMTP serverSMTPDataError: Server rejected messageTimeoutError: Connection timeout
Security Notes
- Never commit email credentials to version control
- Use environment variables for production deployments
- Regularly rotate app passwords
- Consider using dedicated email accounts for automation
- Store credentials in secure locations (not in code)
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
1. Fork the repository 2. Create your feature branch (git checkout -b feature/amazing-feature) 3. Commit your changes (git commit -m 'Add some amazing feature') 4. Push to the branch (git push origin feature/amazing-feature) 5. Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Built for OpenClaw - The open-source AI assistant platform
- Inspired by the need for seamless email automation in AI workflows
- Thanks to all contributors and users
Support
For issues, questions, or feature requests:
- Open an issue on GitHub
- Check the OpenClaw documentation
- Join the OpenClaw community
---
Happy Emailing! 📧✨
# OpenClaw Email Skill Requirements
# Note: smtplib and email are part of Python's standard library
# No additional packages required for basic functionality
# Optional: For enhanced email features (HTML emails, etc.)
# beautifulsoup4>=4.9.0
# lxml>=4.6.0