Knocket: One Knock. Every Connection.
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
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β
ββββββββββββββββββββββββββββββββββββββββββββββ
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,
});
}
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 clean. It aggregates information from various channels and distinguishes between social media, email, and web sources.
- 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?
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.
