@mastra/telegram 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/README.md +137 -0
- package/package.json +68 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# @mastra/telegram
|
|
2
|
+
|
|
3
|
+
## 0.1.0-alpha.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Added `@mastra/telegram` for connecting Mastra agents to Telegram bots. It supports multiple bots, webhook or polling delivery, commands, and streaming replies, and ships a dual ESM + CJS build. Set `encryptionKey` or `MASTRA_ENCRYPTION_KEY` to encrypt stored bot tokens and webhook secret tokens at rest. ([#19975](https://github.com/mastra-ai/mastra/pull/19975))
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { Mastra } from '@mastra/core';
|
|
11
|
+
import { TelegramProvider } from '@mastra/telegram';
|
|
12
|
+
|
|
13
|
+
const telegram = new TelegramProvider();
|
|
14
|
+
|
|
15
|
+
export const mastra = new Mastra({
|
|
16
|
+
agents: { support },
|
|
17
|
+
channels: { telegram },
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// Paste a BotFather token to connect an agent instantly:
|
|
21
|
+
const result = await telegram.connect('support', { botToken: process.env.TELEGRAM_BOT_TOKEN });
|
|
22
|
+
// → { type: 'immediate', installationId: '...' }
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- Updated dependencies [[`66bbfb5`](https://github.com/mastra-ai/mastra/commit/66bbfb5f05b473d39f88c0e4a481ccac41634f3a)]:
|
|
28
|
+
- @mastra/core@1.58.0-alpha.10
|
package/README.md
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# @mastra/telegram
|
|
2
|
+
|
|
3
|
+
Telegram channel wrapper for Mastra — a `ChannelProvider` (`@mastra/core/channels`) over **[`@chat-adapter/telegram`](https://www.npmjs.com/package/@chat-adapter/telegram)** (`^4.34.0`, aligned with the `@chat-adapter/*` version the monorepo builds against), to parity with `@mastra/slack`.
|
|
4
|
+
|
|
5
|
+
The adapter already handles the Bot API transport (webhook parse, send/edit, typing, rich messages, inline keyboards). This package adds the install/lifecycle layer: a multi-bot token store, `setWebhook` + secret-token verification, `setMyCommands`, and Mastra route/stream wiring.
|
|
6
|
+
|
|
7
|
+
**Shape (how Telegram differs from Slack):** no OAuth, no Ed25519, no app-factory. The BotFather token _is_ the credential — one token per bot, one bot per agent.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @mastra/telegram
|
|
13
|
+
# peer: @mastra/core — channels require >= 1.22.0
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import { Mastra } from '@mastra/core';
|
|
20
|
+
import { TelegramProvider } from '@mastra/telegram';
|
|
21
|
+
|
|
22
|
+
const telegram = new TelegramProvider({
|
|
23
|
+
baseUrl: 'https://your-app.example.com', // for setWebhook; auto-detected from the Mastra server if omitted
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export const mastra = new Mastra({
|
|
27
|
+
agents: { support },
|
|
28
|
+
channels: { telegram },
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// Paste a BotFather token to connect an agent instantly:
|
|
32
|
+
const result = await telegram.connect('support', { botToken: process.env.TELEGRAM_BOT_TOKEN });
|
|
33
|
+
// → { type: 'immediate', installationId: '...' }
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## The connect flow
|
|
37
|
+
|
|
38
|
+
`connect(agentId, options?)` returns a discriminated `ChannelConnectResult` — Telegram never uses OAuth:
|
|
39
|
+
|
|
40
|
+
| Call | Result | Meaning |
|
|
41
|
+
| --------------------------- | ------------------------------------------------------ | --------------------------------------------------------------------------------------- |
|
|
42
|
+
| `connect(id, { botToken })` | `{ type: 'immediate' }` | Token validated via `getMe`; the bot is live. |
|
|
43
|
+
| `connect(id)` | `{ type: 'deep_link', url: 'https://t.me/botfather' }` | No token yet — open BotFather, run `/newbot`, then call `connect` again with the token. |
|
|
44
|
+
|
|
45
|
+
`connect` is idempotent per agent: a pending install upgrades to active (same id/webhook) when the token arrives, and re-connecting an already-active agent throws (disconnect first). **One bot = one agent.**
|
|
46
|
+
|
|
47
|
+
## Webhook vs polling
|
|
48
|
+
|
|
49
|
+
Setting a webhook and long-polling `getUpdates` are mutually exclusive; the provider manages the switch per bot via the `mode` option:
|
|
50
|
+
|
|
51
|
+
- `auto` (default) — webhook when a `baseUrl` is available, otherwise polling.
|
|
52
|
+
- `webhook` — register `setWebhook` (requires a `baseUrl`).
|
|
53
|
+
- `polling` — clear any webhook first, then long-poll.
|
|
54
|
+
|
|
55
|
+
In polling mode the adapter's `getUpdates` loop starts automatically once the agent is wired (tune it with `longPolling`); `disconnect()` stops it.
|
|
56
|
+
|
|
57
|
+
In webhook mode the provider mounts one route, `POST /telegram/events/:webhookId`, and verifies the `X-Telegram-Bot-Api-Secret-Token` header (constant-time) on **every** request before delegating to the agent. The per-bot secret is generated automatically and never travels in the URL.
|
|
58
|
+
|
|
59
|
+
## Commands
|
|
60
|
+
|
|
61
|
+
Commands are published via `setMyCommands` and default to the conventional `/start` `/help` `/settings` seed. Override per agent or provider-wide:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
await telegram.connect('support', {
|
|
65
|
+
botToken,
|
|
66
|
+
commands: ['/ask', { command: 'summarize', description: 'Summarize a link' }],
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Names are normalized to the Bot API constraints (lowercase `[a-z0-9_]`, 1-32 chars; description 1-256).
|
|
71
|
+
|
|
72
|
+
## Streaming
|
|
73
|
+
|
|
74
|
+
Telegram has no native token streaming. With `streaming: true` (default) the reply is chunk-edited via `editMessageText` (4096-char cap handled by the adapter), and `typingStatus: true` (default) keeps a `sendChatAction` indicator alive. Set either to `false` to disable.
|
|
75
|
+
|
|
76
|
+
## Configuration
|
|
77
|
+
|
|
78
|
+
`new TelegramProvider(config)`:
|
|
79
|
+
|
|
80
|
+
| Option | Default | Notes |
|
|
81
|
+
| ---------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
|
|
82
|
+
| `baseUrl` | Mastra server config | Public HTTPS base for `setWebhook`. |
|
|
83
|
+
| `storage` | Mastra channels storage, else in-memory | Installation persistence (`ChannelsStorage`). |
|
|
84
|
+
| `encryptionKey` | `MASTRA_ENCRYPTION_KEY` env | Encrypts `botToken`/`secretToken` at rest with AES-256-GCM when set; otherwise they are stored in plaintext. |
|
|
85
|
+
| `apiBaseUrl` | `https://api.telegram.org` | Override for a self-hosted Bot API server. |
|
|
86
|
+
| `mode` | `auto` | `auto` \| `webhook` \| `polling`. |
|
|
87
|
+
| `allowedUpdates` | message, edited_message, channel_post, callback_query, message_reaction | Passed to `setWebhook`. |
|
|
88
|
+
| `longPolling` | adapter defaults | Poll-loop tuning (`timeout`, `limit`, `retryDelayMs`…) for polling mode. |
|
|
89
|
+
| `commands` | `/start /help /settings` | Default command seed. |
|
|
90
|
+
| `commandScope` | Telegram default | `BotCommandScope` for `setMyCommands`. |
|
|
91
|
+
| `streaming` | `true` | Post-and-edit reply streaming. |
|
|
92
|
+
| `typingStatus` | `true` | Typing keepalive. |
|
|
93
|
+
| `toolDisplay` | `'text'` | How tool calls render. Telegram has no Block Kit, so `'cards'`/`'grouped'`/`'timeline'` degrade to text. |
|
|
94
|
+
| `waitUntil` | — | Keep serverless invocations alive (Vercel/Lambda). |
|
|
95
|
+
|
|
96
|
+
### AgentChannels passthrough
|
|
97
|
+
|
|
98
|
+
These forward to the agent's `AgentChannels` (the same curated subset `@mastra/slack` exposes); each falls back to anything the agent author already configured:
|
|
99
|
+
|
|
100
|
+
| Option | Notes |
|
|
101
|
+
| --------------------------------- | ------------------------------------------------------------------------ |
|
|
102
|
+
| `handlers` | Override `onDirectMessage` / `onMention` / `onSubscribedMessage`. |
|
|
103
|
+
| `inlineMedia` | Which media types are sent inline to the model (Telegram photos, PDFs…). |
|
|
104
|
+
| `inlineLinks` | Promote URLs in messages to file parts. |
|
|
105
|
+
| `tools` | Expose reaction tools (`add_reaction`/`remove_reaction`). Default on. |
|
|
106
|
+
| `state` | State adapter for dedup, locking, subscriptions. |
|
|
107
|
+
| `threadContext` | Fetch recent messages when joining a thread mid-conversation. |
|
|
108
|
+
| `chatOptions` | Passthrough to the underlying Chat SDK. |
|
|
109
|
+
| `resolveResourceId` | Choose memory ownership for a thread. |
|
|
110
|
+
| `cors` / `formatError` / `logger` | Webhook-route CORS, error rendering, adapter logger. |
|
|
111
|
+
| `resolveWaitUntil` | Resolve `waitUntil` from the request context. |
|
|
112
|
+
| `onInstall` | Called after an agent connects and the install is persisted. |
|
|
113
|
+
|
|
114
|
+
## Formatting & interactivity
|
|
115
|
+
|
|
116
|
+
Message rendering is owned by the adapter, not this provider — so there is no double-escaping to worry about:
|
|
117
|
+
|
|
118
|
+
- **MarkdownV2** — the adapter emits `parse_mode: MarkdownV2` with context-aware escaping. Return `{ raw: '…' }` from a card to ship a pre-escaped string yourself.
|
|
119
|
+
- **Inline keyboards** — supported via the adapter's card buttons. Telegram caps `callback_data` at **64 bytes**, so keep button ids/values short; rich elements beyond buttons render as fallback text.
|
|
120
|
+
- **Reactions** — enabled through `tools` (`add_reaction`/`remove_reaction`); `message_reaction` updates are requested by default.
|
|
121
|
+
|
|
122
|
+
## Module format
|
|
123
|
+
|
|
124
|
+
Dual **ESM + CJS**. `@chat-adapter/telegram` is ESM-only (its `exports` declares only an `import` condition), and tsup externalises `dependencies` by default — so the adapter is kept external in the ESM build (lean, deduped) but bundled into the CJS output via `noExternal`. Both `import` and `require('@mastra/telegram')` therefore work. See `tsup.config.ts` for why this intentionally differs from `channels/slack`.
|
|
125
|
+
|
|
126
|
+
## Development
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
pnpm install
|
|
130
|
+
pnpm --filter @mastra/telegram typecheck
|
|
131
|
+
pnpm --filter @mastra/telegram test # vitest, undici-mocked Bot API
|
|
132
|
+
pnpm --filter @mastra/telegram build # tsup → dist
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## License
|
|
136
|
+
|
|
137
|
+
Apache-2.0
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mastra/telegram",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"description": "Telegram integration for Mastra agents — a ChannelProvider over @chat-adapter/telegram with webhooks, secret verification, commands, and streaming replies",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"CHANGELOG.md"
|
|
12
|
+
],
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"import": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"default": "./dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"require": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"default": "./dist/index.cjs"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsup",
|
|
27
|
+
"dev": "tsup --watch",
|
|
28
|
+
"typecheck": "tsc --noEmit",
|
|
29
|
+
"test": "vitest run",
|
|
30
|
+
"test:watch": "vitest"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@chat-adapter/telegram": "^4.34.0"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@mastra/core": "workspace:*",
|
|
37
|
+
"@types/node": "^22.20.1",
|
|
38
|
+
"tsup": "^8.5.1",
|
|
39
|
+
"typescript": "catalog:",
|
|
40
|
+
"undici": "^6.0.0",
|
|
41
|
+
"vitest": "^4.1.10"
|
|
42
|
+
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"@mastra/core": ">=1.22.0 <2.0.0"
|
|
45
|
+
},
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public"
|
|
48
|
+
},
|
|
49
|
+
"keywords": [
|
|
50
|
+
"mastra",
|
|
51
|
+
"telegram",
|
|
52
|
+
"chatbot",
|
|
53
|
+
"ai",
|
|
54
|
+
"agent"
|
|
55
|
+
],
|
|
56
|
+
"repository": {
|
|
57
|
+
"type": "git",
|
|
58
|
+
"url": "git+https://github.com/mastra-ai/mastra.git",
|
|
59
|
+
"directory": "channels/telegram"
|
|
60
|
+
},
|
|
61
|
+
"homepage": "https://mastra.ai",
|
|
62
|
+
"bugs": {
|
|
63
|
+
"url": "https://github.com/mastra-ai/mastra/issues"
|
|
64
|
+
},
|
|
65
|
+
"engines": {
|
|
66
|
+
"node": ">=22.13.0"
|
|
67
|
+
}
|
|
68
|
+
}
|