Tech

Gmail Auto-Label & Triage: Email Teratur Tanpa Manual Sorting

Inbox rapi otomatis. Setup AI-based email triage yang label, prioritas, dan sort email tanpa kamu sentuh.

๐Ÿ‘ค Zainul Fanani๐Ÿ“… 11 Maret 2026โฑ 1 min read

๐Ÿ“Ž Source:openclaw-sumopod โ€” view on GitHub & star โญ

๐Ÿ“ง Gmail Auto-Label & Smart Triage Tutorial

Transform your inbox chaos into organized, prioritized workflows โ€” automatically!


๐ŸŽฏ Before vs After

BEFORE ๐Ÿ˜ซAFTER ๐Ÿš€
847 unread emailsZero unread, all labeled
Manually sorting each messageAuto-classification in seconds
Missing urgent client emailsPriority routing to top of inbox
Scrolling forever to find docsInstant label-based search
No idea what needs actionClear task queue with notifications

๐Ÿ“‚ Visual Label System

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ ๐Ÿท๏ธ YOUR SMART LABEL HIERARCHY โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ โ”‚ โ”‚ ๐Ÿ“„ Documents โ†’ Contracts, PDFs, proposals โ”‚ โ”‚ ๐Ÿข Clients โ†’ Client communications โ”‚ โ”‚ ๐Ÿ“Š Reports โ†’ Analytics, dashboards, data โ”‚ โ”‚ ๐Ÿ“‹ Tasks โ†’ Action items, to-do requests โ”‚ โ”‚ ๐Ÿ”ฅ Urgent โ†’ High priority, needs attention โ”‚ โ”‚ ๐Ÿ“ฐ Newsletters โ†’ Subscriptions, updates โ”‚ โ”‚ ๐Ÿ—‘๏ธ Low Priority โ†’ FYI only, read when free โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Label Color Coding

LabelColorMeaning
๐Ÿ“„ Documents๐Ÿ”ต BlueReference material
๐Ÿข Clients๐ŸŸข GreenRevenue-critical
๐Ÿ“Š Reports๐ŸŸฃ PurpleData & insights
๐Ÿ“‹ Tasks๐ŸŸ  OrangeRequires action
๐Ÿ”ฅ Urgent๐Ÿ”ด RedImmediate attention
๐Ÿ“ฐ Newsletters๐ŸŸก YellowInformational
๐Ÿ—‘๏ธ Low Priorityโšช GrayOptional reading

๐Ÿ› ๏ธ Step-by-Step Setup

Step 1: Create Gmail Labels

Go to Gmail โ†’ Left sidebar โ†’ Click "+" next to Labels

Create these labels: โ”œโ”€โ”€ ๐Ÿ“„ Documents โ”œโ”€โ”€ ๐Ÿข Clients โ”œโ”€โ”€ ๐Ÿ“Š Reports โ”œโ”€โ”€ ๐Ÿ“‹ Tasks โ”œโ”€โ”€ ๐Ÿ”ฅ Urgent โ”œโ”€โ”€ ๐Ÿ“ฐ Newsletters โ””โ”€โ”€ ๐Ÿ—‘๏ธ Low Priority

Step 2: Enable Gmail API Access

# Install gog CLI (if not already installed) curl -sSL https://openclaw.dev/install/gog | bash # Authenticate with your Google account gog auth login # Verify access gog gmail list --max=5

Step 3: Create Project Directory

mkdir -p ~/automation/gmail-triage cd ~/automation/gmail-triage

๐Ÿ“‹ Classification Rules

Rule Engine Logic

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ EMAIL CLASSIFICATION FLOW โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ โ”‚ โ”‚ ๐Ÿ“ง New Email Arrives โ”‚ โ”‚ โ†“ โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ Check Keywords โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ†“ โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ†“ โ†“ โ†“ โ†“ โ”‚ โ”‚ ๐Ÿ”ฅ Urgent ๐Ÿข Clients ๐Ÿ“„ Docs ๐Ÿ“Š Reports โ”‚ โ”‚ (contains: (from: (subject: (subject: โ”‚ โ”‚ "URGENT" @client.com) "contract" "report") โ”‚ โ”‚ "ASAP") OR .pdf) โ”‚ โ”‚ โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ†“ โ†“ โ†“ โ”‚ โ”‚ ๐Ÿ“‹ Tasks ๐Ÿ“ฐ Newsletters ๐Ÿ—‘๏ธ Low Priority โ”‚ โ”‚ (subject: (from: (no match) โ”‚ โ”‚ "action" newsletter) โ”‚ โ”‚ "task") โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Keyword Dictionary

