DEV Community

Cover image for CouponAI: Turn Promotional Emails into Smart Savings
Utkarsh212
Utkarsh212

Posted on

CouponAI: Turn Promotional Emails into Smart Savings

This is a submission for the Postmark Challenge: Inbox Innovators.

What I Built

I built CouponAI, a server-side application that automates the extraction of promotional offers, deals, and coupons from your inbox using Postmark’s inbound email parsing feature.

Many of us receive dozens of marketing and promotional emails every day from services like Swiggy, Zomato, Uber, Ola, e-commerce brands, and more. While these emails often contain valuable discounts and promo codes, they’re easy to miss or forget when we actually need them.

CouponAI solves this problem by allowing users to automatically forward promotional emails to a custom inbound server email address for parsing (powered by Postmark). From there, the parsed emails are processed with the help of a local LLM (Large Language Model) to extract structured information like:

  • The company or brand
  • Offer
  • Offer description
  • Expiry date
  • Category (e.g., food, travel, shopping)

This data is then stored in a MongoDB database and can be retrieved via a simple frontend interface, helping users quickly check which discounts are available to them before making purchases or placing orders.

You can now retrieve all usable offers from a single endpoint and never miss a discount again!!

Demo

You can watch CouponAI demo here
CouponAI

As this project depends on a locally hosted Large Language Model (LLM) to process parsed email data — which would be costly to deploy in the cloud — it is currently not live.

However, you can run and test it on your local machine by following a few simple steps outlined below:

How to Run and Test Locally

You can try this project on your local machine by following these steps:

  1. Clone the Repository and Install dependencies

    git clone https://github.com/Utkarsh212/CouponAI.git
    cd CouponAI
    npm install
    
  2. Install and Run Ollama

    • You can download it from here
    • I have used gemma3:4b you can choose any suitable model as per your needs.
    ollama run <YOUR_MODEL_NAME>
    
  3. Configure Environment Variables
    Update config.env with the following variables:

    PORT=5000
    MODEL=YOUR_MODEL_NAME // Add your model name here
    HOSTED_MODEL_URL=http://127.0.0.1:11434/api/chat
    DB_CONNECTION_URL=YOUR_DB_CONNECTION_STRING // Add your MongoDB connection string here
    
  4. Expose the App with ngrok

    • You can download Ngrok from here
    • Run your Express app (e.g., on port 5000)
    • Start ngrok to expose it:
    ngrok http 5000
    
  5. Configure Ngrok URL over Postmark

    • Add ngrok URL to your server’s inbound webhook URL field on Postmark portal. Postmark portal config
  6. Forward a Test Email

    • From any email account, forward promotional email to the Postmark inbound server email address.
    • Postmark will parse it and send the content to your server’s inbound webhook URL.
  7. See Results

    • Open the index.html file to view the results.
    • You'll see a list of all promotional emails along with their details.
    • Alternatively, you can access the Ngrok URL directly to view all the extracted offers in JOSN.

Results

Here are example of an email that were forwarded to the inbound server:
Example Email

Corresponding Output from LLM:

The parsed and structured JSON results:

{
  "company": "Zomato",
  "offer": "Up to 50% off on your favourite treats",
  "details": "Just code ZOMATO while ordering online.",
  "expiry": null,
  "category": "Food"
}
Enter fullscreen mode Exit fullscreen mode

Code Repository

GitHub: github.com/Utkarsh212/CouponAI

How I Built It

The application is powered by a Node.js + Express backend, a locally running LLM model via Ollama, and Postmark’s inbound email parsing feature to automate the extraction of useful promotional data from email content.

Tech Stack

  • Backend: Node.js + Express
  • LLM: gemma3:4b model running locally via Ollama
  • Database: MongoDB
  • Email Parsing: Postmark Inbound Stream
  • Development Tools: Ngrok (for exposing localhost), dotenv, axios

Architecture Overview

Below is the architecture diagram that illustrates the complete flow — from the moment a email is forwarded, to how it gets parsed, processed by an LLM, and stored in the database.

CouponAI Architecture Diagram


