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 deployed email-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!
- Log in to Zoho Mail
- Go to Settings โ Security โ App Passwords
- Generate a new app password for "Clawdbot" or "IMAP/SMTP Access"
- Copy the password (you'll need it next)
2. Configure Credentials
Option A: Environment Variables
Export your Zoho credentials:
export ZOHO_EMAIL="[email protected]"
export ZOHO_PASSWORD="your-app-specific-password"
Option B: Credentials File
Create ~/.clawdbot/zoho-credentials.sh:
#!/bin/bash
export ZOHO_EMAIL="[email protected]"
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 [email protected] "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 [email protected] "Newsletter" examples/templates/newsletter.html
# Send HTML from inline text
python3 scripts/zoho-email.py send-html [email protected] "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="[email protected]",
subject="Newsletter",
html_body="<h1>Hello!</h1><p>Welcome!</p>"
)
# Method 2: Send HTML with custom plain text version
zoho.send_email(
to="[email protected]",
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="[email protected]",
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
Templates:
Pre-built templates available in examples/templates/:
newsletter.html- Professional newsletter layoutannouncement.html- Important announcements with bannerswelcome.html- Onboarding welcome emailsimple.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 "[email protected]" "Subject" "Email body here"
Send Email with Attachments
python3 scripts/zoho-email.py send "[email protected]" "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 "[email protected]" "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="[email protected]",
subject="Hello",
body="Message text",
cc="[email protected]" # optional
)
# Send HTML email (auto-generated plain text fallback)
zoho.send_html_email(
to="[email protected]",
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="[email protected]",
subject="Update",
body="Plain text version",
html_body="<h1>HTML version</h1>",
cc="[email protected]"
)
# Send email with attachments
zoho.send_email_with_attachment(
to="[email protected]",
subject="Invoice",
body="Please find the invoice attached",
attachments=["invoice.pdf", "receipt.jpg"],
cc="[email protected]" # 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
Quick Start:
#!/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="[email protected]",
subject="๐ Welcome to Our Platform!",
html_body=html
)
๐ Folder Reference
Common Zoho Mail folders:
INBOX- Main inboxSent- Sent emailsDrafts- Draft emailsSpam- Spam folderTrash- 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="[email protected]"
export ZOHO_PASSWORD="your-app-password"
๐ฃ๏ธ Roadmap
โ Completed (v2.0.0)
- OAuth2 authentication - Secure token-based auth with auto-refresh
- Zoho Mail REST API - 5-10x faster than IMAP/SMTP
- Attachment support - Download and send attachments
- HTML email composition - Rich formatting with templates
- Batch operations - Mark, delete, move multiple emails
- 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 readmark-unread- Mark all matching emails as unreaddelete- Move all matching emails to Trash
Search query examples:
# By subject
--search 'SUBJECT "invoice"'
# By sender
--search 'FROM "[email protected]"'
# Unread emails
--search 'UNSEEN'
# Combine criteria (AND)
--search '(SUBJECT "urgent" FROM "[email protected]")'
# 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.