Documentation
Everything you need to add live chat to your site and receive messages in Telegram.
Quick Start
Get from zero to a working chat widget in under 5 minutes.
- 1 Create an account
Sign up at dash.bubblegram.co.
- 2 Create a project
Enter a name and your site's domain (e.g.
example.com). - 3 Connect Telegram
Click Link Telegram in your project. One tap adds the bot and links the group. See Telegram Setup.
- 4 Embed the script tag
Paste one line of HTML into your site. See Embed the Widget.
- 5 Done.
The chat bubble appears on your site. Visitors send messages; you reply in Telegram. Replies are delivered back to the widget in real time.
Telegram Setup
Bubblegram delivers visitor messages to a Telegram group. Each visitor gets a dedicated topic thread so conversations stay organized.
1. Create a Telegram group
- Open Telegram and tap the pencil icon (or "New Message").
- Choose New Group.
- Optionally add members (you can add yourself from another account, or a teammate). You can also skip this and create the group alone.
- Give the group a name, then create it.
2. Enable Topics (Forum mode)
Topics allow each visitor to get their own thread inside the group. Without this, all messages arrive in one mixed stream.
On desktop
- Open the group and click Manage group.
- Go to Topics and enable it.
- Set the display to List. This makes it easier to scan and manage multiple visitor conversations.
On mobile
- Tap the group name at the top to open group info.
- Tap Group settings.
- Go to Topics and enable it.
- Select List as the display style.
3. Add the bot
In the dashboard, open your project and click Link Telegram. This opens Telegram with the bot pre-selected and admin permissions pre-filled. Confirm. The bot joins, gets admin rights, and links your group automatically. No extra steps.
Already have the bot in the group?
If the bot was already a member before you started setup, the deep link
won't fire. Instead, copy the /start command from the dashboard
and send it in the group manually:
/start YOUR_LINK_TOKEN The bot replies: "Project linked successfully." Then promote it to admin. It needs permission to manage topics, post messages, and delete messages.
Embed the Widget
The widget loads from a CDN and is initialized with your project's API key.
Script tag
Add this to your HTML, just before the closing </body> tag:
<script
src="https://cdn.bubblegram.co/widget.js"
data-key="pk_live_YOUR_KEY_HERE"
async
></script> Your API key is shown in the project's Embed section in the dashboard, visible after your Telegram group is linked.
Attributes
| Attribute | Required | Description |
|---|---|---|
data-key | Required | Your project's public API key. Starts with pk_live_. |
data-api | Optional | API base URL. Defaults to https://api.bubblegram.co. |
data-email | Optional | Pre-fill the visitor's email. Useful on server-rendered pages where the user is already signed in. Skips the email input even when "Require email" is enabled. |
JavaScript API
After the script loads, a Bubblegram object is available on
window. You can control the widget programmatically:
Bubblegram.open() // open the chat panel
Bubblegram.close() // close the chat panel
Bubblegram.connect() // reconnect WebSocket (if disconnected)
Bubblegram.setEmail('user@example.com') // pre-fill email for signed-in users
Use setEmail when the email is only known after client-side
auth. For example, in React or Next.js after the session loads:
useEffect(() => {
if (session?.user?.email) {
window.Bubblegram?.setEmail(session.user.email)
}
}, [session?.user?.email])
If this runs before widget.js has finished loading (common
in SPAs, since the script tag is async),
window.Bubblegram won't exist yet and the call is silently
lost. Use the queue stub shown in the React/Next.js examples below to
make it safe to call anytime.
On server-rendered pages (PHP, Rails, Django, etc.) where the email is
available at render time, use the data-email attribute instead:
<script
src="https://cdn.bubblegram.co/widget.js"
data-key="pk_live_YOUR_KEY_HERE"
data-email="<?= $currentUser->email ?>"
async
></script>
For React, Next.js, or other SPAs, add the script to your root HTML
file. In Vite or Create React App, that's index.html:
<script>
window.Bubblegram = window.Bubblegram || (function () {
var q = []
var api = { q: q }
;['init', 'sendMessage', 'connect', 'open', 'close', 'setEmail', 'destroy'].forEach(function (m) {
api[m] = function () { q.push([m, Array.prototype.slice.call(arguments)]) }
})
return api
})()
</script>
<script
src="https://cdn.bubblegram.co/widget.js"
data-key="pk_live_YOUR_KEY_HERE"
async
></script>
In Next.js, use the built-in Script component in your _app.tsx or root layout. Load the stub with beforeInteractive so
it exists before any of your components try to call
Bubblegram:
import Script from 'next/script'
<Script id="bubblegram-stub" strategy="beforeInteractive">
{`window.Bubblegram = window.Bubblegram || (function () {
var q = []
var api = { q: q }
;['init', 'sendMessage', 'connect', 'open', 'close', 'setEmail', 'destroy'].forEach(function (m) {
api[m] = function () { q.push([m, Array.prototype.slice.call(arguments)]) }
})
return api
})()`}
</Script>
<Script
src="https://cdn.bubblegram.co/widget.js"
data-key="pk_live_YOUR_KEY_HERE"
strategy="afterInteractive"
/> Widget Customization
All visual settings are configured in the Project Builder in your dashboard. Changes are reflected in the live preview as you edit and applied to your site when you click Publish changes.
| Setting | Description | Limit |
|---|---|---|
| Brand color | Primary color for the chat button, header, and sent messages. | Any hex color |
| Logo | Shown in the widget header. PNG, JPEG, or WebP. | 512 KB max |
| Welcome message | Displayed as the first message when the widget opens, before the visitor types anything. | 200 characters |
| Greeting bubble | Short text shown in a speech bubble above the chat button. Leave empty to hide it. | 100 characters |
| Require email | When on, visitors must enter their email before sending a message. When off, anonymous messaging is allowed. | Toggle |
Email channel
The email channel puts your support inbox in the same Telegram group
as your widget chats. Someone emails support@yoursite.com,
it lands as a topic in Telegram, you reply in the topic, and they get
a normal email back from your own address.
Nothing changes about how you work. You answer everything in Telegram, whether the person used the widget or sent an email.
How it works
You keep your existing mailbox. We do not replace it, and you do not move your email anywhere. You set up a forwarding rule that sends a copy of incoming mail to a private address we generate for your project. That address is the only piece of plumbing involved.
- A customer emails your support address.
- Your mail provider forwards a copy to your Bubblegram address.
- We create a Telegram topic for that sender and post the message, with attachments.
- You reply in the topic.
- They receive an email reply. If your domain is verified it comes from your own address.
- Their reply comes straight back to the same topic, no forwarding involved.
Setup is two steps. Step 1 gets email flowing into Telegram and is all most people need. Step 2 makes replies go out from your own domain instead of ours, and is optional.
1. Turn on the email channel
Open your project in the dashboard, go to the Email tab, and click Enable email channel. You get an address that looks like this:
875a8eff4f3940e4a2f5937e37565a13@mail.bubblegram.co It is unique to the project and not guessable. Treat it as private: anyone who knows it can post into your Telegram group. It does not change if you disable and re-enable the channel later, so your forwarding rule keeps working.
2. Forward your support email
Set up forwarding to that address in whatever provider hosts your support inbox. The dashboard shows exact steps for your provider. Gmail is the one worth walking through here, because it takes two settings that look like one.
Gmail and Google Workspace
- Open Gmail, click the gear icon, then See all settings, then the Forwarding and POP/IMAP tab.
- Click Add a forwarding address, paste your Bubblegram address, then click Next, Proceed, OK.
- Gmail sends a confirmation to that address. Since the address is ours, we catch it and show it on the Email tab within a few seconds. Personal Gmail accounts get a code to type into the box next to the pending address, then click Verify. Google Workspace accounts get a confirmation link instead: open it and press Confirm. Whichever one you get is what we show you.
- Back on the same tab, select Forward a copy of incoming mail to and pick the address.
- Scroll to the bottom of the page and click Save Changes.
You never have to go hunting for Gmail's confirmation email. It is sent to an address only we can read, so we watch for it, pull out whatever it contains, and put it on the Email tab. It also goes to your Telegram group as a backup.
Other providers
| Provider | Where to set it up |
|---|---|
| Outlook | Settings > Mail > Forwarding > Enable forwarding. Check "Keep a copy of forwarded messages", then Save. |
| Microsoft 365 | Same as Outlook. Your admin may need to allow external forwarding under Security & Compliance > Anti-spam > Outbound policy. |
| Cloudflare Email Routing | Dashboard > your domain > Email > Email Routing > Create address, with the destination set to your Bubblegram address. No confirmation step, so this is the quickest option. |
| Anything else | Look for a forwarding or redirect setting and point it at your Bubblegram address. |
Confirming it works
Nothing arrives on its own. Once forwarding is saved, email your support address from a personal account. Within a few seconds a topic appears in Telegram and the dashboard flips step 1 to done on its own, with no refresh needed. Forwarding only applies to mail that arrives after you saved, so anything already sitting in the inbox stays there.
3. Reply from your own domain
This step is optional. Skip it and everything still works, replies just
go out from noreply@mail.bubblegram.co instead of your own
address.
Enter your domain and the address you want replies to come from, for
example support@yoursite.com. The from address has to be on
the domain you are verifying. We generate three DNS records for you to
add at your registrar:
| Record | Type | What it does |
|---|---|---|
| SPF | TXT | Authorizes our servers to send mail as your domain. |
| DKIM | CNAME | Signs outgoing mail so receivers can verify it is really you. |
| DMARC | TXT | Tells receivers what to do with mail that fails the checks. |
The dashboard checks verification for you every few seconds and updates each record as it goes green. DNS changes usually take a few minutes, occasionally a few hours. You can close the tab and come back.
What it looks like in Telegram
Each sender gets their own topic, named with an envelope so you can tell it apart from widget chats at a glance:
📧 john@example.com The first message in a new topic is preceded by a short info card:
From: john@example.com
Subject: Can't reset my password Attachments come through as files or photos in the same topic. Quoted reply chains and signatures are stripped, so you see what the person actually wrote rather than the whole thread. If a message fails sender authentication, we flag it at the top rather than hiding it, since that's a common sign of a spoofed address.
Replying
Just reply in the topic. A few details worth knowing:
- Several quick replies are bundled into one email rather than sent separately, so you can think out loud without filling someone's inbox.
-
Replies thread properly in the recipient's client, under
Re: their subject. - When they reply, it comes directly back to us and into the same topic. It does not depend on your forwarding rule, and it works even if they answer from a different address than the one they wrote in with.
- If someone starts in the widget and continues by email, or the other way around, it stays in one topic with the full history.
-
/closeworks the same as it does for widget chats. If they email again later, the topic reopens.
What we filter out
A support inbox receives a lot that isn't a customer talking to you. Rather than forwarding all of it into Telegram, we drop the following silently:
| Dropped | Why |
|---|---|
| Out of office and auto-replies | Marked as automatic by the sending server. Left alone they can ping-pong with your replies forever. |
| Newsletters and mailing lists | Marked as bulk mail. Nobody is waiting on an answer. |
noreply@, no-reply@,
mailer-daemon@, postmaster@ | Automated senders that got caught by your forwarding rule. |
| Our own outgoing replies | If you forward the same address we send from, replies would loop back to us. We tag and ignore them. |
So a forwarded newsletter is not a useful way to test your setup. Send an ordinary email from a personal account instead.
Limits
- Around 15 emails per minute per project, in short bursts of up to 20.
- 5 emails per sender per 5 minutes, which stops one loop or one angry refresher from flooding the group.
- Up to 20 new conversations at once, then roughly 6 per minute after that.
- Message bodies are capped at 50,000 characters.
These are far above normal support volume. If you are hitting them, something is looping and we should look at it together.
Turning it off
Disable email channel on the Email tab stops delivery. Your address and domain verification are kept, so re-enabling later is one click and your existing forwarding rule still points to the right place. Remember to remove the forwarding rule at your provider too, otherwise your mail is being copied somewhere that ignores it.
Multiple Sites
Each project in Bubblegram corresponds to one website and one Telegram group. Every project is fully isolated:
- Its own API key for the embed script
- Its own widget configuration (colors, messages, logo)
- Its own Telegram group with separate topic threads
- Its own message history and analytics
To add a second site, create a new project in the dashboard and run through the Telegram setup again for that site's group.
Bot commands
Type these commands as replies inside any conversation thread in your Telegram group:
| Command | What it does |
|---|---|
/close | Mark the conversation as resolved. |
/status | Show linked project info for this group. |
/unlink | Remove the project link from this group. |
Troubleshooting
Widget not appearing on my site
Check that the data-key attribute in your script tag matches
the API key shown in your project's Embed section. The key starts with
pk_live_. Also confirm the script tag is in the <body>, not the <head>.
Messages aren't arriving in Telegram
Your project may not be linked. Open the project in the dashboard. If the status shows Not linked, click Link Telegram and complete the flow. The bot must be in the group and have admin rights.
Origin mismatch error
The domain saved in your project settings must exactly match the
domain your site runs on. Enter it without https:// and without
a trailing slash. For example: example.com, not https://example.com/. Subdomains count as different domains.
Bot joined the group but messages aren't creating topics
The bot needs admin rights. Open your Telegram group, go to Administrators, find the bot, and ensure it has permission to manage topics, post messages, and delete messages. Without these, topic creation fails silently.
I set up forwarding in Gmail but no email arrives
Almost always the last step. Go back to Gmail's Forwarding and POP/IMAP tab and check that Forward a copy of incoming mail to is actually selected, then scroll down and click Save Changes. Verifying the address does not switch forwarding on by itself, and Gmail throws the setting away if you leave the page without saving. After that, send yourself a test email from a different account. Only mail arriving after you saved gets forwarded.
Gmail says "An error occurred with the secure Google verification"
This is Gmail failing before it sends anything, not a problem with your Bubblegram address. The usual cause is being signed into several Google accounts in the same browser: open an incognito window, sign into just the one account, and try again. On Google Workspace, forwarding may be disabled for your organization, in which case your admin needs to allow it under Admin Console > Apps > Google Workspace > Gmail > End User Access. Ad blockers and privacy extensions can also break the verification popup. If you've tried several times in a row, wait an hour before retrying.
The Gmail confirmation code isn't showing in the dashboard
Click Re-send email next to the pending address in Gmail and watch the Email tab. The code appears within a few seconds and is also posted to your Telegram group. If it still doesn't show up, the confirmation never reached us, which usually means the address was pasted with a typo. Compare it against the address on the Email tab character for character, or remove it in Gmail and add it again.
My test email never showed up in Telegram
Check what you sent. Newsletters, notifications and anything from a
noreply@ address are filtered out on purpose, so they make
a poor test. Send an ordinary message from a personal mailbox instead.
Also confirm your plan is still Pro: on the Free plan the email channel
is set up but incoming mail is not delivered, and we post a notice in
your Telegram group once a day when that happens.
Replies are coming from noreply@mail.bubblegram.co
That's the default sender until your own domain is verified. Finish step 3 on the Email tab by adding the SPF, DKIM and DMARC records at your registrar. Until all three verify, replies still send and still thread correctly, they just come from our address rather than yours.
Link token expired
Link tokens are valid for 10 minutes. If you waited too long between generating the token and completing the setup, go back to your project in the dashboard, click Link Telegram again, and use the newly generated token.