LabelKeywords (Subject OR Body)Sender Patterns
๐Ÿ”ฅ Urgenturgent, asap, emergency, deadline today-
๐Ÿข Clientsproposal, contract, invoice, project*@client*.com
๐Ÿ“„ Documents.pdf, .doc, contract, agreement, attachment-
๐Ÿ“Š Reportsreport, analytics, dashboard, metrics, statsnoreply@*analytics*
๐Ÿ“‹ Tasksaction required, task, todo, please review, approve-
๐Ÿ“ฐ Newslettersnewsletter, weekly, update, digestnewsletter@*
๐Ÿ—‘๏ธ Low Priorityfyi, for your information, no actionno-reply@*

๐Ÿ”” Notification Setup

Telegram Bot Configuration

# 1. Create Telegram Bot via @BotFather # 2. Get your Chat ID via @userinfobot # 3. Set environment variables export TELEGRAM_BOT_TOKEN="YOUR_BOT_TOKEN_HERE" export TELEGRAM_CHAT_ID="YOUR_CHAT_ID_HERE"

Notification Triggers

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ WHEN TO SEND TELEGRAM ALERTS โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ โ”‚ โ”‚ โœ… ALWAYS notify on: โ”‚ โ”‚ โ€ข ๐Ÿ”ฅ Urgent emails โ”‚ โ”‚ โ€ข ๐Ÿข Client emails (high value) โ”‚ โ”‚ โ€ข ๐Ÿ“‹ Task emails (requires action) โ”‚ โ”‚ โ”‚ โ”‚ โš ๏ธ SUMMARIZE only (daily digest): โ”‚ โ”‚ โ€ข ๐Ÿ“„ Documents received โ”‚ โ”‚ โ€ข ๐Ÿ“Š Reports generated โ”‚ โ”‚ โ”‚ โ”‚ โŒ NO notification: โ”‚ โ”‚ โ€ข ๐Ÿ“ฐ Newsletters (check when convenient) โ”‚ โ”‚ โ€ข ๐Ÿ—‘๏ธ Low Priority (batch review weekly) โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ’ป Full Code Script

gmail-triage.py โ€” Complete Auto-Label System

