Outlook Calendar Assistant

Daily Assistant while Silencing Outlook’s Chaos

Outlook reminders have a special talent for interrupting my first sip of coffee, popping up and then vanishing behind a maze of windows. One Saturday, fueled by caffeine and fresh irritation, I hacked together OutlookCal: a compact Python script that scrapes today’s (and, if you want, tomorrow’s) calendar, turns it into a short, human‑sounding summary, and speaks it aloud. No cloud services, no APIs just local code keeping Outlook honest.

Why Bother

  • Time is finite. If something wastes more than two minutes a day, it should be scripted into oblivion.
  • Audio beats pop‑ups. Hearing the plan while I hunt for socks is easier than chasing notifications across three monitors.
  • Everything stays local. Calendar data never leaves the laptop.

High‑Level Game Plan

High‑Level Flow diagram

  1. Bootstrap – Checks for pywin32 & pyttsx3 (installs if missing).
  2. Connect – Opens Outlook via COM and pulls calendar items for the chosen date range.
  3. Filter – Drops holidays, birthdays and other noise.
  4. Rewrite – Converts 09:00 → 9 AM; adds natural connectors (then, after that).
  5. Speak – Feeds the summary to pyttsx3 at ~150 wpm.

Detailed Walk‑through of the Script

Detailed Flow diagram

  1. Kick‑off (main) – Parses --tomorrow and --silent; bad flags trigger argparse usage and exit.
  2. Bootstrap dependencies (ensure_deps) – Tries importing pywin32 & pyttsx3; missing libs are installed via subprocess.check_call. Any pip failure exits with “Run as admin”.
  3. Open Outlook (connect_outlook)win32com.client.Dispatch("Outlook.Application") attaches/launches Outlook. If Outlook can’t start, a pywintypes.com_error is caught and the script bails.
  4. Grab the Calendar – Fetches the default Calendar (MAPIFolder 9) and applies a MAPI Restrict for today (plus a day if --tomorrow).
  5. Collect items (fetch_items) – Iterates restricted appointments and yields Subject, Start, End, Categories, AllDayEvent.
  6. Filter noise (is_noise) – Skips items whose category is in skip_categories or are all‑day; logs each skip.
  7. Normalise data (clean_events) – Converts COM datetimes to timezone‑aware Python datetime objects using pytz; outputs plain dictionaries.
  8. Generate text (summarise) – Builds a deterministic paragraph: 12‑hour times plus connectors (then, after that, finally).
  9. Speak it (speak) – Unless --silent, feeds text to pyttsx3 (voice = Microsoft David Desktop, rate = 150, volume = 0.9).
  10. Exit paths & logging – If no meetings survived filtering, prints and (unless silent) speaks “No meetings today. Enjoy the silence.”; always exits 0 so Task Scheduler stays happy.

Under the Bonnet

Component Purpose Notes
Dependency checker Installs missing libs Runs at start‑up
Outlook connector win32com.client MAPIFolder 9 = default Calendar
Event filter Skips holidays, birthdays, all‑day Edit skip_categories
Formatter 12‑hour times & paragraph Hard‑coded template
TTS engine pyttsx3 Offline; built‑in voices

The entire script is under 250 lines (including comments). Tweaking categories or voices is a two‑line edit.

Installation & First Run

# Windows only (COM ties us to Outlook)
cd %USERPROFILE%\code
git clone https://github.com/JacoMoolman/OulookCal.git
cd OulookCal
python daily_assistant.py    # add --tomorrow to include the next day

Sample Terminal Output

Here’s what you’ll see when the script runs:

🌅 Good morning! Starting your daily briefing...
============================================================
🔍 Checking required Python packages...
✅ pywin32 is already installed
✅ pyttsx3 is already installed
✅ All required packages are available!
🔊 Initializing text-to-speech...
👋 Hi there! I don't know your name yet.
What's your name? Sarah
✅ Nice to meet you, Sarah! I'll remember that.
📅 Reading LOCAL Outlook calendar...
📂 Looking in calendar: Calendar
📝 Creating your day summary...

1. 📅 Team Standup
   🕘 9:00 AM - 9:30 AM
   👤 Organizer: john.doe@company.com

2. 📅 Project Review Meeting
   🕚 11:00 AM - 12:00 PM
   👤 Organizer: jane.smith@company.com

3. 📅 Client Call - Q4 Planning
   🕐 2:00 PM - 3:30 PM
   👤 Organizer: mike.wilson@company.com

======================================================================
📝 DAY SUMMARY:
======================================================================
Good morning Sarah! You have 3 meetings today starting at 9 AM with Team Standup, followed by Project Review Meeting at 11 AM, then Client 
Call - Q4 Planning at 2 PM. It's a moderately busy day with some time for focused work between meetings.

======================================================================
✨ Have a great day! ✨
======================================================================

🔊 Reading your daily summary...

The LLM Detour

Originally I tried a local language model SMOLLM (≈ 15 million parameters, ~200 MB; see the
Hugging Face blog) to write the summary. Even with aggressive prompt‑engineering it added fluff, mangled times, or hallucinated meetings. I scrapped it in favor of a hard‑coded template: predictable output and a noticeably faster launch.

For Mac Users

Mac users should follow this link in order to setup the calendar script.

Final Thoughts

OutlookCal won’t change the world, but shaving a minute off every morning compounds quickly. If Outlook reminders drive you mad too, grab the code, break it, and tell me what hurts.

GitHub Repository

For those who would like to give this a try or automate it even further below is the link to all the code.