# Telegram

Telegram bot integration

- Package: @bijectionhq/telegram
- Category: Messaging
- Status: Preview
- License: Apache-2.0
- Bijection source (repository access required): https://github.com/bijectionhq/telegram/tree/1337ee1addde1af50e535abe94baf5a0af0bd9f7
- Upstream: https://github.com/Re11oy/convex-telegram/tree/9935b4cc115ee8e8199d699fd562e2d34fb0b7a4
- Documentation: https://docs.bijection.com/components/using
- Directory: https://bijection.com/components/telegram

## Get the source

Bijection repository access is required. Request access at https://bijection.com/contact.

```sh
git clone https://github.com/bijectionhq/telegram.git
cd telegram
git checkout 1337ee1addde1af50e535abe94baf5a0af0bd9f7
```

## Before using this component

Read the package README at the recorded revision for setup, dependencies, and API examples. Upstream documentation describes the original package and may differ from the Bijection adaptation. This is a source candidate for evaluation. Catalog inclusion does not establish npm availability or runtime qualification. Check compatibility with your SDK and deployment before adoption. External providers run their own compute.

## Upstream package documentation

Recorded 2026-10-23. This describes convex-telegram; check the Bijection adaptation separately.

convex-telegram is a Convex component that wraps the Telegram Bot API with a fully typed client built on @gramio/types. It provides both outbound messaging via `bot.api.*` from Convex actions and inbound update handling via a registered HTTP webhook route. The component manages webhook registration, secret verification, and typed update dispatching so you can focus on bot logic rather than API plumbing.

### Use cases

- Building a Telegram bot that sends notifications or alerts to users from Convex actions triggered by database changes or scheduled functions
- Receiving and processing user messages or callback queries in a Convex backend without managing webhook infrastructure manually
- Echoing, logging, or storing incoming Telegram messages in a Convex database with typed update payloads
- Creating interactive bots that respond to inline keyboard callback queries with full type safety across the Telegram update object
- Adding Telegram as a communication channel to an existing Convex application without standing up a separate bot service

### How it works

The component exposes a `TelegramBot` class that you instantiate with a reference to the mounted component and optionally a token, webhook secret, and webhook path. The bot token is read from the `TELEGRAM_BOT_TOKEN` environment variable by default. Once instantiated, `bot.api` gives you a typed proxy over every method in the Telegram Bot API, callable from any Convex action.

To receive updates, you call `registerRoutes` in your `convex/http.ts` file. This registers an HTTP route (defaulting to `/telegram/webhook`) that the component uses to accept and verify incoming Telegram updates. The component checks the `X-Telegram-Bot-Api-Secret-Token` header against a stored hash, using either your `TELEGRAM_WEBHOOK_SECRET` env var or a generated secret if unset.

Update routing is handler-based. You pass a `handlers` object to `registerRoutes` where keys correspond to fields on the Telegram update object such as `message` or `callback_query`. An optional `onUpdate` handler runs before any specific handler. After deploying the HTTP route, you call `bot.setupWebhook()` once from a Convex action to register your `CONVEX_SITE_URL`-based webhook URL with Telegram, along with the allowed update types.

The package also ships a test helper compatible with `convex-test` so you can register the component in unit tests without a real deployment.

### Upstream README

# convex-telegram

