Email to Calendar Extraction Engine
by @1kalin
Extract calendar events, deadlines, action items, and follow-ups from emails. Works with any calendar provider (Google, Outlook, Apple, Notion, etc.). No external dependencies β pure agent intelligence. Use when the user forwards an email, asks to check inbox for events, or wants to extract structured scheduling data from any text.
clawhub install afrexai-email-to-calendarπ About This Skill
name: afrexai-email-to-calendar version: 1.0.0 description: > Extract calendar events, deadlines, action items, and follow-ups from emails. Works with any calendar provider (Google, Outlook, Apple, Notion, etc.). No external dependencies β pure agent intelligence. Use when the user forwards an email, asks to check inbox for events, or wants to extract structured scheduling data from any text.
Email β Calendar Extraction Engine
Turn emails into structured calendar events with zero missed deadlines.
Quick Start
When you receive an email (forwarded, pasted, or from inbox):
1. Parse β Extract every time-relevant item using the framework below 2. Classify β Score each item by type and confidence 3. Present β Show structured results with numbered selection 4. Create β Use the user's calendar tool to create confirmed events 5. Follow up β Track deadlines and send reminders
1. Extraction Framework
What to Look For
Scan every email for ALL of these categories:
| Category | Signals | Priority | |----------|---------|----------| | Hard Events | "meeting at", "call on", "event on", specific date+time | π΄ High | | Deadlines | "due by", "submit before", "RSVP by", "register by", "expires" | π΄ High | | Soft Events | "sometime next week", "let's meet soon", "planning for March" | π‘ Medium | | Recurring | "every Monday", "weekly", "monthly", "standing meeting" | π‘ Medium | | Action Items | "please review", "can you send", "follow up on", "action required" | π‘ Medium | | Travel/Logistics | Flight numbers, hotel confirmations, check-in times, gate info | π΄ High | | Implicit Deadlines | Event is Feb 20 β ticket deadline is likely 1-2 weeks before | π‘ Medium |
Extraction Template
For each item found, extract:
- title: "Descriptive name (max 80 chars)"
type: event | deadline | action_item | travel | recurring
date: "YYYY-MM-DD"
day_of_week: "Monday" # Always include for verification
time_start: "14:00" # 24h format, default 09:00 if unclear
time_end: "15:00" # Default: start + 1h for meetings, all-day for deadlines
timezone: "America/New_York" # Extract from email headers or content
is_all_day: false
is_multi_day: false # If true, include end_date
end_date: null
recurrence: null # "weekly" | "biweekly" | "monthly" | "MWF" | custom RRULE
location: null # Physical address or video link
url: null # Registration link, event page, or action URL
attendees: [] # Names/emails mentioned
confidence: high | medium | low
source_quote: "exact text from email that indicates this event"
notes: "any context the user should know"
deadline_action: null # "RSVP" | "register" | "buy tickets" | "submit"
deadline_url: null # Direct link to take action
reminder_minutes: 30 # Suggested reminder (15 for calls, 60 for travel, 1440 for deadlines)
Confidence Scoring
| Confidence | Criteria | |------------|----------| | High | Explicit date + time + clear event type. E.g. "Meeting on Feb 15 at 2pm" | | Medium | Date but no time, or time but approximate date. E.g. "next Tuesday afternoon" | | Low | Vague reference. E.g. "we should catch up soon", "sometime in March" |
Smart Defaults
2. Email Classification
Before extracting, classify the email:
| Email Type | How to Handle | |------------|---------------| | Calendar notification (from calendar-notification@google.com, outlook, etc.) | SKIP β these are responses to existing events | | Newsletter/marketing | Extract only if contains relevant event dates | | Personal/work email | Full extraction | | Travel confirmation | Extract ALL logistics: flights, hotels, car rentals, check-ins | | Meeting invite (ICS attachment or structured invite) | Extract directly, high confidence | | Thread/reply | Only extract NEW events, not ones from quoted text | | Forwarded email | Process the forwarded content, note original sender |
Ignore Patterns (Skip These)
3. Presentation Format
Always present extracted items in this format:
π§ From: [sender] | Subject: [subject] | Date: [received date]Found [N] calendar items:
1. π΄ Team Standup β Mon Feb 17, 9:00-9:30 AM EST
π Zoom (link in email) | π₯ Alice, Bob, Charlie
π Recurring: Every weekday
β
Confidence: High
2. π΄ Project Deadline: Q1 Report β Fri Feb 28, EOD
β οΈ ACTION REQUIRED: Submit report
π Submission portal
β° Suggested reminder: 3 days before
β
Confidence: High
3. π‘ Team Lunch β "sometime next week"
π TBD
β οΈ Confidence: Medium β date needs confirmation
Reply with numbers to create (e.g. "1, 2"), "all", or "none".
Type "edit 3" to modify before creating.
Presentation Rules
1. Always show day of week β humans verify dates by day name 2. Group by date when >5 items 3. Flag conflicts β if new event overlaps existing calendar 4. Highlight deadlines with β οΈ and days remaining 5. Show source quote for medium/low confidence items 6. Never auto-create without user confirmation
4. Calendar Creation
After user confirms, create events using their calendar tool:
Google Calendar (via gog or API)
gog calendar create \
--title "Event Title" \
--start "2026-02-17T09:00:00-05:00" \
--end "2026-02-17T10:00:00-05:00" \
--description "Extracted from email: [subject]" \
--location "Zoom link or address"
Apple Calendar (via osascript)
osascript -e 'tell application "Calendar"
tell calendar "Work"
make new event with properties {summary:"Event Title", start date:date "Monday, February 17, 2026 at 9:00:00 AM", end date:date "Monday, February 17, 2026 at 10:00:00 AM", description:"Extracted from email", location:"Zoom"}
end tell
end tell'
Notion / Other
ICS Export (Universal)
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
DTSTART:20260217T090000
DTEND:20260217T100000
SUMMARY:Event Title
DESCRIPTION:Extracted from email
LOCATION:Zoom link
END:VEVENT
END:VCALENDAR
5. Duplicate Detection
Before creating any event, check for duplicates:
1. Search calendar for events on the same date with similar title (fuzzy match) 2. Check tracking file β maintain a log of created events:
// memory/email-calendar-log.json
{
"created_events": [
{
"email_id": "msg-123",
"email_subject": "Team Offsite",
"event_title": "Team Offsite",
"event_date": "2026-02-17",
"calendar_event_id": "cal-456",
"created_at": "2026-02-13T10:00:00Z"
}
]
}
3. If duplicate found: Show user and ask β "This looks similar to [existing event]. Skip, update, or create anyway?"
6. Deadline & Reminder Engine
Deadline Patterns to Detect
| Pattern | Example | Action | |---------|---------|--------| | RSVP deadline | "RSVP by Feb 10" | Create reminder 3 days before | | Registration | "Register by March 1" | Create reminder 1 week before | | Early bird | "Early bird ends Feb 15" | Create reminder 2 days before | | Ticket sales | "Tickets on sale until..." | Create reminder + calendar event | | Submission | "Submit proposal by..." | Create reminder 3 days before | | Expiration | "Offer expires..." | Create reminder 1 day before |
Reminder Strategy
7. Travel Email Handling
Travel confirmations get special treatment:
Extract ALL of these:
Create these calendar events:
1. Flight departure β include terminal, gate, flight # in description 2. Flight arrival β for connecting flights too 3. Hotel check-in β with address and confirmation # 4. Hotel check-out β with reminder to pack 5. Car pickup/dropoff β with location detailsTravel-specific reminders:
8. Batch Processing
When scanning an inbox for events:
1. Fetch unread emails (or emails from last N days) 2. Filter out noise β apply ignore patterns 3. Extract from each β run extraction framework 4. Deduplicate across emails β same event mentioned in multiple threads 5. Sort by date β nearest first 6. Present grouped summary:
π¬ Inbox Scan: 47 unread β 12 with calendar items β 18 events foundTHIS WEEK (Feb 13-19):
1. π΄ Sprint Review β Thu Feb 13, 3:00 PM
2. π΄ 1:1 with Manager β Fri Feb 14, 10:00 AM
...
NEXT WEEK (Feb 20-26):
5. π‘ Team Lunch β date TBD (mentioned in 2 emails)
...
DEADLINES:
β οΈ Q1 Report β Due Feb 28 (15 days) β Submit here
β οΈ Conference RSVP β Due Feb 20 (7 days) β RSVP
9. Edge Cases
| Situation | How to Handle | |-----------|---------------| | Multiple timezones in one email | Extract each event in its stated timezone, convert to user's TZ for display | | "TBD" or "TBA" times | Create all-day event, flag for follow-up | | Cancelled events | Check if already in calendar β offer to delete | | Rescheduled events | Find original β offer to update (not create new) | | Recurring with exceptions | Note specific exception dates in description | | Date ambiguity (02/03 = Feb 3 or Mar 2?) | Use email's locale/origin for MM/DD vs DD/MM, ask if unclear | | Events in quoted/forwarded text | Only process if user explicitly forwarded it | | Attachments with .ics files | Parse ICS directly β highest confidence source | | "Save the date" emails | Create tentative event, mark as placeholder | | Conference with multiple sessions | Extract all sessions as separate events with shared description |
10. Session Memory
Track user preferences across sessions:
# memory/email-calendar-prefs.yaml
default_timezone: "America/New_York"
default_calendar: "Work"
default_reminder_minutes: 30
auto_create_patterns:
- "standup"
- "1:1"
ignore_patterns:
- "newsletter"
- "marketing"
preferred_format: "12h" # or "24h"
travel_reminder_hours: 3
Update preferences when user corrects you or states a preference.
π‘ Examples
When you receive an email (forwarded, pasted, or from inbox):
1. Parse β Extract every time-relevant item using the framework below 2. Classify β Score each item by type and confidence 3. Present β Show structured results with numbered selection 4. Create β Use the user's calendar tool to create confirmed events 5. Follow up β Track deadlines and send reminders