Should I vibe code
Free live-chat widget for your site that lands in your Telegram
A chat widget is an unauthenticated write endpoint pointed at your phone. Guess who finds it first.
?
Their verdict, the Pro price and the build-time estimate come from their entry, MIT-licensed. Checked 2026-08-04.
?
Our verdict, the regret score and everything below it. Editorial and unsponsored — nobody can pay to be moved.
The honest answer
why the verdict is what it is
Using Telegram as the inbox is the clever part, and it genuinely deletes half the build: no dashboard, no operator websocket, no seats. What it does not delete is that you are running the front door of a business on a script tag, and there is exactly one thing you have to get right on every single message — which visitor a reply belongs to. Get it wrong once and you have not shipped a bug, you have shown one customer another customer's conversation.
What actually breaks
not "if". the specific failures.
- Reply routing, because Telegram hands you a chat and not a conversation — the mapping back to a visitor session is yours to keep, and losing it delivers one customer's answer to a different customer
- The visitor's transport, where someone types into a socket that is open on their side and gone on yours, and every message shows as sent
- Telegram's rate limits, which are generous right up until a launch day or a bot storm, after which messages are simply dropped
- The bot token, which is a bearer credential for the entire inbox and which ends up in an env var, a screenshot and a git history
- Your personal Telegram history as the system of record, where 'please delete my data' has no implementation
- The widget script on a page you do not own, which makes your uptime part of somebody else's page load
- An unauthenticated POST that anyone can find in the bundle and call directly, at any rate they like
Two conversations arrive ninety seconds apart. The second visitor's message lands while the bot is mid-retry on the first, and because the reply mapping is keyed on the last message id you stored per chat, the retry overwrites it. What you type next — reading back a booking reference and the last four digits of a card to confirm you have the right order — goes to the wrong browser. Neither person reports it, because neither of them has any way to know what happened. You find out five weeks later from a support email that opens 'this is probably nothing, but'.
Is that you?
the verdict is a default, not a law
- It is a contact form that forwards to Telegram, presented as one, with no live-chat framing
- It runs on one site you own, with traffic low enough that two conversations never overlap
- The widget never implies that somebody is available right now
- Every conversation is keyed on an id you generated and stored, and the reply path looks it up rather than inferring it
- Reply routing depends on anything other than a stored, server-generated conversation id
- It ships on a client's site, where their visitors depend on your uptime and their page depends on your script
- You have no answer for a deletion request, because the transcript lives in your personal chat history
- The endpoint accepts messages from any origin, at any rate, with no session binding
If you build it anyway
the checklist, then the prompt that enforces it
- Key every conversation on a server-generated id, persist the Telegram message-to-conversation mapping durably, and make the reply path a lookup rather than an inference. This is the one bug in this product that is a disclosure rather than an outage.
- Persist messages in your own database before forwarding them anywhere. Telegram is a delivery channel and a terrible system of record — you cannot query it, migrate it, or reliably purge it.
- Bind the widget to an allowlist of origins and rate-limit per session and per IP before the first real visitor. An unauthenticated write endpoint pointed at your phone is a denial-of-service against you personally.
- Escape in both directions: visitor text rendered into the widget's DOM as text only, and visitor text sent to Telegram with its parse mode disabled or fully escaped.
- Show availability derived from something real. If nobody is going to answer for nine hours, say so and take an email address instead of implying presence.
- Load the widget asynchronously with a timeout and fail silently, so your outage never slows the page it sits on.
- Decide retention before launch, and write down honestly that transcripts sitting in a personal Telegram account are not something you can delete on request — that gap is the reason to keep your own store authoritative.
Before you write a chat widget that forwards to Telegram, apply these and push back if I ask you to break them.
1. The sharpest failure is a reply reaching the wrong visitor. Build the
conversation model first: a server-generated conversation id, a durable
mapping from it to the Telegram message thread, and a reply path that looks
the conversation up. Never infer the target from 'the most recent chat'.
2. Write a test that interleaves two conversations with a retry in the middle
and asserts no message crosses over. Do it before any UI exists.
3. Persist every message to my own database before forwarding it. Telegram is
delivery, not storage — a transcript that exists only in a chat app cannot
be exported, searched or deleted on request.
4. The visitor endpoint is unauthenticated by definition. Before it accepts one
message: allowlist origins, rate-limit per session and per IP, cap message
size and conversation length, and reject over-cap rather than truncating.
5. Treat visitor text as hostile in both directions — rendered into the widget
as text, never markup, and sent to Telegram with parse mode disabled or
every special character escaped.
6. Handle Telegram's rate limits with a queue and backoff, and alert me on a
dropped message. A silently dropped customer message beats no error only in
the logs.
7. Treat the bot token as the credential to the whole inbox: environment only,
never in the client bundle, never logged, rotatable without a redeploy.
8. Compute availability from something real. If nobody is around, the widget
says so and takes an email address. Never hardcode a response time.
9. Load the widget asynchronously with a timeout and fail silently, so my
outage never blocks or slows the host page.
10. Implement deletion before styling: one action that removes a conversation
from my store, plus an honest README note on what remains in Telegram.
11. Out of scope unless I ask: file uploads, multi-operator assignment, canned
replies, chat ratings.That one keeps you out of trouble. For the prompt that actually builds it, canivibecodeit.com has one.
their build prompt ↗Or don’t build it
the boring option, and the way back out
This is an unusual entry to write a buy case for, because the hosted version is free at one site and $4.99 a month after that, so you are not saving a subscription — you are choosing to own the reply-routing bug and the deletion story. That is a legitimate choice if the widget is a small part of something larger you are already running. It is a bad trade if the only reason is that a Telegram bot looked like fifty lines.
$4.99/mo is cheaper than your weekend.
Keep conversations in your own database — stable ids, plain timestamps, one row per message — with Telegram treated as an output. If Telegram is the only store you have no export, no deletion path and nothing to hand a real help desk. Keep the embed behind a URL you control rather than a hardcoded script tag, so retiring it is a redirect rather than an email asking every site owner to edit their HTML.
Self-hostable customer engagement suite · far heavier than this, but open source and battle-tested, including the conversation model.
Maintained TypeScript Telegram bot framework · handles webhooks, retries and rate limits so you are not reimplementing the transport.
Questions
Telegram does the hard part. How much is really left?
Telegram removes the operator half — no dashboard, no inbox, no notifications to build — and that is a real saving. It removes none of the visitor half, and it adds a problem the hosted help desks do not have: a chat app has no concept of your conversations, so the mapping between a Telegram message and a visitor session is state you invented and must never lose. Everything that goes badly wrong here goes wrong in that mapping.
Why is using a chat app as the database such a problem?
Because three ordinary requests become impossible. Export a customer's history: there is no query. Delete it on request: you can delete messages one at a time, from one account, with no guarantee about copies on other devices. Hand support to a colleague: the archive is in your personal account. None of this stops the demo working, which is exactly why it gets discovered late.
How is this different from your Chatwoot Cloud entry?
Chatwoot's entry is about realtime delivery — half-open sockets, unacknowledged messages, a visitor typing into a void. Half of that disappears here because the operator side is Telegram's problem. What replaces it is routing and custody: which conversation a reply belongs to, and where the transcript actually lives once it has been forwarded into a consumer messaging account.
- GDPR Art. 5 — principles relating to processing of personal data (purpose limitation, storage limitation)
- GDPR Art. 32 — security of processing
Every week, someone ships something they shouldn’t have.
New verdicts, the worst thing that landed in the trap, and the occasional incident report. No other email, ever.
An AI that answers your customers wrongly is a support ticket that scales.
A dropped support email is invisible. You find out from the refund request.
Live chat is a promise that someone is there. Your uptime is now a customer expectation.
last reviewed 2026-08-04 · verdict is editorial and unsponsored · shared entry data from canivibecodeit under MIT · not legal advice