#!/usr/bin/env python3 """ ๐Ÿ“ง Gmail Auto-Label & Smart Triage Automated email classification with Telegram notifications """ import os import re import json import base64 from datetime import datetime, timedelta from typing import List, Dict, Optional import requests # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• # CONFIGURATION # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• # Telegram Settings TELEGRAM_BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN", "YOUR_BOT_TOKEN") TELEGRAM_CHAT_ID = os.getenv("TELEGRAM_CHAT_ID", "YOUR_CHAT_ID") # Label Definitions with Keywords LABEL_RULES = { "๐Ÿ”ฅ Urgent": { "keywords": ["urgent", "asap", "emergency", "deadline today", "critical"], "senders": [], "notify": True, "priority": 1 }, "๐Ÿข Clients": { "keywords": ["proposal", "contract", "invoice", "project", "quotation"], "senders": ["client", "customer"], # Pattern matching "notify": True, "priority": 2 }, "๐Ÿ“„ Documents": { "keywords": [".pdf", ".doc", "contract", "agreement", "document", "attachment"], "senders": [], "notify": False, "priority": 3 }, "๐Ÿ“Š Reports": { "keywords": ["report", "analytics", "dashboard", "metrics", "stats", "performance"], "senders": ["analytics", "reports", "noreply"], "notify": False, "priority": 4 }, "๐Ÿ“‹ Tasks": { "keywords": ["action required", "task", "todo", "please review", "approve", "sign"], "senders": [], "notify": True, "priority": 2 }, "๐Ÿ“ฐ Newsletters": { "keywords": ["newsletter", "weekly", "update", "digest", "roundup"], "senders": ["newsletter", "updates"], "notify": False, "priority": 5 }, "๐Ÿ—‘๏ธ Low Priority": { "keywords": ["fyi", "for your information", "no action needed"], "senders": ["no-reply", "noreply", "notifications"], "notify": False, "priority": 6 } } # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• # TELEGRAM NOTIFICATIONS # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• def send_telegram_message(message: str, priority: int = 3): """Send notification to Telegram with priority formatting""" # Priority emojis priority_emojis = {1: "๐Ÿšจ", 2: "โšก", 3: "๐Ÿ“ง", 4: "๐Ÿ“Ž", 5: "๐Ÿ“ฐ", 6: "โšช"} emoji = priority_emojis.get(priority, "๐Ÿ“ง") # Format message with priority formatted = f"{emoji} *Gmail Triage Alert*\n\n{message}" url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage" payload = { "chat_id": TELEGRAM_CHAT_ID, "text": formatted, "parse_mode": "Markdown", "disable_notification": priority > 2 # Silent for low priority } try: response = requests.post(url, json=payload, timeout=10) return response.json().get("ok", False) except Exception as e: print(f"โŒ Telegram error: {e}") return False def send_daily_summary(stats: Dict): """Send daily digest of classified emails""" message = f""" ๐Ÿ“Š *Daily Email Summary* ๐Ÿ“ง Total Processed: `{stats['total']}` ๐Ÿ”ฅ Urgent: `{stats['urgent']}` ๐Ÿข Clients: `{stats['clients']}` ๐Ÿ“‹ Tasks: `{stats['tasks']}` ๐Ÿ“„ Documents: `{stats['documents']}` ๐Ÿ“Š Reports: `{stats['reports']}` ๐Ÿ“ฐ Newsletters: `{stats['newsletters']}` โœ… All emails have been auto-labeled! """ send_telegram_message(message, priority=3) # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• # EMAIL CLASSIFICATION ENGINE # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• def classify_email(subject: str, sender: str, body: str = "") -> Optional[str]: """ Classify email based on rules Returns label name or None """ text = f"{subject} {body}".lower() sender_lower = sender.lower() best_match = None best_priority = 999 for label, rules in LABEL_RULES.items(): score = 0 # Check keywords for keyword in rules["keywords"]: if keyword.lower() in text: score += 1 # Check sender patterns for pattern in rules["senders"]: if pattern.lower() in sender_lower: score += 2 # Sender match is stronger # If matched and higher priority (lower number), update if score > 0 and rules["priority"] < best_priority: best_match = label best_priority = rules["priority"] return best_match def get_label_id(label_name: str) -> Optional[str]: """Get Gmail label ID from name using gog CLI""" import subprocess try: result = subprocess.run( ["gog", "gmail", "labels", "list", "--format=json"], capture_output=True, text=True, timeout=30 ) if result.returncode != 0: print(f"โŒ Error fetching labels: {result.stderr}") return None labels = json.loads(result.stdout) for label in labels: if label.get("name") == label_name: return label.get("id") return None except Exception as e: print(f"โŒ Error: {e}") return None def apply_label(message_id: str, label_id: str) -> bool: """Apply label to Gmail message""" import subprocess try: result = subprocess.run( ["gog", "gmail", "messages", "modify", message_id, "--add-label", label_id], capture_output=True, text=True, timeout=30 ) return result.returncode == 0 except Exception as e: print(f"โŒ Error applying label: {e}") return False # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• # MAIN TRIAGE WORKFLOW # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• def fetch_unprocessed_emails(max_results: int = 50) -> List[Dict]: """Fetch recent unread emails using gog CLI""" import subprocess try: result = subprocess.run( ["gog", "gmail", "list", "--query", "is:unread -in:๐Ÿ“„* -in:๐Ÿข* -in:๐Ÿ“Š* -in:๐Ÿ“‹* -in:๐Ÿ”ฅ* -in:๐Ÿ“ฐ* -in:๐Ÿ—‘๏ธ*", "--max", str(max_results), "--format=json"], capture_output=True, text=True, timeout=60 ) if result.returncode != 0: print(f"โŒ Error fetching emails: {result.stderr}") return [] return json.loads(result.stdout) if result.stdout else [] except Exception as e: print(f"โŒ Error: {e}") return [] def get_email_content(message_id: str) -> Dict: """Get full email content""" import subprocess try: result = subprocess.run( ["gog", "gmail", "get", message_id, "--format=json"], capture_output=True, text=True, timeout=30 ) if result.returncode == 0 and result.stdout: return json.loads(result.stdout) return {} except Exception as e: print(f"โŒ Error fetching email: {e}") return {} def triage_emails(dry_run: bool = False): """Main triage function""" print("๐Ÿ” Starting Gmail Triage...") print("โ”" * 50) # Statistics stats = {key: 0 for key in LABEL_RULES.keys()} stats["total"] = 0 stats["unclassified"] = 0 # Fetch emails emails = fetch_unprocessed_emails(max_results=100) if not emails: print("โœ… No new emails to process!") return print(f"๐Ÿ“ง Found {len(emails)} unprocessed emails\n") for email in emails: msg_id = email.get("id") subject = email.get("subject", "No Subject") sender = email.get("from", "Unknown") print(f"Processing: {subject[:50]}...") # Get full content for better classification full_email = get_email_content(msg_id) body = full_email.get("snippet", "") # Classify label = classify_email(subject, sender, body) if label: stats[label] += 1 stats["total"] += 1 print(f" โ””โ”€ ๐Ÿ“Œ Labeled: {label}") if not dry_run: # Apply label label_id = get_label_id(label) if label_id: apply_label(msg_id, label_id) # Send notification if required rules = LABEL_RULES[label] if rules["notify"]: message = f""" *{label}* *From:* `{sender}` *Subject:* {subject} _Priority Level: {rules['priority']}_ """ send_telegram_message(message, rules["priority"]) print(f" โ””โ”€ ๐Ÿ“ฑ Notification sent") else: stats["unclassified"] += 1 print(f" โ””โ”€ โšช No match (skipped)") print("\n" + "โ”" * 50) print("๐Ÿ“Š TRIAGE SUMMARY") print("โ”" * 50) for label, count in stats.items(): if count > 0 and label in LABEL_RULES: print(f" {label}: {count}") print(f" Total: {stats['total']}") print(f" Unclassified: {stats['unclassified']}") print("โ”" * 50) # Send daily summary if it's the last run of the day hour = datetime.now().hour if hour >= 18: # After 6 PM send_daily_summary(stats) # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• # PRIORITY ROUTING # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• def move_to_inbox_top(message_id: str): """Move important emails to top of inbox""" import subprocess try: # Mark as important subprocess.run( ["gog", "gmail", "messages", "modify", message_id, "--add-label", "IMPORTANT"], capture_output=True, timeout=10 ) except Exception as e: print(f"โš ๏ธ Could not prioritize: {e}") def archive_low_priority(): """Auto-archive low priority emails""" import subprocess try: result = subprocess.run( ["gog", "gmail", "list", "--query", "in:๐Ÿ—‘๏ธ* is:unread older_than:7d", "--format=json"], capture_output=True, text=True, timeout=30 ) if result.returncode == 0: emails = json.loads(result.stdout) if result.stdout else [] for email in emails: msg_id = email.get("id") subprocess.run( ["gog", "gmail", "messages", "modify", msg_id, "--remove-label", "INBOX"], capture_output=True, timeout=10 ) print(f"๐Ÿ“ฆ Archived {len(emails)} old low-priority emails") except Exception as e: print(f"โš ๏ธ Could not archive: {e}") # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• # CLI INTERFACE # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• if __name__ == "__main__": import argparse parser = argparse.ArgumentParser( description="๐Ÿ“ง Gmail Auto-Label & Smart Triage", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" Examples: python gmail-triage.py # Run triage python gmail-triage.py --dry-run # Preview only python gmail-triage.py --archive # Archive old low-priority python gmail-triage.py --summary # Send daily summary """ ) parser.add_argument("--dry-run", action="store_true", help="Preview without applying labels") parser.add_argument("--archive", action="store_true", help="Archive old low-priority emails") parser.add_argument("--summary", action="store_true", help="Send daily summary now") args = parser.parse_args() if args.archive: archive_low_priority() elif args.summary: send_daily_summary({ "total": 0, "urgent": 0, "clients": 0, "tasks": 0, "documents": 0, "reports": 0, "newsletters": 0 }) else: triage_emails(dry_run=args.dry_run)

