Narrative

Email Marketing — From Batch Blasts to Behavior-Triggered

batch, time-basedevent-triggeredcampaign type

Email campaigns were going out on fixed schedules to everyone, regardless of where users were in their journey or what actions they had taken. Engagement was low — the right message was not reaching people at the right time.

PythonSendGridAutomationAPI

What Was Broken

How It Was Built

The core shift was from time-based to event-based triggering.

Event-based trigger engine
  • Instead of send this email every Tuesday, the system listens for user actions — sign-up, product view, abandoned cart, first purchase — and triggers the appropriate email based on that event.
  • 📄 trigger_engine.py
SendGrid for deliverability — not raw SMTP
  • SMTP at scale is a reliability and deliverability problem.
Configurable rules — non-engineers can operate it
  • Marketing teams can adjust which events trigger which emails without touching code.

Event-based trigger engine

Instead of send this email every Tuesday, the system listens for user actions — sign-up, product view, abandoned cart, first purchase — and triggers the appropriate email based on that event. Built a lightweight event listener and rules engine mapping events to templates and delays.

trigger_engine.py
python
class TriggerEngine:
    RULES = {
        'user.signup':      ('welcome', delay=0),
        'product.viewed':   ('follow_up', delay=3600),
        'cart.abandoned':   ('recovery', delay=7200),
        'order.completed':  ('receipt', delay=0),
    }
    
    def handle_event(self, event: str, user_id: str):
        if event not in self.RULES:
            return
        
        template, delay = self.RULES[event]
        
        # Idempotency — cooldown per user per event
        if self.in_cooldown(user_id, event):
            return
        
        self.schedule_email(
            user_id=user_id,
            template=template,
            send_at=now() + delay
        )
        self.set_cooldown(user_id, event)

SendGrid for deliverability — not raw SMTP

SMTP at scale is a reliability and deliverability problem. SendGrid handles bounce management, unsubscribes, and deliverability reputation. Integrated their API with full suppression list checking on every send.

Configurable rules — non-engineers can operate it

Marketing teams can adjust which events trigger which emails without touching code. Deliberate design choice: the system should outlast any single engineer.

What Changed

Campaigns became targeted and contextually relevant. Marketing teams can evolve campaigns without engineering involvement each time.

Campaign Type
batch, time-based
0
contextual
Engineering Dependency
every change
0
self-service
"People were getting messages that matched where they actually were in their journey, not generic blasts."

Common Questions

SendGrid handles unsubscribe mechanics and suppression lists automatically. I made sure the integration checked suppression lists on every send before any email goes out. GDPR and CAN-SPAM compliance was built into the integration, not bolted on after.
I built idempotency into the trigger logic — each event type has a cooldown window per user. If the same event fires again within that window, it is ignored. You do not want someone who views a product five times to get five emails.