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
- Bootstrap – Checks for
pywin32
&pyttsx3
(installs if missing). - Connect – Opens Outlook via COM and pulls calendar items for the chosen date range.
- Filter – Drops holidays, birthdays and other noise.
- Rewrite – Converts
09:00
→9 AM
; adds natural connectors (then, after that). - Speak – Feeds the summary to
pyttsx3
at ~150 wpm.
Detailed Walk‑through of the Script
- Kick‑off (
main
) – Parses--tomorrow
and--silent
; bad flags triggerargparse
usage and exit. - Bootstrap dependencies (
ensure_deps
) – Tries importingpywin32
&pyttsx3
; missing libs are installed viasubprocess.check_call
. Any pip failure exits with “Run as admin”. - Open Outlook (
connect_outlook
) –win32com.client.Dispatch("Outlook.Application")
attaches/launches Outlook. If Outlook can’t start, apywintypes.com_error
is caught and the script bails. - Grab the Calendar – Fetches the default Calendar (MAPIFolder 9) and applies a MAPI
Restrict
for today (plus a day if--tomorrow
). - Collect items (
fetch_items
) – Iterates restricted appointments and yields Subject, Start, End, Categories, AllDayEvent. - Filter noise (
is_noise
) – Skips items whose category is inskip_categories
or are all‑day; logs each skip. - Normalise data (
clean_events
) – Converts COM datetimes to timezone‑aware Pythondatetime
objects usingpytz
; outputs plain dictionaries. - Generate text (
summarise
) – Builds a deterministic paragraph: 12‑hour times plus connectors (then, after that, finally). - Speak it (
speak
) – Unless--silent
, feeds text topyttsx3
(voice = Microsoft David Desktop, rate = 150, volume = 0.9). - 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.