Skip to content
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. Dibahas praktis dengan konteks Radian Group, enginee
7 minutes to read
4 bulan lalu
Zainul Fanani
Gmail Auto-Label & Triage: Email Teratur Tanpa Manual Sorting
๐Ÿ“… 11 Mar 2026๐Ÿค0 ๐Ÿ‘ 0 ๐Ÿ”— 0

๐Ÿ“Ž 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


๐Ÿ“‚ Visual Label System

text
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ๐Ÿท๏ธ  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


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

Step 1: Create Gmail Labels

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

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

Step 2: Enable Gmail API Access

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

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

๐Ÿ“‹ Classification Rules

Rule Engine Logic

text
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    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


๐Ÿ”” Notification Setup

Telegram Bot Configuration

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

text
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  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

python
#!/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

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

2. Create Environment File

bash
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)

bash
# 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)

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

Test Telegram Notifications

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

Verify Gmail Labels

bash
gog gmail labels list

๐Ÿ“Š Expected Results

After running for 1 week:

text
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ๐Ÿ“ง 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:

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

Changing Notification Schedule

Modify the cron timing:

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


๐Ÿ’ก 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)

Newsletter

Subscribe to Newsletter

Artikel baru, automation notes, dan engineering insight. Clean inbox, no spam.

Dengan subscribe, kamu setuju menerima update seperlunya.

F
Zainul Fanani

Founder, Radian Group. Engineering & tech enthusiast.

Lihat profil lengkap โ†’