โšก Automation Setup

1. Make Script Executable

chmod +x ~/automation/gmail-triage/gmail-triage.py

2. Create Environment File

cat > ~/automation/gmail-triage/.env << 'EOF' TELEGRAM_BOT_TOKEN=your_bot_token_here TELEGRAM_CHAT_ID=your_chat_id_here EOF

3. Add to Crontab (Auto-Run Every 15 Minutes)

# Open crontab crontab -e # Add this line: */15 * * * * cd ~/automation/gmail-triage && source .env && python3 gmail-triage.py >> triage.log 2>&1 # Daily summary at 6 PM 0 18 * * * cd ~/automation/gmail-triage && source .env && python3 gmail-triage.py --summary >> triage.log 2>&1

๐Ÿงช Testing Your Setup

Dry Run (Safe Preview)

cd ~/automation/gmail-triage python3 gmail-triage.py --dry-run

Test Telegram Notifications

python3 -c " from gmail_triage import send_telegram_message send_telegram_message('๐Ÿงช Test notification working!', priority=1) "

Verify Gmail Labels

gog gmail labels list

๐Ÿ“Š Expected Results

After running for 1 week:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ ๐Ÿ“ง WEEKLY STATISTICS โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ โ”‚ โ”‚ Emails Processed: ~500 โ”‚ โ”‚ Auto-Labeled: ~450 (90%) โ”‚ โ”‚ Manual Review: ~50 (10%) โ”‚ โ”‚ Notifications Sent: ~25 โ”‚ โ”‚ Time Saved: ~3 hours/week โ”‚ โ”‚ โ”‚ โ”‚ ๐ŸŽฏ Zero emails slip through the cracks! โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ”ง Customization Tips

