{
  "schemaVersion": "1.0",
  "item": {
    "slug": "email-to-calendar",
    "name": "Email To Calendar",
    "source": "tencent",
    "type": "skill",
    "category": "效率提升",
    "sourceUrl": "https://clawhub.ai/tonimelisma/email-to-calendar",
    "canonicalUrl": "https://clawhub.ai/tonimelisma/email-to-calendar",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/email-to-calendar",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=email-to-calendar",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "BOOT.md",
      "CHANGELOG.md",
      "CONTRIBUTING.md",
      "SETUP.md",
      "SKILL.md",
      "package.json"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-23T16:43:11.935Z",
      "expiresAt": "2026-04-30T16:43:11.935Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=4claw-imageboard",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=4claw-imageboard",
        "contentDisposition": "attachment; filename=\"4claw-imageboard-1.0.1.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/email-to-calendar"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/email-to-calendar",
    "agentPageUrl": "https://openagent3.xyz/skills/email-to-calendar/agent",
    "manifestUrl": "https://openagent3.xyz/skills/email-to-calendar/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/email-to-calendar/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Email to Calendar Skill",
        "body": "Extract calendar events and action items from emails, present them for review, and create/update calendar events with duplicate detection and undo support.\n\nFirst-time setup: See SETUP.md for configuration options and smart onboarding."
      },
      {
        "title": "Reading Email Content",
        "body": "IMPORTANT: Before you can extract events, you must read the email body. Use the wrapper scripts.\n\nSCRIPTS_DIR=\"$HOME/.openclaw/workspace/skills/email-to-calendar/scripts\"\n\n# Get a single email by ID (PREFERRED)\n\"$SCRIPTS_DIR/email_read.sh\" --email-id \"<messageId>\"\n\n# Search with body content included\n\"$SCRIPTS_DIR/email_search.sh\" --query \"in:inbox is:unread\" --max 20 --include-body\n\nNote on stale forwards: Don't use newer_than:1d because it checks the email's original date header, not when it was received. Process all UNREAD emails and rely on the \"already processed\" check."
      },
      {
        "title": "0. Pre-Processing Checks (MANDATORY)",
        "body": "SCRIPTS_DIR=\"$HOME/.openclaw/workspace/skills/email-to-calendar/scripts\"\nCONFIG_FILE=\"$HOME/.config/email-to-calendar/config.json\"\nINDEX_FILE=\"$HOME/.openclaw/workspace/memory/email-extractions/index.json\"\n\n# Start activity logging\n\"$SCRIPTS_DIR/activity_log.sh\" start-session\n\n# Check email mode\nEMAIL_MODE=$(jq -r '.email_mode // \"forwarded\"' \"$CONFIG_FILE\")\n\n# Check if email was already processed\nEMAIL_ID=\"<the email message ID>\"\nif jq -e \".extractions[] | select(.email_id == \\\"$EMAIL_ID\\\")\" \"$INDEX_FILE\" > /dev/null 2>&1; then\n    \"$SCRIPTS_DIR/activity_log.sh\" log-skip --email-id \"$EMAIL_ID\" --subject \"Subject\" --reason \"Already processed\"\n    exit 0\nfi\n\n# Load ignore/auto-create patterns\nIGNORE_PATTERNS=$(jq -r '.event_rules.ignore_patterns[]' \"$CONFIG_FILE\")\nAUTO_CREATE_PATTERNS=$(jq -r '.event_rules.auto_create_patterns[]' \"$CONFIG_FILE\")"
      },
      {
        "title": "1. Find Emails to Process",
        "body": "DIRECT mode: Scan all unread emails for event indicators (dates, times, meeting keywords).\n\nFORWARDED mode: Only process emails with forwarded indicators (Fwd:, forwarded message headers)."
      },
      {
        "title": "2. Extract Events (Agent does this directly)",
        "body": "Read the email and extract events as structured data. Include for each event:\n\ntitle: Descriptive name (max 80 chars)\ndate: Event date(s)\nday_of_week: For verification\ntime: Start/end times (default: 9 AM - 5 PM)\nis_multi_day: Whether it spans multiple days\nis_recurring: Whether it repeats (and pattern)\nconfidence: high/medium/low\nurls: Any URLs found in the email (REQUIRED - always look for registration links, info pages, ticketing sites, etc.)\ndeadline_date: RSVP/registration/ticket deadline date (if found)\ndeadline_action: What user needs to do (e.g., \"RSVP\", \"get tickets\", \"register\")\ndeadline_url: Direct link for taking action (often same as event URL)\n\nURL Extraction Rule: ALWAYS scan the email for URLs and include the most relevant one at the BEGINNING of the event description."
      },
      {
        "title": "2.1 Deadline Detection",
        "body": "Scan the email for deadline patterns that indicate action is required before the event:\n\nCommon Deadline Patterns:\n\n\"RSVP by [date]\", \"Please RSVP by [date]\"\n\"Register by [date]\", \"Registration closes [date]\"\n\"Tickets available until [date]\", \"Get tickets by [date]\"\n\"Early bird ends [date]\", \"Early registration deadline [date]\"\n\"Must respond by [date]\", \"Respond by [date]\"\n\"Sign up by [date]\", \"Sign up deadline [date]\"\n\"Deadline: [date]\", \"Due by [date]\"\n\"Last day to [action]: [date]\"\n\nWhen a deadline is found:\n\nExtract the deadline date\nDetermine the required action (RSVP, register, buy tickets, etc.)\nFind the URL for taking that action\nFlag the event for special handling (see sections below)"
      },
      {
        "title": "3. Present Items to User and WAIT",
        "body": "Apply event rules, then present with numbered selection:\n\nI found the following potential events:\n\n1. ~~ELAC Meeting (Feb 2, Monday at 8:15 AM)~~ - SKIP (matches ignore pattern)\n2. **Team Offsite (Feb 2-6, Sun-Thu)** - PENDING\n3. **Staff Development Day (Feb 12, Wednesday)** - AUTO-CREATE\n\nReply with numbers to create (e.g., '2, 3'), 'all', or 'none'.\n\nSTOP AND WAIT for user response.\n\nAfter presenting, record pending invites for follow-up reminders:\n\n# Record pending invites using add_pending.sh\n\"$SCRIPTS_DIR/add_pending.sh\" \\\n    --email-id \"$EMAIL_ID\" \\\n    --email-subject \"$EMAIL_SUBJECT\" \\\n    --events-json '[{\"title\":\"Event Name\",\"date\":\"2026-02-15\",\"time\":\"14:00\",\"status\":\"pending\"}]'"
      },
      {
        "title": "4. Check for Duplicates (MANDATORY)",
        "body": "ALWAYS check before creating any event:\n\n# Step 1: Check local tracking first (fast)\nTRACKED=$(\"$SCRIPTS_DIR/lookup_event.sh\" --email-id \"$EMAIL_ID\")\nif [ \"$(echo \"$TRACKED\" | jq 'length')\" -gt 0 ]; then\n    EXISTING_EVENT_ID=$(echo \"$TRACKED\" | jq -r '.[0].event_id')\nfi\n\n# Step 2: If not found, try summary match\nif [ -z \"$EXISTING_EVENT_ID\" ]; then\n    TRACKED=$(\"$SCRIPTS_DIR/lookup_event.sh\" --summary \"$EVENT_TITLE\")\nfi\n\n# Step 3: Fall back to calendar search using wrapper script\nif [ -z \"$EXISTING_EVENT_ID\" ]; then\n    \"$SCRIPTS_DIR/calendar_search.sh\" --calendar-id \"$CALENDAR_ID\" --from \"${EVENT_DATE}T00:00:00\" --to \"${EVENT_DATE}T23:59:59\"\nfi\n\nUse LLM semantic matching for fuzzy duplicates (e.g., \"Team Offsite\" vs \"Team Offsite 5-6pm\")."
      },
      {
        "title": "5. Create or Update Calendar Events",
        "body": "Use create_event.sh (recommended) - handles date parsing, tracking, and changelog:\n\n# Create new event\n\"$SCRIPTS_DIR/create_event.sh\" \\\n    \"$CALENDAR_ID\" \\\n    \"Event Title\" \\\n    \"February 11, 2026\" \\\n    \"9:00 AM\" \\\n    \"5:00 PM\" \\\n    \"Description\" \\\n    \"$ATTENDEE_EMAILS\" \\\n    \"\" \\\n    \"$EMAIL_ID\"\n\n# Update existing event (pass event_id as 8th parameter)\n\"$SCRIPTS_DIR/create_event.sh\" \\\n    \"$CALENDAR_ID\" \\\n    \"Updated Title\" \\\n    \"February 11, 2026\" \\\n    \"10:00 AM\" \\\n    \"6:00 PM\" \\\n    \"Updated description\" \\\n    \"$ATTENDEE_EMAILS\" \\\n    \"$EXISTING_EVENT_ID\" \\\n    \"$EMAIL_ID\"\n\nFor direct gog commands and advanced options, see references/gog-commands.md."
      },
      {
        "title": "6. Email Disposition (Automatic)",
        "body": "Email disposition (mark as read and/or archive) is handled automatically by create_event.sh based on config settings. No manual step needed - emails are dispositioned after event creation.\n\nTo manually disposition an email:\n\n\"$SCRIPTS_DIR/disposition_email.sh\" --email-id \"$EMAIL_ID\"\n\nTo process calendar reply emails (accepts, declines, tentatives):\n\n\"$SCRIPTS_DIR/process_calendar_replies.sh\"           # Process all\n\"$SCRIPTS_DIR/process_calendar_replies.sh\" --dry-run # Preview only\n\n# End activity session\n\"$SCRIPTS_DIR/activity_log.sh\" end-session"
      },
      {
        "title": "Date/Time Handling",
        "body": "Single-day events: Default 9:00 AM - 5:00 PM\nMulti-day events (e.g., Feb 2-6): Use --rrule \"RRULE:FREQ=DAILY;COUNT=N\"\nEvents with specific times: Use exact time from email"
      },
      {
        "title": "Event Descriptions",
        "body": "Format event descriptions in this order:\n\nACTION WARNING (if deadline exists):\n*** ACTION REQUIRED: [ACTION] BY [DATE] ***\n\n\n\nEvent Link (if URL found):\nEvent Link: [URL]\n\n\n\nEvent Details: Information extracted from the email\n\nExample WITH deadline:\n\n*** ACTION REQUIRED: GET TICKETS BY FEB 15 ***\n\nEvent Link: https://example.com/tickets\n\nSpring Concert at Downtown Theater\nDoors open at 7 PM\nVIP meet & greet available\n\nExample WITHOUT deadline:\n\nEvent Link: https://example.com/event\n\nSpring Concert at Downtown Theater\nDoors open at 7 PM"
      },
      {
        "title": "Duplicate Detection",
        "body": "Consider it a duplicate if:\n\nSame date AND similar title (semantic matching) AND overlapping time\n\nAlways update existing events rather than creating duplicates."
      },
      {
        "title": "Creating Deadline Events",
        "body": "When an event has a deadline (RSVP, registration, ticket purchase, etc.), create TWO calendar events:\n\n1. Main Event (as normal, but with warning in description):\n\n\"$SCRIPTS_DIR/create_event.sh\" \\\n    \"$CALENDAR_ID\" \\\n    \"Spring Concert\" \\\n    \"March 1, 2026\" \\\n    \"7:00 PM\" \\\n    \"10:00 PM\" \\\n    \"*** ACTION REQUIRED: GET TICKETS BY FEB 15 ***\n\nEvent Link: https://example.com/tickets\n\nSpring Concert at Downtown Theater\nDoors open at 7 PM\" \\\n    \"$ATTENDEE_EMAILS\" \\\n    \"\" \\\n    \"$EMAIL_ID\"\n\n2. Deadline Reminder Event (separate event on the deadline date):\n\n# Use create_event.sh for deadline reminders too (ensures tracking)\n\"$SCRIPTS_DIR/create_event.sh\" \\\n    \"$CALENDAR_ID\" \\\n    \"DEADLINE: Get tickets for Spring Concert\" \\\n    \"2026-02-15\" \\\n    \"09:00\" \\\n    \"09:30\" \\\n    \"Action required: Get tickets\n\nEvent Link: https://example.com/tickets\n\nMain event: Spring Concert on March 1, 2026\" \\\n    \"\" \\\n    \"\" \\\n    \"$EMAIL_ID\"\n\nDeadline Event Properties:\n\nTitle format: DEADLINE: [Action] for [Event Name]\nDate: The deadline date\nTime: 9:00 AM (30 minute duration)\nReminders: Email 1 day before + popup 1 hour before\nDescription: Action required, URL, reference to main event"
      },
      {
        "title": "Email Notifications for Deadlines",
        "body": "When creating events with deadlines, send a notification email to alert the user:\n\n# Load config\nCONFIG_FILE=\"$HOME/.config/email-to-calendar/config.json\"\nUSER_EMAIL=$(jq -r '.deadline_notifications.email_recipient // .gmail_account' \"$CONFIG_FILE\")\nNOTIFICATIONS_ENABLED=$(jq -r '.deadline_notifications.enabled // false' \"$CONFIG_FILE\")\n\n# Send notification if enabled (using wrapper script)\nif [ \"$NOTIFICATIONS_ENABLED\" = \"true\" ]; then\n    \"$SCRIPTS_DIR/email_send.sh\" \\\n        --to \"$USER_EMAIL\" \\\n        --subject \"ACTION REQUIRED: Get tickets for Spring Concert by Feb 15\" \\\n        --body \"A calendar event has been created that requires your action.\n\nEvent: Spring Concert\nDate: March 1, 2026\nDeadline: February 15, 2026\nAction Required: Get tickets\n\nLink: https://example.com/tickets\n\nCalendar events created:\n- Main event: Spring Concert (March 1)\n- Deadline reminder: DEADLINE: Get tickets for Spring Concert (Feb 15)\n\n---\nThis notification was sent by the email-to-calendar skill.\"\nfi\n\nWhen to send notifications:\n\nOnly when deadline_notifications.enabled is true in config\nOnly for events that have action-required deadlines\nInclude the deadline date, action, URL, and event details"
      },
      {
        "title": "Activity Log",
        "body": "# Start session\n\"$SCRIPTS_DIR/activity_log.sh\" start-session\n\n# Log skipped emails\n\"$SCRIPTS_DIR/activity_log.sh\" log-skip --email-id \"abc\" --subject \"Newsletter\" --reason \"No events\"\n\n# Log events\n\"$SCRIPTS_DIR/activity_log.sh\" log-event --email-id \"def\" --title \"Meeting\" --action created\n\n# End session\n\"$SCRIPTS_DIR/activity_log.sh\" end-session\n\n# Show recent activity\n\"$SCRIPTS_DIR/activity_log.sh\" show --last 3"
      },
      {
        "title": "Changelog and Undo",
        "body": "Changes can be undone within 24 hours:\n\n# List recent changes\n\"$SCRIPTS_DIR/changelog.sh\" list --last 10\n\n# List undoable changes\n\"$SCRIPTS_DIR/undo.sh\" list\n\n# Undo most recent change\n\"$SCRIPTS_DIR/undo.sh\" last\n\n# Undo specific change\n\"$SCRIPTS_DIR/undo.sh\" --change-id \"chg_20260202_143000_001\""
      },
      {
        "title": "Pending Invites",
        "body": "Events not immediately actioned are tracked for reminders:\n\n# Add pending invites (after presenting events to user)\n\"$SCRIPTS_DIR/add_pending.sh\" \\\n    --email-id \"$EMAIL_ID\" \\\n    --email-subject \"Party Invite\" \\\n    --events-json '[{\"title\":\"Birthday Party\",\"date\":\"2026-02-15\",\"time\":\"14:00\",\"status\":\"pending\"}]'\n\n# List pending invites (JSON)\n\"$SCRIPTS_DIR/list_pending.sh\"\n\n# Human-readable summary\n\"$SCRIPTS_DIR/list_pending.sh\" --summary\n\n# Update reminder tracking\n\"$SCRIPTS_DIR/list_pending.sh\" --summary --update-reminded\n\n# Auto-dismiss after 3 ignored reminders\n\"$SCRIPTS_DIR/list_pending.sh\" --summary --auto-dismiss"
      },
      {
        "title": "Event Tracking",
        "body": "# Look up by email ID\n\"$SCRIPTS_DIR/lookup_event.sh\" --email-id \"19c1c86dcc389443\"\n\n# Look up by summary\n\"$SCRIPTS_DIR/lookup_event.sh\" --summary \"Staff Development\"\n\n# List all tracked events\n\"$SCRIPTS_DIR/lookup_event.sh\" --list\n\n# Validate events exist (removes orphans)\n\"$SCRIPTS_DIR/lookup_event.sh\" --email-id \"abc\" --validate"
      },
      {
        "title": "File Locations",
        "body": "FilePurpose~/.config/email-to-calendar/config.jsonUser configuration~/.openclaw/workspace/memory/email-extractions/Extracted data~/.openclaw/workspace/memory/email-extractions/index.jsonProcessing index~/.openclaw/workspace/memory/email-to-calendar/events.jsonEvent tracking~/.openclaw/workspace/memory/email-to-calendar/pending_invites.jsonPending invites~/.openclaw/workspace/memory/email-to-calendar/activity.jsonActivity log~/.openclaw/workspace/memory/email-to-calendar/changelog.jsonChange history~/.openclaw/workspace/skills/email-to-calendar/scripts/Utility scripts~/.openclaw/workspace/skills/email-to-calendar/MEMORY.mdUser preferences"
      },
      {
        "title": "References",
        "body": "Setup Guide: SETUP.md - Configuration and onboarding\nCLI Reference: references/gog-commands.md - Detailed gog CLI usage\nExtraction Patterns: references/extraction-patterns.md - Date/time parsing\nWorkflow Example: references/workflow-example.md - Complete example"
      },
      {
        "title": "Date Parsing",
        "body": "Handles common formats:\n\nJanuary 15, 2026, Wednesday January 15\n01/15/2026, 15/01/2026\nDate ranges like \"Feb 2-6\""
      },
      {
        "title": "Time Zones",
        "body": "All times assumed local timezone. Time zone info preserved in descriptions."
      }
    ],
    "body": "CRITICAL RULES - READ BEFORE PROCESSING ANY EMAIL\n\nNEVER CALL gog DIRECTLY - ALWAYS use wrapper scripts (create_event.sh, email_read.sh, etc.). Direct gog calls bypass tracking and cause duplicates. THIS IS NON-NEGOTIABLE.\nIGNORE CALENDAR NOTIFICATIONS - DO NOT process emails from calendar-notification@google.com (Accepted:, Declined:, Tentative:, etc.). These are responses to existing invites, NOT new events. Run process_calendar_replies.sh to archive them.\nALWAYS ASK BEFORE CREATING - Never create calendar events without explicit user confirmation in the current conversation\nCHECK IF ALREADY PROCESSED - Before processing any email, check processed_emails in index.json\nREAD CONFIG FIRST - Load and apply ignore_patterns and auto_create_patterns before presenting events\nREAD MEMORY.MD - Check for user preferences stored from previous sessions\nINCLUDE ALL CONFIGURED ATTENDEES - When creating/updating/deleting events, always include attendees from config with --attendees flag (and --send-updates all if supported)\nCHECK TRACKED EVENTS FIRST - Use lookup_event.sh --email-id to find existing events before calendar search (faster, more reliable)\nTRACK ALL CREATED EVENTS - The create_event.sh script automatically tracks events; use tracked IDs for updates/deletions\nSHOW DAY-OF-WEEK - Always include the day of week when presenting events for user verification\n\n⛔ FORBIDDEN: DO NOT USE gog COMMANDS DIRECTLY ⛔\n\nWRONG: gog calendar create ... or gog gmail ... RIGHT: \"$SCRIPTS_DIR/create_event.sh\" ... or \"$SCRIPTS_DIR/email_read.sh\" ...\n\nDirect CLI calls bypass event tracking, break duplicate detection, and cause duplicate events. ALL operations MUST go through the wrapper scripts in scripts/.\n\nEmail to Calendar Skill\n\nExtract calendar events and action items from emails, present them for review, and create/update calendar events with duplicate detection and undo support.\n\nFirst-time setup: See SETUP.md for configuration options and smart onboarding.\n\nReading Email Content\n\nIMPORTANT: Before you can extract events, you must read the email body. Use the wrapper scripts.\n\nSCRIPTS_DIR=\"$HOME/.openclaw/workspace/skills/email-to-calendar/scripts\"\n\n# Get a single email by ID (PREFERRED)\n\"$SCRIPTS_DIR/email_read.sh\" --email-id \"<messageId>\"\n\n# Search with body content included\n\"$SCRIPTS_DIR/email_search.sh\" --query \"in:inbox is:unread\" --max 20 --include-body\n\n\nNote on stale forwards: Don't use newer_than:1d because it checks the email's original date header, not when it was received. Process all UNREAD emails and rely on the \"already processed\" check.\n\nWorkflow\n0. Pre-Processing Checks (MANDATORY)\nSCRIPTS_DIR=\"$HOME/.openclaw/workspace/skills/email-to-calendar/scripts\"\nCONFIG_FILE=\"$HOME/.config/email-to-calendar/config.json\"\nINDEX_FILE=\"$HOME/.openclaw/workspace/memory/email-extractions/index.json\"\n\n# Start activity logging\n\"$SCRIPTS_DIR/activity_log.sh\" start-session\n\n# Check email mode\nEMAIL_MODE=$(jq -r '.email_mode // \"forwarded\"' \"$CONFIG_FILE\")\n\n# Check if email was already processed\nEMAIL_ID=\"<the email message ID>\"\nif jq -e \".extractions[] | select(.email_id == \\\"$EMAIL_ID\\\")\" \"$INDEX_FILE\" > /dev/null 2>&1; then\n    \"$SCRIPTS_DIR/activity_log.sh\" log-skip --email-id \"$EMAIL_ID\" --subject \"Subject\" --reason \"Already processed\"\n    exit 0\nfi\n\n# Load ignore/auto-create patterns\nIGNORE_PATTERNS=$(jq -r '.event_rules.ignore_patterns[]' \"$CONFIG_FILE\")\nAUTO_CREATE_PATTERNS=$(jq -r '.event_rules.auto_create_patterns[]' \"$CONFIG_FILE\")\n\n1. Find Emails to Process\n\nDIRECT mode: Scan all unread emails for event indicators (dates, times, meeting keywords).\n\nFORWARDED mode: Only process emails with forwarded indicators (Fwd:, forwarded message headers).\n\n2. Extract Events (Agent does this directly)\n\nRead the email and extract events as structured data. Include for each event:\n\ntitle: Descriptive name (max 80 chars)\ndate: Event date(s)\nday_of_week: For verification\ntime: Start/end times (default: 9 AM - 5 PM)\nis_multi_day: Whether it spans multiple days\nis_recurring: Whether it repeats (and pattern)\nconfidence: high/medium/low\nurls: Any URLs found in the email (REQUIRED - always look for registration links, info pages, ticketing sites, etc.)\ndeadline_date: RSVP/registration/ticket deadline date (if found)\ndeadline_action: What user needs to do (e.g., \"RSVP\", \"get tickets\", \"register\")\ndeadline_url: Direct link for taking action (often same as event URL)\n\nURL Extraction Rule: ALWAYS scan the email for URLs and include the most relevant one at the BEGINNING of the event description.\n\n2.1 Deadline Detection\n\nScan the email for deadline patterns that indicate action is required before the event:\n\nCommon Deadline Patterns:\n\n\"RSVP by [date]\", \"Please RSVP by [date]\"\n\"Register by [date]\", \"Registration closes [date]\"\n\"Tickets available until [date]\", \"Get tickets by [date]\"\n\"Early bird ends [date]\", \"Early registration deadline [date]\"\n\"Must respond by [date]\", \"Respond by [date]\"\n\"Sign up by [date]\", \"Sign up deadline [date]\"\n\"Deadline: [date]\", \"Due by [date]\"\n\"Last day to [action]: [date]\"\n\nWhen a deadline is found:\n\nExtract the deadline date\nDetermine the required action (RSVP, register, buy tickets, etc.)\nFind the URL for taking that action\nFlag the event for special handling (see sections below)\n3. Present Items to User and WAIT\n\nApply event rules, then present with numbered selection:\n\nI found the following potential events:\n\n1. ~~ELAC Meeting (Feb 2, Monday at 8:15 AM)~~ - SKIP (matches ignore pattern)\n2. **Team Offsite (Feb 2-6, Sun-Thu)** - PENDING\n3. **Staff Development Day (Feb 12, Wednesday)** - AUTO-CREATE\n\nReply with numbers to create (e.g., '2, 3'), 'all', or 'none'.\n\n\nSTOP AND WAIT for user response.\n\nAfter presenting, record pending invites for follow-up reminders:\n\n# Record pending invites using add_pending.sh\n\"$SCRIPTS_DIR/add_pending.sh\" \\\n    --email-id \"$EMAIL_ID\" \\\n    --email-subject \"$EMAIL_SUBJECT\" \\\n    --events-json '[{\"title\":\"Event Name\",\"date\":\"2026-02-15\",\"time\":\"14:00\",\"status\":\"pending\"}]'\n\n4. Check for Duplicates (MANDATORY)\n\nALWAYS check before creating any event:\n\n# Step 1: Check local tracking first (fast)\nTRACKED=$(\"$SCRIPTS_DIR/lookup_event.sh\" --email-id \"$EMAIL_ID\")\nif [ \"$(echo \"$TRACKED\" | jq 'length')\" -gt 0 ]; then\n    EXISTING_EVENT_ID=$(echo \"$TRACKED\" | jq -r '.[0].event_id')\nfi\n\n# Step 2: If not found, try summary match\nif [ -z \"$EXISTING_EVENT_ID\" ]; then\n    TRACKED=$(\"$SCRIPTS_DIR/lookup_event.sh\" --summary \"$EVENT_TITLE\")\nfi\n\n# Step 3: Fall back to calendar search using wrapper script\nif [ -z \"$EXISTING_EVENT_ID\" ]; then\n    \"$SCRIPTS_DIR/calendar_search.sh\" --calendar-id \"$CALENDAR_ID\" --from \"${EVENT_DATE}T00:00:00\" --to \"${EVENT_DATE}T23:59:59\"\nfi\n\n\nUse LLM semantic matching for fuzzy duplicates (e.g., \"Team Offsite\" vs \"Team Offsite 5-6pm\").\n\n5. Create or Update Calendar Events\n\nUse create_event.sh (recommended) - handles date parsing, tracking, and changelog:\n\n# Create new event\n\"$SCRIPTS_DIR/create_event.sh\" \\\n    \"$CALENDAR_ID\" \\\n    \"Event Title\" \\\n    \"February 11, 2026\" \\\n    \"9:00 AM\" \\\n    \"5:00 PM\" \\\n    \"Description\" \\\n    \"$ATTENDEE_EMAILS\" \\\n    \"\" \\\n    \"$EMAIL_ID\"\n\n# Update existing event (pass event_id as 8th parameter)\n\"$SCRIPTS_DIR/create_event.sh\" \\\n    \"$CALENDAR_ID\" \\\n    \"Updated Title\" \\\n    \"February 11, 2026\" \\\n    \"10:00 AM\" \\\n    \"6:00 PM\" \\\n    \"Updated description\" \\\n    \"$ATTENDEE_EMAILS\" \\\n    \"$EXISTING_EVENT_ID\" \\\n    \"$EMAIL_ID\"\n\n\nFor direct gog commands and advanced options, see references/gog-commands.md.\n\n6. Email Disposition (Automatic)\n\nEmail disposition (mark as read and/or archive) is handled automatically by create_event.sh based on config settings. No manual step needed - emails are dispositioned after event creation.\n\nTo manually disposition an email:\n\n\"$SCRIPTS_DIR/disposition_email.sh\" --email-id \"$EMAIL_ID\"\n\n\nTo process calendar reply emails (accepts, declines, tentatives):\n\n\"$SCRIPTS_DIR/process_calendar_replies.sh\"           # Process all\n\"$SCRIPTS_DIR/process_calendar_replies.sh\" --dry-run # Preview only\n\n# End activity session\n\"$SCRIPTS_DIR/activity_log.sh\" end-session\n\nEvent Creation Rules\nDate/Time Handling\nSingle-day events: Default 9:00 AM - 5:00 PM\nMulti-day events (e.g., Feb 2-6): Use --rrule \"RRULE:FREQ=DAILY;COUNT=N\"\nEvents with specific times: Use exact time from email\nEvent Descriptions\n\nFormat event descriptions in this order:\n\nACTION WARNING (if deadline exists):\n\n*** ACTION REQUIRED: [ACTION] BY [DATE] ***\n\n\nEvent Link (if URL found):\n\nEvent Link: [URL]\n\n\nEvent Details: Information extracted from the email\n\nExample WITH deadline:\n\n*** ACTION REQUIRED: GET TICKETS BY FEB 15 ***\n\nEvent Link: https://example.com/tickets\n\nSpring Concert at Downtown Theater\nDoors open at 7 PM\nVIP meet & greet available\n\n\nExample WITHOUT deadline:\n\nEvent Link: https://example.com/event\n\nSpring Concert at Downtown Theater\nDoors open at 7 PM\n\nDuplicate Detection\n\nConsider it a duplicate if:\n\nSame date AND similar title (semantic matching) AND overlapping time\n\nAlways update existing events rather than creating duplicates.\n\nCreating Deadline Events\n\nWhen an event has a deadline (RSVP, registration, ticket purchase, etc.), create TWO calendar events:\n\n1. Main Event (as normal, but with warning in description):\n\n\"$SCRIPTS_DIR/create_event.sh\" \\\n    \"$CALENDAR_ID\" \\\n    \"Spring Concert\" \\\n    \"March 1, 2026\" \\\n    \"7:00 PM\" \\\n    \"10:00 PM\" \\\n    \"*** ACTION REQUIRED: GET TICKETS BY FEB 15 ***\n\nEvent Link: https://example.com/tickets\n\nSpring Concert at Downtown Theater\nDoors open at 7 PM\" \\\n    \"$ATTENDEE_EMAILS\" \\\n    \"\" \\\n    \"$EMAIL_ID\"\n\n\n2. Deadline Reminder Event (separate event on the deadline date):\n\n# Use create_event.sh for deadline reminders too (ensures tracking)\n\"$SCRIPTS_DIR/create_event.sh\" \\\n    \"$CALENDAR_ID\" \\\n    \"DEADLINE: Get tickets for Spring Concert\" \\\n    \"2026-02-15\" \\\n    \"09:00\" \\\n    \"09:30\" \\\n    \"Action required: Get tickets\n\nEvent Link: https://example.com/tickets\n\nMain event: Spring Concert on March 1, 2026\" \\\n    \"\" \\\n    \"\" \\\n    \"$EMAIL_ID\"\n\n\nDeadline Event Properties:\n\nTitle format: DEADLINE: [Action] for [Event Name]\nDate: The deadline date\nTime: 9:00 AM (30 minute duration)\nReminders: Email 1 day before + popup 1 hour before\nDescription: Action required, URL, reference to main event\nEmail Notifications for Deadlines\n\nWhen creating events with deadlines, send a notification email to alert the user:\n\n# Load config\nCONFIG_FILE=\"$HOME/.config/email-to-calendar/config.json\"\nUSER_EMAIL=$(jq -r '.deadline_notifications.email_recipient // .gmail_account' \"$CONFIG_FILE\")\nNOTIFICATIONS_ENABLED=$(jq -r '.deadline_notifications.enabled // false' \"$CONFIG_FILE\")\n\n# Send notification if enabled (using wrapper script)\nif [ \"$NOTIFICATIONS_ENABLED\" = \"true\" ]; then\n    \"$SCRIPTS_DIR/email_send.sh\" \\\n        --to \"$USER_EMAIL\" \\\n        --subject \"ACTION REQUIRED: Get tickets for Spring Concert by Feb 15\" \\\n        --body \"A calendar event has been created that requires your action.\n\nEvent: Spring Concert\nDate: March 1, 2026\nDeadline: February 15, 2026\nAction Required: Get tickets\n\nLink: https://example.com/tickets\n\nCalendar events created:\n- Main event: Spring Concert (March 1)\n- Deadline reminder: DEADLINE: Get tickets for Spring Concert (Feb 15)\n\n---\nThis notification was sent by the email-to-calendar skill.\"\nfi\n\n\nWhen to send notifications:\n\nOnly when deadline_notifications.enabled is true in config\nOnly for events that have action-required deadlines\nInclude the deadline date, action, URL, and event details\nActivity Log\n# Start session\n\"$SCRIPTS_DIR/activity_log.sh\" start-session\n\n# Log skipped emails\n\"$SCRIPTS_DIR/activity_log.sh\" log-skip --email-id \"abc\" --subject \"Newsletter\" --reason \"No events\"\n\n# Log events\n\"$SCRIPTS_DIR/activity_log.sh\" log-event --email-id \"def\" --title \"Meeting\" --action created\n\n# End session\n\"$SCRIPTS_DIR/activity_log.sh\" end-session\n\n# Show recent activity\n\"$SCRIPTS_DIR/activity_log.sh\" show --last 3\n\nChangelog and Undo\n\nChanges can be undone within 24 hours:\n\n# List recent changes\n\"$SCRIPTS_DIR/changelog.sh\" list --last 10\n\n# List undoable changes\n\"$SCRIPTS_DIR/undo.sh\" list\n\n# Undo most recent change\n\"$SCRIPTS_DIR/undo.sh\" last\n\n# Undo specific change\n\"$SCRIPTS_DIR/undo.sh\" --change-id \"chg_20260202_143000_001\"\n\nPending Invites\n\nEvents not immediately actioned are tracked for reminders:\n\n# Add pending invites (after presenting events to user)\n\"$SCRIPTS_DIR/add_pending.sh\" \\\n    --email-id \"$EMAIL_ID\" \\\n    --email-subject \"Party Invite\" \\\n    --events-json '[{\"title\":\"Birthday Party\",\"date\":\"2026-02-15\",\"time\":\"14:00\",\"status\":\"pending\"}]'\n\n# List pending invites (JSON)\n\"$SCRIPTS_DIR/list_pending.sh\"\n\n# Human-readable summary\n\"$SCRIPTS_DIR/list_pending.sh\" --summary\n\n# Update reminder tracking\n\"$SCRIPTS_DIR/list_pending.sh\" --summary --update-reminded\n\n# Auto-dismiss after 3 ignored reminders\n\"$SCRIPTS_DIR/list_pending.sh\" --summary --auto-dismiss\n\nEvent Tracking\n# Look up by email ID\n\"$SCRIPTS_DIR/lookup_event.sh\" --email-id \"19c1c86dcc389443\"\n\n# Look up by summary\n\"$SCRIPTS_DIR/lookup_event.sh\" --summary \"Staff Development\"\n\n# List all tracked events\n\"$SCRIPTS_DIR/lookup_event.sh\" --list\n\n# Validate events exist (removes orphans)\n\"$SCRIPTS_DIR/lookup_event.sh\" --email-id \"abc\" --validate\n\nFile Locations\nFile\tPurpose\n~/.config/email-to-calendar/config.json\tUser configuration\n~/.openclaw/workspace/memory/email-extractions/\tExtracted data\n~/.openclaw/workspace/memory/email-extractions/index.json\tProcessing index\n~/.openclaw/workspace/memory/email-to-calendar/events.json\tEvent tracking\n~/.openclaw/workspace/memory/email-to-calendar/pending_invites.json\tPending invites\n~/.openclaw/workspace/memory/email-to-calendar/activity.json\tActivity log\n~/.openclaw/workspace/memory/email-to-calendar/changelog.json\tChange history\n~/.openclaw/workspace/skills/email-to-calendar/scripts/\tUtility scripts\n~/.openclaw/workspace/skills/email-to-calendar/MEMORY.md\tUser preferences\nReferences\nSetup Guide: SETUP.md - Configuration and onboarding\nCLI Reference: references/gog-commands.md - Detailed gog CLI usage\nExtraction Patterns: references/extraction-patterns.md - Date/time parsing\nWorkflow Example: references/workflow-example.md - Complete example\nNotes\nDate Parsing\n\nHandles common formats:\n\nJanuary 15, 2026, Wednesday January 15\n01/15/2026, 15/01/2026\nDate ranges like \"Feb 2-6\"\nTime Zones\n\nAll times assumed local timezone. Time zone info preserved in descriptions."
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/tonimelisma/email-to-calendar",
    "publisherUrl": "https://clawhub.ai/tonimelisma/email-to-calendar",
    "owner": "tonimelisma",
    "version": "1.13.1",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/email-to-calendar",
    "downloadUrl": "https://openagent3.xyz/downloads/email-to-calendar",
    "agentUrl": "https://openagent3.xyz/skills/email-to-calendar/agent",
    "manifestUrl": "https://openagent3.xyz/skills/email-to-calendar/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/email-to-calendar/agent.md"
  }
}