Complete Zoho Mail integration with OAuth2, REST API (5-10x faster), Clawdbot /email commands, HTML emails, attachments, and batch operations. Security-harde...
Install
Documentation
Zoho Email Integration
v2.2.6 - Complete Zoho Mail integration with OAuth2 authentication, REST API backend (5-10x faster than IMAP/SMTP), and Clawdbot extension with /email commands for Telegram/Discord. Security-hardened against path traversal and command injection. Supports HTML emails, attachments, batch operations, and advanced automation workflows.Choose your authentication: OAuth2 (recommended, secure) or app password (simple setup).
🔄 Update to Latest Version
clawhub install zoho-email-integration --force
Or update all skills:
clawhub update
🔒 Security Notice (v2.2.5+)
CRITICAL FIX: Removed vulnerable JavaScript command handler. If you deployedemail-command.js from the examples folder, update immediately:
Re-download the secure handler
clawhub install zoho-email-integration --force
cp ~/.openclaw/skills/zoho-email-integration/examples/clawdbot-extension/email-command.js /your/deployment/path/
The vulnerable version used execSync with shell interpolation. The new version uses spawn with argument arrays to prevent command injection.
✨ Features
🔐 Authentication & Performance
- -OAuth2 authentication - Secure token-based auth with automatic refresh
- -REST API backend - 5-10x faster operations than IMAP/SMTP
- -Graceful fallback - Automatically falls back to IMAP if REST API unavailable
- -App password support - Simple alternative to OAuth2
📧 Email Operations
- -📥 Read emails - Fetch from any folder (Inbox, Sent, Drafts, etc.)
- -🔍 Smart search - Search by subject, sender, keywords with REST API speed
- -📊 Monitor inbox - Real-time unread count for notifications
- -📤 Send emails - Plain text or HTML with CC/BCC support
- -🎨 HTML emails - Rich formatting with professional templates included
- -📎 Attachments - Send and download file attachments
⚡ Batch & Bulk Operations
- -Batch operations - Mark, delete, or move multiple emails efficiently
- -Bulk actions - Search and act on hundreds of emails at once
- -Dry-run mode - Preview actions before executing for safety
🔒 Security
- -No hardcoded credentials - OAuth2 tokens or environment variables only
- -Automatic token refresh - Seamless token renewal
- -Encrypted connections - SSL/TLS for all operations
📦 Installation
clawdhub install zoho-email
Requirements:
- -Python 3.x
- -
requestslibrary (install:pip3 install requests) - -Zoho Mail account
⚙️ Setup
1. Get an App-Specific Password
Important: Don't use your main Zoho password!1. Log in to Zoho Mail
2. Go to Settings → Security → App Passwords
3. Generate a new app password for "Clawdbot" or "IMAP/SMTP Access"
4. Copy the password (you'll need it next)
2. Configure Credentials
Option A: Environment VariablesExport your Zoho credentials:
export ZOHO_EMAIL="your-email@domain.com"
export ZOHO_PASSWORD="your-app-specific-password"
Option B: Credentials File
Create ~/.clawdbot/zoho-credentials.sh:
#!/bin/bash
export ZOHO_EMAIL="your-email@domain.com"
export ZOHO_PASSWORD="your-app-specific-password"
Make it executable and secure:
chmod 600 ~/.clawdbot/zoho-credentials.sh
Then source it before running:
source ~/.clawdbot/zoho-credentials.sh
3. Test Connection
python3 scripts/zoho-email.py unread
Expected output:
{"unread_count": 5}
🚀 Usage
All commands require credentials set via environment variables.
Quick commands (common tasks)
Diagnose setup (recommended first step)
python3 scripts/zoho-email.py doctor
Unread count (great for briefings)
python3 scripts/zoho-email.py unread
Search inbox
python3 scripts/zoho-email.py search "invoice"
Get a specific email (folder + id)
python3 scripts/zoho-email.py get INBOX <id>
Send a simple email
python3 scripts/zoho-email.py send recipient@example.com "Subject" "Body text"
Empty Spam (safe by default: DRY RUN)
python3 scripts/zoho-email.py empty-spam
Execute for real
python3 scripts/zoho-email.py empty-spam --execute
Empty Trash (safe by default: DRY RUN)
python3 scripts/zoho-email.py empty-trash
Execute for real
python3 scripts/zoho-email.py empty-trash --execute
Send HTML Emails
Send rich, formatted HTML emails with multipart/alternative support (both HTML and plain text versions):
CLI Command:Send HTML from a file
python3 scripts/zoho-email.py send-html recipient@example.com "Newsletter" examples/templates/newsletter.html
Send HTML from inline text
python3 scripts/zoho-email.py send-html recipient@example.com "Welcome" "<h1>Hello!</h1><p>Welcome to our service.</p>"
Preview HTML email before sending
python3 scripts/zoho-email.py preview-html examples/templates/newsletter.html
Python API:
from scripts.zoho_email import ZohoEmail
zoho = ZohoEmail()
Method 1: Send HTML with auto-generated plain text fallback
zoho.send_html_email(
to="recipient@example.com",
subject="Newsletter",
html_body="<h1>Hello!</h1><p>Welcome!</p>"
)
Method 2: Send HTML with custom plain text version
zoho.send_email(
to="recipient@example.com",
subject="Newsletter",
body="Plain text version of your email",
html_body="<h1>Hello!</h1><p>HTML version of your email</p>"
)
Load HTML from template file
with open('examples/templates/newsletter.html', 'r') as f:
html_content = f.read()
zoho.send_html_email(
to="recipient@example.com",
subject="Monthly Newsletter",
html_body=html_content
)
Features:
- -✅ Multipart/alternative emails (HTML + plain text)
- -✅ Auto-generated plain text fallback
- -✅ Load HTML from files or inline strings
- -✅ Preview mode to test before sending
- -✅ Full CSS styling support
- -✅ Works with all email clients
Pre-built templates available in examples/templates/:
- -
newsletter.html- Professional newsletter layout - -
announcement.html- Important announcements with banners - -
welcome.html- Onboarding welcome email - -
simple.html- Basic HTML template for quick customization
Check Unread Count
python3 scripts/zoho-email.py unread
Perfect for morning briefings or notification systems.
Search Inbox
python3 scripts/zoho-email.py search "invoice"
Returns last 10 matching emails with subject, sender, date, and body preview.
Search Sent Emails
python3 scripts/zoho-email.py search-sent "client name"
Returns last 5 matching sent emails.
Get Specific Email
python3 scripts/zoho-email.py get Inbox 4590
python3 scripts/zoho-email.py get Sent 1234
Returns full email content including complete body.
Send Email
python3 scripts/zoho-email.py send "client@example.com" "Subject" "Email body here"
Send Email with Attachments
python3 scripts/zoho-email.py send "client@example.com" "Invoice" "Please find the invoice attached" --attach invoice.pdf --attach receipt.jpg
Supports multiple attachments with --attach flag.
List Email Attachments
python3 scripts/zoho-email.py list-attachments Inbox 4590
Returns JSON with attachment details:
[
{
"index": 0,
"filename": "invoice.pdf",
"content_type": "application/pdf",
"size": 52341
},
{
"index": 1,
"filename": "receipt.jpg",
"content_type": "image/jpeg",
"size": 128973
}
]
Download Attachment
Download first attachment (index 0) with original filename
python3 scripts/zoho-email.py download-attachment Inbox 4590 0
Download second attachment (index 1) with custom filename
python3 scripts/zoho-email.py download-attachment Inbox 4590 1 my-receipt.jpg
Returns JSON with download details:
{
"filename": "invoice.pdf",
"output_path": "invoice.pdf",
"size": 52341,
"content_type": "application/pdf"
}
🤖 Clawdbot Integration Examples
Morning Briefing
Check unread emails and report:
UNREAD=$(python3 scripts/zoho-email.py unread | jq -r '.unread_count')
echo "📧 You have $UNREAD unread emails"
Email Monitoring
Watch for VIP emails:
RESULTS=$(python3 scripts/zoho-email.py search "Important Client")
COUNT=$(echo "$RESULTS" | jq '. | length')
if [ $COUNT -gt 0 ]; then
echo "⚠️ New email from Important Client!"
fi
Automated Responses
Search and reply workflow:
Find latest invoice inquiry
EMAIL=$(python3 scripts/zoho-email.py search "invoice" | jq -r '.[0]')
FROM=$(echo "$EMAIL" | jq -r '.from')
Send reply
python3 scripts/zoho-email.py send "$FROM" "Re: Invoice" "Thanks for your inquiry..."
Attachment Workflows
Download invoice attachments automatically:
Search for invoice emails
EMAILS=$(python3 scripts/zoho-email.py search "invoice")
Get latest email ID
EMAIL_ID=$(echo "$EMAILS" | jq -r '.[0].id')
List attachments
ATTACHMENTS=$(python3 scripts/zoho-email.py list-attachments Inbox "$EMAIL_ID")
Download all PDF attachments
echo "$ATTACHMENTS" | jq -r '.[] | select(.content_type == "application/pdf") | .index' | while read INDEX; do
python3 scripts/zoho-email.py download-attachment Inbox "$EMAIL_ID" "$INDEX" "invoice_${INDEX}.pdf"
echo "Downloaded invoice_${INDEX}.pdf"
done
Send report with attachments:
Generate report
python3 generate_report.py > report.txt
Send with attachment
python3 scripts/zoho-email.py send "manager@example.com" "Weekly Report" "Please see attached report" --attach report.txt --attach chart.png
📚 Python API
Import the module for programmatic use:
from scripts.zoho_email import ZohoEmail
zoho = ZohoEmail()
Search emails
results = zoho.search_emails(folder="INBOX", query='SUBJECT "invoice"', limit=10)
Get specific email
email = zoho.get_email(folder="Sent", email_id="4590")
Send plain text email
zoho.send_email(
to="client@example.com",
subject="Hello",
body="Message text",
cc="manager@example.com" # optional
)
Send HTML email (auto-generated plain text fallback)
zoho.send_html_email(
to="client@example.com",
subject="Newsletter",
html_body="<h1>Welcome!</h1><p>Rich HTML content here</p>",
text_body="Welcome! Plain text version here" # optional, auto-generated if not provided
)
Send multipart email (HTML + custom plain text)
zoho.send_email(
to="client@example.com",
subject="Update",
body="Plain text version",
html_body="<h1>HTML version</h1>",
cc="manager@example.com"
)
Send email with attachments
zoho.send_email_with_attachment(
to="client@example.com",
subject="Invoice",
body="Please find the invoice attached",
attachments=["invoice.pdf", "receipt.jpg"],
cc="manager@example.com" # optional
)
List attachments
attachments = zoho.get_attachments(folder="INBOX", email_id="4590")
for att in attachments:
print(f"{att['index']}: {att['filename']} ({att['size']} bytes)")
Download attachment
result = zoho.download_attachment(
folder="INBOX",
email_id="4590",
attachment_index=0,
output_path="downloaded_file.pdf" # optional, uses original filename if not provided
)
Check unread count
count = zoho.get_unread_count()
📖 HTML Email Examples
Check out the complete example in examples/send-html-newsletter.py:
Run the HTML email examples
python3 examples/send-html-newsletter.py
This demonstrates:
- -Sending simple inline HTML
- -Loading and sending HTML templates
- -Custom plain text fallbacks
- -Professional email layouts
#!/usr/bin/env python3
from scripts.zoho_email import ZohoEmail
zoho = ZohoEmail()
Load a template
with open('examples/templates/welcome.html', 'r') as f:
html = f.read()
Send to recipient
zoho.send_html_email(
to="newuser@example.com",
subject="🎉 Welcome to Our Platform!",
html_body=html
)
📁 Folder Reference
Common Zoho Mail folders:
- -
INBOX- Main inbox - -
Sent- Sent emails - -
Drafts- Draft emails - -
Spam- Spam folder - -
Trash- Deleted emails - -Custom folders (e.g.,
INBOX/ClientName)
🔧 Advanced Configuration
Override default IMAP/SMTP servers (if using Zoho Mail self-hosted):
export ZOHO_IMAP="imap.yourdomain.com"
export ZOHO_SMTP="smtp.yourdomain.com"
export ZOHO_IMAP_PORT="993"
export ZOHO_SMTP_PORT="465"
❓ Troubleshooting
Authentication Failed
- -Ensure IMAP is enabled in Zoho Mail settings
- -Use an app-specific password, not your main password
- -Verify credentials are properly exported
Connection Timeout
- -Check firewall allows port 993 (IMAP) and 465 (SMTP)
- -Verify Zoho Mail server status
- -Try with a different network (corporate firewalls may block IMAP)
Search Returns No Results
- -IMAP search is case-insensitive
- -Try broader keywords
- -Verify folder name is correct (case-sensitive)
"ZOHO_EMAIL and ZOHO_PASSWORD must be set"
You forgot to export credentials! Run:
export ZOHO_EMAIL="your-email@domain.com"
export ZOHO_PASSWORD="your-app-password"
🛣️ Roadmap
✅ Completed (v2.0.0)
- -[x] OAuth2 authentication - Secure token-based auth with auto-refresh
- -[x] Zoho Mail REST API - 5-10x faster than IMAP/SMTP
- -[x] Attachment support - Download and send attachments
- -[x] HTML email composition - Rich formatting with templates
- -[x] Batch operations - Mark, delete, move multiple emails
- -[x] Bulk actions - Search and act on many emails at once
🔮 Future Enhancements
- -[ ] Email threading/conversations - Group related emails together
- -[ ] Label management - Create and manage Zoho Mail labels
- -[ ] Draft email management - Create, edit, and send drafts
- -[ ] Scheduled sends - Schedule emails to send later
- -[ ] Email templates - Reusable email templates with variables
- -[ ] Webhooks - Real-time notifications for new emails
- -[ ] Advanced search - Filter by size, has-attachment, date ranges
- -[ ] Zoho Calendar integration - Create events from emails
- -[ ] Zoho CRM integration - Sync contacts and activities
📝 Notes
- -Search limit: Returns last 5-10 emails by default (configurable in code)
- -Body truncation: Search results show first 500 characters
- -Encoding: Handles UTF-8 and various email encodings
- -Security: Credentials never leave your system except to Zoho servers
🤝 Contributing
Found a bug or want to contribute? Submit issues or PRs on GitHub!
📄 License
MIT License - free to use, modify, and distribute.
---
Created: 2026-01-29 Status: Production-ready ✅ Requires: Python 3.x. For REST API mode:pip install -r requirements.txt (includes requests).
🔄 Batch Operations
New in v1.1! Process multiple emails efficiently with batch commands.
Mark Multiple Emails as Read
python3 scripts/zoho-email.py mark-read INBOX 1001 1002 1003
Mark several emails as read in one command. Perfect for clearing notifications.
Mark Multiple Emails as Unread
python3 scripts/zoho-email.py mark-unread INBOX 1004 1005
Flag important emails to revisit later.
Delete Multiple Emails
python3 scripts/zoho-email.py delete INBOX 2001 2002 2003
Safety: Asks for confirmation before deleting. Emails are moved to Trash (not permanently deleted).
Move Emails Between Folders
python3 scripts/zoho-email.py move INBOX "Archive/2024" 3001 3002 3003
Organize emails by moving them to custom folders.
Bulk Actions with Search
Perform actions on all emails matching a search query:
Dry run first - see what would be affected
python3 scripts/zoho-email.py bulk-action \
--folder INBOX \
--search 'SUBJECT "newsletter"' \
--action mark-read \
--dry-run
Execute the action
python3 scripts/zoho-email.py bulk-action \
--folder INBOX \
--search 'SUBJECT "newsletter"' \
--action mark-read
Available actions:
- -
mark-read- Mark all matching emails as read - -
mark-unread- Mark all matching emails as unread - -
delete- Move all matching emails to Trash
By subject
--search 'SUBJECT "invoice"'
By sender
--search 'FROM "sender@example.com"'
Unread emails
--search 'UNSEEN'
Combine criteria (AND)
--search '(SUBJECT "urgent" FROM "boss@company.com")'
Date range
--search 'SINCE 01-Jan-2024'
Batch Operations in Python
from scripts.zoho_email import ZohoEmail
zoho = ZohoEmail()
Mark multiple emails as read
result = zoho.mark_as_read(['1001', '1002', '1003'], folder="INBOX")
print(f"Success: {len(result['success'])}, Failed: {len(result['failed'])}")
Delete multiple emails
result = zoho.delete_emails(['2001', '2002'], folder="INBOX")
Move emails to another folder
result = zoho.move_emails(
email_ids=['3001', '3002'],
target_folder="Archive/2024",
source_folder="INBOX"
)
Bulk action with search
result = zoho.bulk_action(
query='SUBJECT "newsletter"',
action='mark-read',
folder="INBOX",
dry_run=True # Preview first
)
print(f"Found {result['total_found']} emails")
print(f"Will process {result['to_process']} emails")
Execute for real
result = zoho.bulk_action(
query='SUBJECT "newsletter"',
action='mark-read',
folder="INBOX",
dry_run=False
)
Batch Cleanup Example
Clean up old newsletters automatically:
1. Preview what will be deleted
python3 scripts/zoho-email.py bulk-action \
--folder INBOX \
--search 'SUBJECT "newsletter"' \
--action delete \
--dry-run
2. Review the preview output
3. Execute if satisfied
python3 scripts/zoho-email.py bulk-action \
--folder INBOX \
--search 'SUBJECT "newsletter"' \
--action delete
See examples/batch-cleanup.py for a complete automated cleanup script.
Launch an agent with Zoho Email Integration on Termo.