Germán Tarnoski Logo
Germán Tarnoski
GENMailHackITBA 2023 Finalist
← Projects

Case Study · 2023

GENMail

HackITBA 2023 Finalist

Built in 36 hours at HackITBA 2023, a hackathon hosted by ITBA, one of the most prestigious engineering universities in Argentina. A personal news feed for your university inbox: filtered and prioritized by rules you set, summarized by GPT-3.5. A three-person team from Information Systems Engineering, with me leading. We finished as finalists.

36hBuild time
3Team size
FinalistHackITBA 2023

Theme and AI context

The hackathon theme was Automation: build something useful with AI that automates a real process. Talking to other students at the event, and drawing from our own experience at university, the problem surfaced quickly. Universities in Argentina send a relentless stream of institutional email. Cancelled exams, rescheduled dates, company visit invitations, inscription deadlines, faculty announcements. Students receive dozens per week and miss half of them because nothing tells you what matters.

As we built the app and layered in customization (keyword filters, priority ordering, configurable time windows), it became more than a summarizer. By the end, we were calling it a personal news feed for your inbox: you define what's relevant, it surfaces at the top; you mark what you don't care about, it never shows up.

At the time, LLMs were proving themselves at text tasks but weren't reliable enough for open-ended judgment calls. Email summarization was a natural fit: text in, text out, with the curation logic driven by user-defined rules rather than left to the model.

36 Hours

The pivot

We chose Gmail from the start: one OAuth flow would handle both login and inbox access, and it's what most students in Argentina use for university. The problem was we couldn't get the OAuth flow to complete reliably, and we were burning time on it. I made the call to pivot: route everything through Telegram instead. Users would authenticate through a bot and receive summaries in chat. We built it, but the problem was that the Telegram bot API is fragile under fast-iteration conditions: webhook behavior was inconsistent and we didn't have runway to stabilize it. Additionally, the flow of sending credentials over Telegram didn't feel right. A few hours in I called the second pivot: back to Gmail OAuth. We got it working, scrapped Telegram entirely, and built a web UI on Django. The pivot cost time, but it was the right call.

Leading the team

I split the work across the three of us, proposed the tools and architecture, debugged blockers when they appeared, and paired with teammates when they got stuck. When nobody was sure which direction to take, they asked me. None of us had worked with OAuth or the Gmail API before, and we were learning while building with no time to absorb mistakes. The job was to make sure the team was always working on the right thing.

GENMail

The output

From raw inbox to a ranked, summarized digest.

Users authorize via Google OAuth 2.0, which handles token refresh automatically. The app fetches emails from the IMPORTANT label through the Gmail API, parses the MIME structure, base64-decodes the bodies, and strips HTML before anything reaches the summarization step. Passing raw email content to the model would have included noise like unsubscribe footers, formatting markup, and quoted reply chains, which had to be removed beforehand to avoid wasting tokens.

Each surviving email is passed to GPT-3.5 with a structured prompt that produces a first-person narrative summary in Spanish, addressed to the user by name, something like: "Germán, UCEMA is letting you know that enrollment for the second semester closes on Friday." Users choose the time window for their digest: 24 hours, 3 days, or 1 week. Each summary links back to the original thread in Gmail.

GENMail digest — ranked and summarized email feed
The digest: prioritized, summarized, linked back to Gmail
GENMail settings — priority keywords and exclusion filters
Settings: define priority keywords and exclusion filters. The "Generated related words" checkbox triggers AI keyword expansion via GPT-3.5.

Keyword exclusion filters: Users define a comma-separated list of terms. Any email whose body, subject, or sender matches a term is dropped before summarization. Sender matching is handled separately: a term containing @ is checked against the sender address rather than the body, so users can exclude an entire sender without false positives from body text. The filters are verbatim: fast, predictable, and not dependent on the model.

Priority ordering: A second keyword list reorders the surviving emails by relevance. Emails matching higher-priority terms float to the top of the digest. The output is sorted by what the user told the app they care about, not by arrival time. A user interested in everything about excursions or company visits sees those first, regardless of when they arrived.

AI keyword expansion:For users who don't want to enumerate every synonym manually, a button on the settings page sends each keyword to GPT-3.5 and returns related terms. "Excursion, visit" might expand to "excursion, visit, trip, daytrip," catching relevant emails the original terms wouldn't have matched. Expansions are deduplicated before saving, and the feature is optional: the base filters work fine without it.

Decisions and working around AI limitations

Verbatim filters, not model-driven ones

We had GPT-3.5 available for everything, but we didn't use it to decide which emails to include or exclude. Verbatim keyword matching is fast, deterministic, and debuggable. An exclusion filter that works by text match will never suppress an email because the model misread the intent. The AI layer was reserved for summarization (where generative output is the point) and for optional keyword expansion, where the model's role is assistive rather than gatekeeping.

The prompt as a debugging log

Getting GPT-3.5 to produce clean, parseable output in Spanish took more work than the rest of the summarization logic combined. The model summarized from the sender's perspective, pulled in unsubscribe links, translated rather than summarized, and defaulted to English even when asked for Spanish. Every "do not" or "it is essential" in the final prompt maps to a specific failure we observed and patched. The system prompt basically shows the debugging history.

Finalists

Finalist, and a call that didn't hold

The judges rated GENMail a finalist and responded well to the demo. Their main criticism was the hard limitation they saw in the concept: most people wouldn't trust an AI application with full access to their email inbox.

Their criticism was reasonable at the time. However, a couple of years later, people are giving AI agents access to their inboxes, Slack, calendars, their entire desktops and even IoT devices at home.

Tools Used

PythonDjangoSQLiteGoogle OAuth 2.0Gmail APIOpenAI GPT-3.5Bootstrap
← Back to Projects