LeadRobin

Intelligent Lead Routing
for Any Team

LeadRobin distributes every inbound lead fairly and instantly, from any source: email, web forms, APIs, partner feeds, and CRMs. No more manual sorting, no more favorites, no more dropped balls.

Request a DemoSign In
LeadRobin Series

Building LeadRobin: Node.js, Docker, and the Microsoft 365 Ecosystem

August 31, 2026 · 3 min read · Part 2 of the LeadRobin Series

The new lead routing system needed to be reliable, maintainable, and scalable. Here's the architecture I chose:

Containerization with Docker

Every component runs in Docker containers orchestrated with Docker Compose. The web interface, the email processor, and the PostgreSQL database each get their own container. This makes deployments predictable - build an image, tag it, deploy it. Rollbacks are just as easy. And because it's Linux containers, it's cheaper and easier to deploy than Windows Server licenses.

Microsoft Graph API and Shared Mailboxes

The agencies already use Microsoft 365 for business, with shared mailboxes dedicated to lead intake. Instead of building a separate lead capture system, I integrated directly with what they already have.

The system uses Microsoft Graph API with OAuth2 client credentials flow to access those shared mailboxes programmatically. No user passwords stored - the app authenticates with its own credentials and reaches the designated shared mailbox directly. The processor polls every 30 seconds, checking both inbox and junk folders for unread emails.

This approach has several advantages:

The Graph API integration handles the heavy lifting - authenticating, fetching unread emails, extracting lead data from the email body HTML, and marking messages as read to prevent duplicate processing. It's a clean separation of concerns: M365 handles email, LeadRobin handles routing logic.

PostgreSQL

The C# version used SQL Server. I switched to PostgreSQL for the Node.js stack. The schema is straightforward - a Brokers table with email, login status, and LastLead timestamp for round-robin selection. A Leads table tracks every lead received, who it was assigned to, and the API response. A ProcessingLog table captures every significant event for debugging.

Agency Management System Integration

The system authenticates to the agency management system via OAuth2, gets an access token, and POSTs the lead data as JSON. The payload structure matches the reference implementation exactly - same fields, same naming, same formatting. This turned out to be critical (more on that in Part 3).

Caddy Reverse Proxy with Modern Cryptography

Caddy handles TLS termination and routes requests based on hostname. But Caddy doesn't just use standard TLS - it sets up ECC (Elliptic Curve Cryptography) certificates and supports post-quantum cryptography.

What does that mean? ECC is a more efficient form of encryption that provides the same security as traditional RSA but with smaller keys, making it faster and more secure. Post-quantum cryptography is designed to be resistant to attacks from future quantum computers, which could potentially break current encryption methods. By using these modern cryptographic standards, the system is protected not just today, but against future threats. It's forward-looking security without extra configuration - Caddy handles it automatically.

The Round-Robin Logic

When an email arrives, the system queries for the logged-in broker with the oldest LastLead timestamp (or NULL if they've never received a lead). It updates their LastLead to now, forwards the email, and sends the data to the agency management system. This ensures fair distribution and prevents race conditions.

The system runs 24/7 with automatic restarts on failure. Structured logging for every step. It's been running in production for months, processing thousands of leads.

Follow the LeadRobin Series

This is Part 2 of an ongoing series documenting how LeadRobin was built from the ground up using AI coding tools. New to the series? Start with Part 1: Why I Built LeadRobin. Part 3 publishes September 1.

Read the Blog

← All posts  ·  Request a demo