A Convex component for integrating
[Telegram Bot API](https://core.telegram.org/bots) through typed API client
based on [@gramio/types](https://www.npmjs.com/package/@gramio/types).

## What you can do

- **Send messages** (and call any Bot API method) with the typed `bot.api.*`
  client.
- **Receive updates** (messages, callback queries, …) by registering a webhook
  route and handling typed updates.

## Installation

```bash
pnpm add convex-telegram
# or: npm install convex-telegram
```

## Setup

### 1. Create a bot and set the token

Create a bot with [@BotFather](https://t.me/BotFather)
([docs](https://core.telegram.org/bots/features#botfather)) to get a token, then
set it on your deployment:

```bash
npx convex env set TELEGRAM_BOT_TOKEN <your-bot-token>
```

### 2. Add the component

`convex/convex.config.ts`:

```ts
import { defineApp } from "convex/server";
import telegram from "convex-telegram/convex.config";

const app = defineApp();
app.use(telegram);

export default app;
```

### 3. Create the bot client

`convex/telegram.ts`:

```ts
import { TelegramBot } from "convex-telegram";
import { components } from "./_generated/api";

export const bot = new TelegramBot(components.telegram);
```

You can now [send messages](#sending-messages). To also
[receive messages](#receiving-messages), register a webhook.

## Sending messages

Call any [Bot API method](https://core.telegram.org/bots/api#available-methods)
through `bot.api` from a Convex action or webhook handler:

```ts
import { action } from "./_generated/server";
import { v } from "convex/values";
import { bot } from "./telegram";

export const sendMessage = action({
  args: { chatId: v.union(v.string(), v.float64()), text: v.string() },
  returns: v.null(),
  handler: async (_ctx, args) => {
    await bot.api.sendMessage({ chat_id: args.chatId, text: args.text });
    return null;
  },
});
```

## Receiving messages

To receive [updates](https://core.telegram.org/bots/api#getting-updates) you
register an HTTP route and point Telegram at it.

### 1. Configure a webhook secret (optional)

```bash
npx convex env set TELEGRAM_WEBHOOK_SECRET <random-string>
```

The component always verifies the `X-Telegram-Bot-Api-Secret-Token` header. Set
this to control the secret yourself; when unset, `setupWebhook` generates one and
incoming requests are verified against its stored hash.

### 2. Register the webhook route

`convex/http.ts`:

```ts
import { httpRouter } from "convex/server";
import { registerRoutes } from "convex-telegram";
import { components } from "./_generated/api";
import { bot } from "./telegram";

const http = httpRouter();

registerRoutes(http, components.telegram, {
  handlers: {
    message: async (_ctx, update) => {
      await bot.api.sendMessage({
        chat_id: update.message.chat.id,
        text: "Thanks for the message.",
      });
    },
  },
});

export default http;
```

The route defaults to `/telegram/webhook`.

### 3. Point Telegram at your deployment

Run `setupWebhook` once after deploying the HTTP route:

```ts
import { action } from "./_generated/server";
import { v } from "convex/values";
import { bot } from "./telegram";

export const setupWebhook = action({
  args: {},
  returns: v.object({ botUsername: v.string(), webhookUrl: v.string() }),
  handler: async () => {
    return await bot.setupWebhook({
      allowedUpdates: ["message", "callback_query"],
    });
  },
});
```

`setupWebhook` uses `CONVEX_SITE_URL` to build the webhook URL:

```text
https://<deployment>.convex.site/telegram/webhook
```

Pass `url` to `setupWebhook` if your public webhook URL is not based on
`CONVEX_SITE_URL`.

Handler keys match fields on the
[Telegram update](https://core.telegram.org/bots/api#update) object (`message`,
`callback_query`, …). `onUpdate` runs for every update before specific handlers.

## API Reference

### TelegramBot

```ts
const bot = new TelegramBot(components.telegram, {
  token: "...", // optional, defaults to TELEGRAM_BOT_TOKEN
  webhookSecret: "...", // optional, defaults to TELEGRAM_WEBHOOK_SECRET
  webhookPath: "/telegram/webhook",
});
```

| Method                | Description                                                        |
| --------------------- | ------------------------------------------------------------------ |
| `bot.api`             | Typed [Bot API](https://core.telegram.org/bots/api) client         |
| `bot.setupWebhook()`  | Calls Telegram `setWebhook`, returns `{ botUsername, webhookUrl }` |
| `bot.deleteWebhook()` | Calls Telegram `deleteWebhook`                                     |

### registerRoutes

```ts
registerRoutes(http, components.telegram, {
  webhookPath: "/telegram/webhook",
  onUpdate: async (ctx, update) => { ... },
  handlers: { message: async (ctx, update) => { ... } },
});
```

## Example

A runnable, backend-only example lives in [`example/`](./example). It installs
the component, echoes incoming messages, and stores them in a `messages` table.
See [`example/README.md`](./example/README.md) to run it against a Convex
deployment.

## Testing

Use the package test helper to register the component in
[`convex-test`](https://docs.convex.dev/testing/convex-test):

```ts
import telegram from "convex-telegram/test";

telegram.register(t);
```

## Development

This repo runs the example app against an anonymous local Convex backend (no
account required), which also regenerates component types on change.

```bash
pnpm install
pnpm dev          # run the example app and rebuild the component on change
```

Run the same checks as CI:

```bash
pnpm build
pnpm test
pnpm typecheck
pnpm lint
```

See [CONTRIBUTING.md](./CONTRIBUTING.md) for details.

## License

[Apache-2.0](./LICENSE)