Flow & Architecture

  1. Inbound Email Forwarding:
    Users set up forwarding from their personal email accounts to a Postmark-provided inbound email address.

  2. Postmark Webhook Integration:
    Postmark parses the email and sends structured email data (subject, text body, HTML body, etc.) to a webhook on my Express server.

  3. Email Parsing & LLM Processing:
    The server cleans the raw email content and generates a prompt, which is then sent to a locally running LLM (gemma3:4b). The LLM returns result which is then parsed into a JSON object with the following fields:

-   `company`: Brand or service name
-   `offer`: Promo description
-   `details`: Additional details about the offer
-   `expiry`: Validity date if mentioned
-   `category`: Context (e.g., food, shopping)
Enter fullscreen mode Exit fullscreen mode
  1. Storage & Retrieval:
    The structured offer data is saved in a MongoDB collection and can be retrieved via a public API route.

  2. Frontend (Optional):
    For simplicity, I created a minimal HTML page that displays the available coupons pulled from the backend API.


Experience with Postmark

This was my first time working with Postmark’s inbound email stream feature — and it was a smooth experience. Setting up the inbound stream, getting the parsing to work, and configuring the webhook was very straightforward. I was especially impressed with how detailed and clean the parsed JSON format is out-of-the-box.

Top comments (8)

Collapse
 
riyank786 profile image
Riyank786

Fantastic work, Utkarsh! CouponAI is such a clever and practical solution, turning cluttered promotional emails into curated, smart savings is a game-changer. As someone who often misses out on deals buried in my inbox, this feels incredibly useful. I especially love the idea of automation doing the heavy lifting here.

One suggestion: adding filters for deal amount or specific categories could make the experience even more personalized.
Also, curious if you’re planning to integrate cashback or loyalty reward tracking in the future? That could take it to the next level.

Keep up the amazing work, this is a brilliant example of applying AI to real-life pain points!

Collapse
 
jineshnagori profile image
Jinesh Nagori

@riyank786 totally agree that personalization through filters like deal value or category could enhance user experience significantly. Integrating cashback or loyalty rewards is a fascinating direction too; coupling that with smart tagging and user preferences might open up even deeper savings automation.

Collapse
 
jineshnagori profile image
Jinesh Nagori

This is a genuinely innovative use of Postmark’s inbound capabilities. The idea of combining LLMs with automated email parsing bridges a real-world gap most people overlook—lost value in promo emails. I appreciate how the architecture is modular and extensible, especially with Ollama running locally to reduce cloud overhead. Curious to see how this could scale with multi-user support and deduplication logic. Great work!

Collapse
 
dotallio profile image
Dotallio

This is honestly super useful, I always lose track of those promo codes. How accurate is the LLM when the promo emails are messy or really unstructured?

Collapse
 
utkarsh212 profile image
Utkarsh212

Thanks a lot @dotallio ! 😊 I’m glad you found it useful!

The accuracy of the LLM depends on two key factors:

  1. The quality of the prompt (how well it’s structured to guide the model).
  2. The model size you use.

I tried a few models during development:

  1. deepseek-r1:1.5b-qwen-distill-q4_K_M: Small and fast, but accuracy was only about 50%.
  2. deepseek-r1:1.5b-qwen-distill-fp16: Larger and more accurate, but the response time was slower.
  3. gemma-3:4b: This gave about 75% accuracy. After tweaking the prompt, I got it up to around 80-85%.

One thing to note: I also tested even larger models, but their response time was much slower on my machine, so I had to drop them. It really depends on your hardware, if you have a powerful machine, you could go for a bigger model for better accuracy, but it’ll take more time.

Hope this clears it up! Let me know if you need any more info.

Collapse
 
alcadeus0 profile image
Aazam Thakur

Amazing and Innovative Idea!

Collapse
 
nathan_tarbert profile image
Nathan Tarbert

Pretty cool, I always forget about the promo emails until it's too late - this kinda thing is actually clutch.

Collapse
 
hemendra_shekhawat profile image
Hemendra Shekhawat

Great work, will be using this once in a while I guess, thanks.

Some comments may only be visible to logged-in visitors. Sign in to view all comments.