โ† Back to Web & Frontend Development
Web & Frontend Development by @briansmith80

zoho-email-integration

Complete Zoho Mail integration

0
Source Code

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
  • requests library (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 Variables

Export 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

Templates: 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

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="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)

  • 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 read
  • mark-unread - Mark all matching emails as unread
  • delete - Move all matching emails to Trash

Search query examples:

# 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.