# gmail > Send, read, search emails, manage labels, drafts, and attachments - Author: KIrill Enkogu - Repository: enkogu/pipeline-fullstack-app - Version: 20260125155958 - Stars: 0 - Forks: 0 - Last Updated: 2026-02-06 - Source: https://github.com/enkogu/pipeline-fullstack-app - Web: https://mule.run/skillshub/@@enkogu/pipeline-fullstack-app~gmail:20260125155958 --- --- name: gmail description: Send, read, search emails, manage labels, drafts, and attachments python_requires: - google-api-python-client - google-auth - google-auth-oauthlib - requests requires_oauth: - gmail capabilities: - search_emails - list_emails - read_email - send_email - reply_email - manage_labels - manage_drafts - download_attachments --- # Gmail Skill ## ⚠️ SCRIPT NAMES - These Do NOT Exist Do NOT guess script names. These common mistakes will fail: | ❌ WRONG (doesn't exist) | ✅ CORRECT (use this) | |--------------------------|----------------------| | list-attachments.py | get-attachments.py | | search-messages.py | search-emails.py | | list-messages.py | search-emails.py | | get-emails.py | search-emails.py | | find-emails.py | search-emails.py | | fetch-email.py | read-email.py | | get-email.py | read-email.py | | download-email.py | read-email.py | | read-message.py | read-email.py | ## File Storage Location All downloaded attachments are saved to: `~/.standi/downloads/gmail/` The script returns the absolute `file_path` in the response - use that path for subsequent operations (upload, read, process). ## Script Comparison - Choose the Right Script ### Attachment Scripts | Script | Purpose | Input | Output | |--------|---------|-------|--------| | `get-attachments.py` | List attachment metadata | MESSAGE_ID | Filenames, sizes, attachment IDs | | `download-attachment.py` | Download ONE specific attachment | MESSAGE_ID, ATTACHMENT_ID | Saved file path | | `process-attachments.py` | Batch download from recent emails | DAYS_BACK (integer) | Multiple saved files | | `extract-invoices.py` | List invoice email metadata | DAYS_BACK (integer) | Email list with attachment info (NO download) | | `download-invoices.py` | Batch download invoice attachments | DAYS_BACK (integer) | Multiple saved invoice files | **Common mistake**: Using `process-attachments.py` with a MESSAGE_ID - it expects DAYS_BACK (integer). Use `download-attachment.py` for specific attachments. ### Email Reading Scripts | Script | Purpose | Body Length | Extra Data | |--------|---------|-------------|------------| | `read-email.py` | Quick email read | 5000 chars | Basic headers | | `get-message.py` | Full message details | 10000 chars | Threading headers (Message-ID, References, In-Reply-To) | ### Draft vs Send Scripts | Script | Action | |--------|--------| | `create-draft.py` | Creates draft for later editing/sending | | `send-email.py` | Sends immediately | | `reply-email.py` | Sends reply immediately | | `create-draft-reply.py` | Creates draft reply for editing | ## Common Mistakes 1. **Format options for send-email/create-draft/reply-email:** - ✅ JSON array (explicit order): `'["to@email.com", "Subject", "Body"]'` - ✅ JSON object (auto-converted): `'{"to": "to@email.com", "subject": "Subject", "body": "Body"}'` - Both formats work - JSON object is auto-converted to positional using param_names 2. **Note on process-attachments.py**: JSON object format is supported: - ✅ `'{"days": 60, "query": "has:attachment"}'` → Works - ✅ `'["60", "has:attachment"]'` → Also works 3. **Wrong script for attachment download**: - ❌ `process-attachments.py "19a07f715f14dd67"` (MESSAGE_ID) → ValueError - ✅ `download-attachment.py "MESSAGE_ID" "ATTACHMENT_ID"` → Downloads specific file 4. **Confusing extract vs download for invoices**: - `extract-invoices.py` → Returns metadata only (no files saved) - `download-invoices.py` → Actually downloads files to disk 5. **Missing attachment_id**: - First call `get-attachments.py` to get the attachment_id - Then call `download-attachment.py` with both message_id AND attachment_id ## Commands ### Search Emails Param names: `max_results`, `query` ``` # Positional format: run_skill("gmail/search-emails.py", "") run_skill("gmail/search-emails.py", '["", ""]') # JSON object format (RECOMMENDED for complex queries): run_skill("gmail/search-emails.py", '{"max_results": 50, "query": "subject:invoice has:attachment"}') ``` **Examples:** ``` # Simple query (default 10 results) - single arg run_skill("gmail/search-emails.py", "invoice") run_skill("gmail/search-emails.py", "subject:invoice") run_skill("gmail/search-emails.py", "from:john@example.com") run_skill("gmail/search-emails.py", "has:attachment") # Query with max results - JSON object (recommended) run_skill("gmail/search-emails.py", '{"max_results": 50, "query": "subject:invoice"}') run_skill("gmail/search-emails.py", '{"max_results": 100, "query": "has:attachment newer_than:60d"}') # Positional array also works: run_skill("gmail/search-emails.py", '["20", "from:amazon.com subject:order"]') ``` **Query operators you can combine:** - `from:email@example.com` - from specific sender - `to:email@example.com` - to specific recipient - `subject:word` - subject contains word - `has:attachment` - has attachments - `is:unread` / `is:starred` - status filters - `newer_than:7d` / `older_than:30d` - date filters - `filename:pdf` - attachment filename ### List Recent Emails ``` run_skill("gmail/list-emails.py", "") run_skill("gmail/list-emails.py", "20") ``` **Examples:** ``` # List 10 recent emails (default) run_skill("gmail/list-emails.py", "") # List 20 recent emails run_skill("gmail/list-emails.py", "20") ``` ### Read Email ``` run_skill("gmail/read-email.py", "") ``` **Example:** ``` run_skill("gmail/read-email.py", "18abc123def456") ``` ### Get Message (Full Details with Threading Headers) ``` run_skill("gmail/get-message.py", "") ``` Returns: id, from, to, cc, subject, date, body, attachments, thread_id, message_id_header, references, in_reply_to. ### Send Email Param names: `to`, `subject`, `body` ``` # Positional format: run_skill("gmail/send-email.py", '["to_email", "subject", "body"]') # JSON object format (auto-converted): run_skill("gmail/send-email.py", '{"to": "to@email.com", "subject": "Subject", "body": "Body text"}') ``` **Examples:** ``` # JSON array format (3 arguments) run_skill("gmail/send-email.py", '["john@example.com", "Meeting Tomorrow", "Hi John, let us discuss the project."]') run_skill("gmail/send-email.py", '["client@company.com", "Follow Up", "Thanks for your time today!"]') # JSON object format (auto-converted to positional) run_skill("gmail/send-email.py", '{"to": "client@company.com", "subject": "Project Update", "body": "Dear Client,\n\nHere is the update."}') ``` ### Reply to Email Param names: `message_id`, `body` ``` # Positional format: run_skill("gmail/reply-email.py", '["", ""]') # JSON object format (auto-converted): run_skill("gmail/reply-email.py", '{"message_id": "", "body": ""}') ``` **Example:** ``` run_skill("gmail/reply-email.py", '["18abc123def456", "Thanks for your email!"]') run_skill("gmail/reply-email.py", '{"message_id": "18abc123def456", "body": "Thanks for your email!"}') ``` ## Labels ### List Labels ``` run_skill("gmail/list-labels.py", "") ``` ### Create Label ``` run_skill("gmail/create-label.py", "") ``` **Example:** ``` run_skill("gmail/create-label.py", "Invoices") ``` ### Apply Labels ``` run_skill("gmail/apply-labels.py", '["", ""]') run_skill("gmail/apply-labels.py", '["", "", ""]') ``` **Example:** ``` run_skill("gmail/apply-labels.py", '["18abc123def456", "add:Label_123,Label_456"]') ``` ## Drafts ### Create Draft Param names: `to`, `subject`, `body` ``` # Positional format: run_skill("gmail/create-draft.py", '["to_email", "subject", "body"]') # JSON object format (auto-converted): run_skill("gmail/create-draft.py", '{"to": "to@email.com", "subject": "Subject", "body": "Body text"}') ``` **Examples:** ``` # JSON array format (3 arguments) run_skill("gmail/create-draft.py", '["john@example.com", "Hello", "Hi there, this is my message body."]') run_skill("gmail/create-draft.py", '["client@company.com", "Project Update", "Dear Client,\n\nHere is the update you requested.\n\nBest regards"]') # JSON object format (auto-converted to positional) run_skill("gmail/create-draft.py", '{"to": "email@example.com", "subject": "Let us Connect", "body": "I hope this email finds you well."}') ``` ### Create Draft Reply Param names: `message_id`, `thread_id`, `body` ``` # Positional format: run_skill("gmail/create-draft-reply.py", '["message_id", "thread_id", "body"]') # JSON object format (auto-converted): run_skill("gmail/create-draft-reply.py", '{"message_id": "", "thread_id": "", "body": ""}') ``` **Example:** ``` # JSON array format (3 arguments) run_skill("gmail/create-draft-reply.py", '["18abc123def456", "thread_789", "Thanks for the update!"]') # JSON object format run_skill("gmail/create-draft-reply.py", '{"message_id": "18abc123def456", "thread_id": "thread_789", "body": "Thanks for the update!"}') ``` ### List Drafts ``` run_skill("gmail/list-drafts.py", "") run_skill("gmail/list-drafts.py", "20") ``` ### Get Draft ``` run_skill("gmail/get-draft.py", "") ``` ### Update Draft ``` run_skill("gmail/update-draft.py", '["draft_id", "to_email", "subject", "body"]') ``` **Example:** ``` # REQUIRED: Use JSON array format for 4 arguments run_skill("gmail/update-draft.py", '["draft_abc123", "john@example.com", "Updated Subject", "Updated body text"]') ``` ### Delete Draft ``` run_skill("gmail/delete-draft.py", "") ``` ## Attachments ### Get Attachments Info ``` run_skill("gmail/get-attachments.py", "") ``` **Example:** ``` run_skill("gmail/get-attachments.py", "18abc123def456") ``` Returns list of: filename, mime_type, size, attachment_id ### Download Attachment Param names: `message_id`, `attachment_id`, `path` **Files saved to:** `~/.standi/downloads/gmail/` ``` # Positional format: run_skill("gmail/download-attachment.py", '["", ""]') run_skill("gmail/download-attachment.py", '["", "", ""]') # JSON object format (RECOMMENDED): run_skill("gmail/download-attachment.py", '{"message_id": "...", "attachment_id": "..."}') run_skill("gmail/download-attachment.py", '{"message_id": "...", "attachment_id": "...", "path": "/output/file.pdf"}') ``` **Original filename preserved:** When no output path is provided, the script attempts to use the original attachment filename. **Example:** ``` # First get the attachment_id from get-attachments run_skill("gmail/get-attachments.py", "18abc123def456") # Returns: {"attachments": [{"filename": "Invoice_2025.pdf", "attachment_id": "ANGjdJ8xyz", ...}]} # Then download - JSON object format (recommended) run_skill("gmail/download-attachment.py", '{"message_id": "18abc123def456", "attachment_id": "ANGjdJ8xyz"}') # Returns: {"file_path": "/Users/you/.standi/downloads/gmail/Invoice_2025.pdf", ...} # Or with custom output path run_skill("gmail/download-attachment.py", '{"message_id": "18abc123def456", "attachment_id": "ANGjdJ8xyz", "path": "/custom/Invoice.pdf"}') # Positional array also works: run_skill("gmail/download-attachment.py", '["18abc123def456", "ANGjdJ8xyz"]') ``` ### Process Attachments (Batch Download) Param names: `days`, `query` ``` # Positional format: run_skill("gmail/process-attachments.py", "") run_skill("gmail/process-attachments.py", "") run_skill("gmail/process-attachments.py", '["", ""]') # JSON object format (RECOMMENDED): run_skill("gmail/process-attachments.py", '{"days": 60, "query": "subject:invoice has:attachment"}') ``` **Examples:** ``` # Download attachments from last 7 days (default) run_skill("gmail/process-attachments.py", "") # Download attachments from last 30 days run_skill("gmail/process-attachments.py", "30") # Download invoice attachments from last 60 days - JSON object (recommended) run_skill("gmail/process-attachments.py", '{"days": 60, "query": "subject:invoice"}') # Positional array also works: run_skill("gmail/process-attachments.py", '["60", "subject:invoice"]') ``` ## Invoice Processing ### Extract Invoices ``` run_skill("gmail/extract-invoices.py", "") ``` Searches for invoices and extracts attachment info. ### Download Invoices ``` run_skill("gmail/download-invoices.py", "") ``` Downloads all invoice attachments to artifacts folder. ## Output Format All scripts output JSON to stdout with `success` boolean and data/error fields. ## Common Workflow Examples ### Find and process invoice emails ``` # 1. Search for invoice emails (50 results max) - 2 args need JSON array run_skill("gmail/search-emails.py", '["50", "subject:invoice has:attachment"]') # 2. Read a specific email (using ID from search results) run_skill("gmail/read-email.py", "18abc123def456") # 3. Get attachments info run_skill("gmail/get-attachments.py", "18abc123def456") # 4. Download attachment - JSON object format (recommended) run_skill("gmail/download-attachment.py", '{"msg_id": "18abc123def456", "attach_id": "ANGjdJ8xyz"}') # 5. Create a label for processed invoices run_skill("gmail/create-label.py", "Processed") # 6. Apply label to the email - 2 args need JSON array run_skill("gmail/apply-labels.py", '["18abc123def456", "add:Label_123"]') ``` ### Quick batch download of recent attachments ``` # Download all attachments from invoices in last 60 days - 2 args need JSON array run_skill("gmail/process-attachments.py", '["60", "subject:invoice"]') ``` ### Reply to an email ``` # 1. Find the email run_skill("gmail/search-emails.py", "from:client@example.com") # 2. Read it to get context run_skill("gmail/read-email.py", "18abc123def456") # 3. Reply - 2 args need JSON array run_skill("gmail/reply-email.py", '["18abc123def456", "Thank you for your message. I will review and get back to you."]') ``` ### Send a professional email ``` # Use JSON array for 3 arguments run_skill("gmail/send-email.py", '["client@company.com", "Proposal Follow-Up", "Dear Client,\n\nThank you for your time yesterday. I wanted to follow up on our discussion.\n\nBest regards"]') # Or create a draft first for review run_skill("gmail/create-draft.py", '["client@company.com", "Proposal Follow-Up", "Dear Client,\n\nThank you for your time yesterday.\n\nBest regards"]') ```