Inspiration
Gmail is great at filtering spam but terrible at answering the real question job-seekers ask dozens of times a day: “Where am I in every single hiring pipeline right now?” We wanted a lightweight, AI-powered overlay that answers that instantly without exporting mail to another SaaS, and without making recruiters do anything different.
What it does
- Real-time pill labels – Each conversation row in Gmail gets a colored badge (Applied, Next Round, Interview/Meet, Job Notification, Rejection, Not Important).
- Always-on classification – Scroll, paginate, search, open “Starred”… the extension keeps tagging new rows.
- Live dashboard popup – A one-click Chrome-action shows a bar chart of counts, deduplicated by message-ID, so the numbers stay stable across views.
- Edge-friendly – All inference happens via a tiny FastAPI endpoint you can self-host; no mail data ever reaches a central server.
How we built it
- Frontend – Chrome Manifest V3 extension written in vanilla ES2022. Uses MutationObserver + IntersectionObserver for minimal DOM churn, Chart.js (v4 UMD) for the popup.
- Backend – 30-line FastAPI app wrapped around openai==1.x. CORS headers wide-open so the extension can POST from the browser.
- Queueing – A 2-slot promise queue in openai.js throttles requests to stay under rate limits and retries w/ back-off.
- State – chrome.storage.local holds (a) global category counts and (b) a bloom-like object of message-IDs to ensure we never double-count even when Gmail re-hydrates DOM rows.
Challenges we ran into
- Gmail DOM churn – The row elements are recycled while scrolling, so we had to dedup on both DOM-node (WeakSet) and message-ID.
- CSP & external libs – Manifest V3 disallows from CDNs inside the popup. We solved this by bundling the Chart.js UMD build locally and setting "web_accessible_resources".</li> <li>OpenAI Python migration – The new openai 1.x client broke our first draft; we refactored to the new openai.OpenAI() syntax and asyncio-safe pattern.</li> </ol> <h2 id="accomplishments-that-we-re-proud-of">Accomplishments that we’re proud of</h2> <ol> <li>< 150 KB total (including Chart.js) yet works across all Gmail views.</li> <li>Stateless backend – spin it up on Replit, Fly, or Cloud Run with zero config.</li> <li>Smooth UX – badges fade in exactly where Gmail’s own “Inbox” pill lives, matching colors to Google’s Material palette.</li> </ol> <h2 id="what-we-learned">What we learned</h2> <ol> <li>How to tame Gmail’s ever-changing shadow-DOM without a heavyweight framework.</li> <li>Best practices for Chrome MV3 service-worker lifecycles and message-passing.</li> <li>Practical strategies for client-side rate-limiting OpenAI calls and caching results.</li> </ol>
Log in or sign up for Devpost to join the conversation.