DEV Community

Mary
Mary

Posted on

Knocket: Connect with customers online with just one click.

 Most chat widgets ship with their own dashboard. And another dashboard for email. And a third for the messaging app your users actually use. If you're an indie maker with 30 signups, opening three dashboards to reply to five messages is a joke.

We built Knocket as the free contact layer for indie developers who don't want to babysit dashboards. One line to install a live chat widget. One shareable contact page. One inbox that receives Live Chat, Telegram, and Email in the same place — and lets you reply directly from Telegram without opening anything else.

This post walks through the design decisions behind the unified inbox — specifically how we route three channels through a single webhook without leaking channel-specific logic all over the codebase.

The problem with "one inbox for everything"

You've seen the pitch before. Every helpdesk product from Intercom on down claims a "unified inbox." In practice they mean:

  • Live chat: real-time bidirectional WebSocket
  • Email: SMTP inbound + polling
  • Messaging apps: platform-specific webhooks (Telegram Bot API, Meta Graph, etc.)

Each channel has its own delivery guarantees, ordering, retry semantics, and failure modes. A naive implementation hardcodes three code paths and inevitably drifts — a bug fix in the email path doesn't apply to Telegram, and now you have three subtly different reply behaviors.

The design: normalize at the edge, unify in the middle

We settled on a three-layer shape:

┌────────────────────────────────────────────┐
│  Channel Adapters (one per source)         │
│  ─ Live Chat WebSocket                     │
│  ─ Telegram Bot webhook                    │
│  ─ IMAP/SMTP email                         │
└────────────────────────────────────────────┘
              ↓ normalized event
┌────────────────────────────────────────────┐
│  Unified Message Bus (single format)       │
│  { conversation_id, sender, body, ... }    │
└────────────────────────────────────────────┘
              ↓ fan-out
┌────────────────────────────────────────────┐
│  Inbox UI  ·  Notifications  ·  Reply Router│
└────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

The core rule: anything that knows about "Telegram" or "SMTP" lives only in an adapter. The bus and the UI see one message shape. Adding a new channel (WhatsApp is next) is a new adapter, not a new special case in the reply logic.

The reply router — the interesting part

The subtle problem: when you reply from Telegram, the reply must go back to the visitor via the original channel. If Sarah pinged you via the website widget and you type a reply into your Telegram app, that reply has to appear in Sarah's browser — not as a Telegram message to Sarah.

Every message on the bus carries source_channel. The reply router reads that field and dispatches to the right outbound adapter:

// Simplified
async function routeReply(originalMessage, replyBody) {
  const adapter = adapters[originalMessage.source_channel];
  await adapter.sendReply({
    conversation_id: originalMessage.conversation_id,
    body: replyBody,
  });
}
Enter fullscreen mode Exit fullscreen mode

The Telegram adapter is where the neat trick lives: when Knocket forwards a live-chat message to your Telegram, the message includes structured metadata so a quote-reply in Telegram carries enough context for the router to reconstruct the original conversation. You reply in Telegram like you're replying to a friend, and it lands in the visitor's browser.

No new dashboard. No context switch. No "let me open the console real quick."

What this made easy

  • New channels are additive. Adding a channel is one adapter file plus registration.
  • The inbox UI is boring. It renders one message shape. It doesn't care about the source.
  • Notifications are trivial. One "new message" event, delivered to browser push and Telegram.
  • Failure modes are localized. If Telegram's API is down, only the Telegram adapter fails. Live chat and email keep flowing.

What we open-sourced

We also released a companion project — an open-source AI auto-reply agent that plugs into the same message bus. It's a reference implementation for anyone who wants to run their own AI reply layer against a Knocket inbox: github.com/fangxinmoon/knocket-inbox-agent-EN

If you want to plug it into your own knowledge base, the agent's system prompt and retrieval layer are yours to swap out.

Try it

Knocket is 100% free forever — no ads, no seat limits, no paid tier. If you're at the "first 100 users" stage and Intercom's pricing feels absurd, this is the tool we wish existed when we started.

Set-up is one script tag. If you're on Framer, Webflow, WordPress, Ghost, Shopify, or anything else that supports custom code, you're 60 seconds from a live chat widget.

Powered by Tencent RTC infrastructure for global low-latency delivery.

Would love feedback in the comments — especially from anyone who's built or hated multi-channel inboxes before. What did we get wrong?

Top comments (0)