docs/platform/integrations/chat/telegram.mdx
The Telegram chat integration lets your application send messages to subscribers through a Telegram bot. Each subscriber connects their Telegram chat to Novu once; after that, Novu can deliver workflow notifications or agent replies to that chat.
<Note> Check out the [agents](/agents) documentation to build conversational agents on Telegram. Users message your bot in Telegram and your agent replies in the same chat. </Note>Every Telegram integration uses one bot. Create it with BotFather before adding the provider in Novu.
<Steps> <Step title="Open BotFather"> Open [@BotFather](https://t.me/botfather) in Telegram (mobile or desktop). </Step> <Step title="Run /newbot"> Send the `/newbot` command and follow the prompts to choose a **display name** and a **username** (must end in `bot`, for example `acme_alerts_bot`). </Step> <Step title="Copy the confirmation message"> BotFather replies with a confirmation message that includes your bot token, for example:```
1234567890:AAFdT8_…
```
Copy the full message — Novu can extract the token automatically when you paste it into the dashboard.
On mobile, scan the QR code in the form to open a setup page and paste the BotFather message from the device where you received it.
If you add Telegram to an agent, the dashboard also walks you through connecting your bot and sending a test message.
Before Novu can deliver messages, each subscriber must connect their Telegram chat.
Novu gives you a link that opens your bot in Telegram. When the subscriber taps Start, their chat is linked to their Novu subscriber profile.
<Note> The connection link flow is available when Telegram is set up on an agent. If you only need one-way workflow notifications and already know a subscriber's Telegram chat ID, you can register it with the [channel endpoints API](/api-reference/channel-endpoints/create-a-channel-endpoint) instead. </Note>Request a connection URL from your server when the subscriber chooses to connect Telegram:
<Tabs> <Tab title="Node.js"> ```typescript import { Novu } from '@novu/api';const novu = new Novu({ secretKey: '<NOVU_SECRET_KEY>' });
const response = await novu.integrations.linkChannelEndpoint({ integrationIdentifier: 'telegram', subscriberId: '<SUBSCRIBER_ID>', });
</Tab>
<Tab title="Python">
```python
import os
from novu_py import Novu
with Novu(secret_key=os.getenv("NOVU_SECRET_KEY", "")) as novu:
response = novu.integrations.link_channel_endpoint(link_channel_endpoint_request_dto={
"integration_identifier": "telegram",
"subscriber_id": "<SUBSCRIBER_ID>",
})
novugo "github.com/novuhq/novu-go"
"github.com/novuhq/novu-go/models/components"
)
s := novugo.New(novugo.WithSecurity(os.Getenv("NOVU_SECRET_KEY")))
res, err := s.Integrations.LinkChannelEndpoint(context.Background(), components.LinkChannelEndpointRequestDto{ IntegrationIdentifier: "telegram", SubscriberID: "<SUBSCRIBER_ID>", }, nil)
</Tab>
<Tab title="PHP">
```php
use novu;
use novu\Models\Components;
$sdk = novu\Novu::builder()->setSecurity('<NOVU_SECRET_KEY>')->build();
$response = $sdk->integrations->linkChannelEndpoint(
linkChannelEndpointRequestDto: new Components\LinkChannelEndpointRequestDto(
integrationIdentifier: 'telegram',
subscriberId: '<SUBSCRIBER_ID>',
),
);
var sdk = new NovuSDK(secretKey: "<NOVU_SECRET_KEY>"); var response = await sdk.Integrations.LinkChannelEndpointAsync( linkChannelEndpointRequestDto: new LinkChannelEndpointRequestDto() { IntegrationIdentifier = "telegram", SubscriberId = "<SUBSCRIBER_ID>", });
</Tab>
<Tab title="Java">
```java
import co.novu.Novu;
import co.novu.models.components.*;
Novu novu = Novu.builder().secretKey("<NOVU_SECRET_KEY>").build();
var response = novu.integrations().linkChannelEndpoint()
.body(LinkChannelEndpointRequestDto.builder()
.integrationIdentifier("telegram")
.subscriberId("<SUBSCRIBER_ID>")
.build())
.call();
Open the returned url in a new tab or show it as a button in your UI. Generate a fresh link each time the subscriber starts the flow — links expire after a short time.
@novu/reactFor agent applications, use TelegramConnectButton inside NovuProvider. It opens Telegram for the subscriber and confirms when the chat is connected.
import { NovuProvider, TelegramConnectButton } from '@novu/react';
function ConnectTelegram() {
return (
<NovuProvider subscriberId="user-123" applicationIdentifier="your-app-id">
<TelegramConnectButton
integrationIdentifier="telegram"
connectLabel="Connect Telegram"
connectedLabel="Connected to Telegram"
onConnectSuccess={() => {
console.log('Telegram connected');
}}
/>
</NovuProvider>
);
}
See the connect components guide for the full props reference.
Once subscribers have connected Telegram, add a Chat step to a workflow and trigger it as usual.
<Steps> <Step title="Add a Chat step"> In the Novu dashboard, open your workflow, add a step, and select **Chat** as the channel. </Step> <Step title="Write the message body"> Compose the message content. Use dynamic placeholders such as `{{subscriber.firstName}}` or payload variables from your trigger. </Step> <Step title="Trigger the workflow"> Send a test trigger for a subscriber who has connected Telegram. </Step> </Steps> <Tabs> <Tab title="Node.js"> ```typescript import { Novu } from '@novu/api';const novu = new Novu({ secretKey: "<NOVU_SECRET_KEY>" });
await novu.trigger({ workflowId: "order-shipped", to: { subscriberId: "user-123", }, payload: { "orderNumber": "ORD-12345", "trackingUrl": "https://acme.com/track/123" }, });
</Tab>
<Tab title="Python">
```python
import os
import novu_py
from novu_py import Novu
with Novu(secret_key=os.getenv("NOVU_SECRET_KEY", "")) as novu:
novu.trigger(trigger_event_request_dto=novu_py.TriggerEventRequestDto(
workflow_id="order-shipped",
to={"subscriber_id": "user-123"},
payload={
"orderNumber": "ORD-12345",
"trackingUrl": "https://acme.com/track/123"
},
))
novugo "github.com/novuhq/novu-go"
"github.com/novuhq/novu-go/models/components"
)
s := novugo.New(novugo.WithSecurity(os.Getenv("NOVU_SECRET_KEY")))
res, err := s.Trigger(context.Background(), components.TriggerEventRequestDto{ WorkflowID: "order-shipped", To: components.CreateToSubscriberPayloadDto(components.SubscriberPayloadDto{ SubscriberID: "user-123", }), Payload: map[string]any{ "orderNumber": "ORD-12345", "trackingUrl": "https://acme.com/track/123" }, }, nil)
</Tab>
<Tab title="PHP">
```php
use novu;
use novu\Models\Components;
$sdk = novu\Novu::builder()->setSecurity('<NOVU_SECRET_KEY>')->build();
$sdk->trigger(
triggerEventRequestDto: new Components\TriggerEventRequestDto(
workflowId: 'order-shipped',
to: new Components\SubscriberPayloadDto(subscriberId: 'user-123'),
payload: {
"orderNumber": "ORD-12345",
"trackingUrl": "https://acme.com/track/123"
},
),
);
var sdk = new NovuSDK(secretKey: "<NOVU_SECRET_KEY>");
await sdk.TriggerAsync(triggerEventRequestDto: new TriggerEventRequestDto() { WorkflowId = "order-shipped", To = To.CreateSubscriberPayloadDto(new SubscriberPayloadDto() { SubscriberId = "user-123" }), Payload = { "orderNumber": "ORD-12345", "trackingUrl": "https://acme.com/track/123" }, });
</Tab>
<Tab title="Java">
```java
import co.novu.Novu;
import co.novu.models.components.*;
Novu novu = Novu.builder().secretKey("<NOVU_SECRET_KEY>").build();
novu.trigger()
.body(TriggerEventRequestDto.builder()
.workflowId("order-shipped")
.to(To2.of(SubscriberPayloadDto.builder().subscriberId("user-123").build()))
.payload({
"orderNumber": "ORD-12345",
"trackingUrl": "https://acme.com/track/123"
})
.build())
.call();
Novu finds the subscriber's linked Telegram chat, renders the message, and sends it through your bot. Verify delivery in Activity or in Telegram.
Telegram is a supported agent provider. Connect your bot to an agent so users can message the bot and get replies in the same chat — without building Telegram integrations yourself.
<Card title="Build agents on Telegram" icon="bot" href="/agents"> Learn how Novu agents work, including managed and custom code agents. </Card>When Telegram is connected to an agent:
See agent conversations for capabilities across all providers.
You can also use the CLI:
npx novu@latest connect
Select your agent and Telegram when prompted. The CLI guides you through bot setup, token entry, and a test message.
Add TelegramConnectButton to your app (see Connect a subscriber's Telegram chat) or request a connection URL from your backend and send users to that link.
After a chat is connected, messages to your bot are handled by your agent. Replies show up in the same Telegram chat.
| Use case | What happens |
|---|---|
| Agent conversation | The user messages your bot and your agent replies in the same chat. |
| Workflow notification | You trigger a workflow with a Chat step and Novu sends a one-way message to the subscriber's linked chat. |
Both can use the same bot and the same connected chat. Your agent can handle back-and-forth conversations while workflows send updates such as order confirmations to the same subscriber.