Adding New Labels

  1. Create label in Gmail
  2. Add to LABEL_RULES dictionary
  3. Define keywords and priority

Adjusting Keywords

Edit the keywords list in LABEL_RULES:

"๐Ÿข Clients": { "keywords": ["your", "custom", "keywords", "here"], "senders": ["@yourclient.com"], "notify": True, "priority": 2 }

Changing Notification Schedule

Modify the cron timing:

# Every 5 minutes (more frequent) */5 * * * * python3 gmail-triage.py # Hourly 0 * * * * python3 gmail-triage.py # Business hours only */15 9-17 * * 1-5 python3 gmail-triage.py

โœ… Quick Start Checklist

  • Create 7 Gmail labels (๐Ÿ“„ ๐Ÿข ๐Ÿ“Š ๐Ÿ“‹ ๐Ÿ”ฅ ๐Ÿ“ฐ ๐Ÿ—‘๏ธ)
  • Install gog CLI and authenticate
  • Create Telegram bot (@BotFather)
  • Get Telegram Chat ID (@userinfobot)
  • Save script to ~/automation/gmail-triage/
  • Set environment variables
  • Test with --dry-run
  • Add to crontab
  • Monitor first few runs
  • Adjust keywords as needed

๐Ÿ†˜ Troubleshooting

ProblemSolution
Labels not applyingCheck gog auth status
No Telegram notificationsVerify BOT_TOKEN and CHAT_ID
Wrong classificationsAdjust keywords in LABEL_RULES
Script not runningCheck cron logs: grep CRON /var/log/syslog
Rate limitingReduce cron frequency to every 30 min

๐Ÿ’ก Pro Tip: Review your labeled emails weekly to refine keywords and improve accuracy!

Happy Triage! ๐Ÿš€

Ada Pertanyaan? Yuk Ngobrol!

Butuh bantuan setup OpenClaw, konsultasi IT, atau mau diskusi project engineering? Book a call langsung โ€” gratis.

Book a Call โ€” Gratis

via Cal.com โ€ข WITA (UTC+8)

F

Zainul Fanani

Founder, Radian Group. Engineering & tech enthusiast.

Radian Group

Engineering Excellence Across Indonesia

Perusahaan

  • CV Radian Fokus Mandiri โ€” Balikpapan
  • PT UNO Solusi Teknik โ€” Balikpapan
  • PT Reka Formasi Elektrika โ€” Jakarta
  • PT Raya Fokus Solusi โ€” Sidoarjo
ยฉ 2026 Radian Group. All rights reserved.