@mastra/telegram 0.1.3 → 0.2.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/dist/index.cjs +106 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +51 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +101 -19
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -40,22 +40,50 @@ type TelegramCommand = string | {
|
|
|
40
40
|
*/
|
|
41
41
|
declare const BOTFATHER_DEEP_LINK = "https://t.me/botfather";
|
|
42
42
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* token *is* the credential (one token per bot). Multi-tenancy is therefore a
|
|
47
|
-
* store of bot tokens — see {@link TelegramInstallation}.
|
|
43
|
+
* Self-managed credentials: bot tokens are supplied directly (provider default
|
|
44
|
+
* and/or per-`connect()`) and persisted in the install store. Mutually
|
|
45
|
+
* exclusive with {@link TelegramDelegatedCredentialsConfig}.
|
|
48
46
|
*/
|
|
49
|
-
interface
|
|
47
|
+
interface TelegramSelfManagedCredentialsConfig {
|
|
50
48
|
/**
|
|
51
49
|
* BotFather bot token to use as the default for {@link TelegramProvider.connect}
|
|
52
50
|
* when the caller does not supply one per-agent. Setting this here matches the
|
|
53
51
|
* shape of {@link SlackProvider} / {@link DiscordProvider} and lets the token
|
|
54
|
-
* live
|
|
55
|
-
*
|
|
56
|
-
* {@link TelegramConnectOptions.botToken} wins.
|
|
52
|
+
* live in one place instead of on every `connect()` call site. When both are
|
|
53
|
+
* set, an explicit {@link TelegramConnectOptions.botToken} wins.
|
|
57
54
|
*/
|
|
58
55
|
botToken?: string;
|
|
56
|
+
tokenResolver?: never;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Delegated credentials: an external credential manager (e.g. the Mastra
|
|
60
|
+
* platform) owns the bot token. The provider never persists the token — it
|
|
61
|
+
* asks the resolver for the current token before each Bot API call, so a
|
|
62
|
+
* token re-pasted or rotated upstream takes effect without a restart.
|
|
63
|
+
*
|
|
64
|
+
* The resolver is the single source of truth: a direct `botToken` (config,
|
|
65
|
+
* `configure()`, or per-`connect()`) cannot be combined with it.
|
|
66
|
+
*/
|
|
67
|
+
interface TelegramDelegatedCredentialsConfig {
|
|
68
|
+
/** Resolve the current BotFather bot token on demand. */
|
|
69
|
+
tokenResolver: () => Promise<string>;
|
|
70
|
+
botToken?: never;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* How the provider obtains bot tokens: either directly (`botToken`,
|
|
74
|
+
* self-managed) or via a `tokenResolver` (externally managed) — never both.
|
|
75
|
+
*/
|
|
76
|
+
type TelegramCredentialsConfig = TelegramSelfManagedCredentialsConfig | TelegramDelegatedCredentialsConfig;
|
|
77
|
+
/**
|
|
78
|
+
* Configuration for {@link TelegramProvider}.
|
|
79
|
+
*
|
|
80
|
+
* Telegram has no OAuth and no org-level parent credential: a BotFather bot
|
|
81
|
+
* token *is* the credential (one token per bot). Multi-tenancy is therefore a
|
|
82
|
+
* store of bot tokens — see {@link TelegramInstallation}. Credentials are
|
|
83
|
+
* either self-managed (`botToken`) or delegated (`tokenResolver`), never both
|
|
84
|
+
* — see {@link TelegramCredentialsConfig}.
|
|
85
|
+
*/
|
|
86
|
+
interface TelegramProviderConfigBase {
|
|
59
87
|
/**
|
|
60
88
|
* Public HTTPS base URL used to register per-bot webhooks (`setWebhook`).
|
|
61
89
|
* May be omitted and auto-detected from the Mastra server config, or set later.
|
|
@@ -179,6 +207,8 @@ interface TelegramProviderConfig {
|
|
|
179
207
|
/** Called after an agent successfully connects a bot and the installation is persisted. */
|
|
180
208
|
onInstall?: (installation: TelegramInstallation) => void | Promise<void>;
|
|
181
209
|
}
|
|
210
|
+
/** See {@link TelegramProviderConfigBase} and {@link TelegramCredentialsConfig}. */
|
|
211
|
+
type TelegramProviderConfig = TelegramProviderConfigBase & TelegramCredentialsConfig;
|
|
182
212
|
/** Options accepted by {@link TelegramProvider.connect}. */
|
|
183
213
|
interface TelegramConnectOptions {
|
|
184
214
|
/**
|
|
@@ -212,8 +242,19 @@ interface TelegramInstallation {
|
|
|
212
242
|
webhookId: string;
|
|
213
243
|
/** Whether a bot token has been ingested and validated. */
|
|
214
244
|
status: 'active' | 'pending';
|
|
215
|
-
/**
|
|
245
|
+
/**
|
|
246
|
+
* BotFather bot token — the full credential. Present once ingested in
|
|
247
|
+
* self-managed mode. Absent in delegated mode (`tokenResolver`), where the
|
|
248
|
+
* external credential manager is the single source of truth and the token
|
|
249
|
+
* is never persisted locally.
|
|
250
|
+
*/
|
|
216
251
|
botToken?: string;
|
|
252
|
+
/**
|
|
253
|
+
* Telegram user id of the bot (from `getMe`). Used to detect two agents
|
|
254
|
+
* connecting the same bot when the token itself is not stored (delegated
|
|
255
|
+
* mode).
|
|
256
|
+
*/
|
|
257
|
+
botUserId?: number;
|
|
217
258
|
/**
|
|
218
259
|
* Per-bot webhook shared secret, echoed by Telegram as the
|
|
219
260
|
* `X-Telegram-Bot-Api-Secret-Token` header on every inbound POST.
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/telegram-provider.ts","../src/install-store.ts","../src/telegram-client.ts","../src/commands.ts"],"mappings":";;;;;;;cAWa;;;;;;;KAQD;;;;;cAMC;;;;;UAaI;;EAEf;;EAEA;;;KAIU;EAA6B;EAAiB;;;;;;;cAO7C;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/telegram-provider.ts","../src/install-store.ts","../src/telegram-client.ts","../src/commands.ts"],"mappings":";;;;;;;cAWa;;;;;;;KAQD;;;;;cAMC;;;;;UAaI;;EAEf;;EAEA;;;KAIU;EAA6B;EAAiB;;;;;;;cAO7C;;;;;;UAOI;;;;;;;;EAQf;EAEA;;;;;;;;;;;UAYe;;EAEf,qBAAqB;EACrB;;;;;;KAOU,4BAA4B,uCAAuC;;;;;;;;;;UAW9D;;;;;EAKf;;;;;;EAMA,UAAU;;;;;;;EAOV;;;;;;;EAOA;;;;;;;EAOA,OAAO;;;;;EAKP;;;;;;EAMA,cAAc;;;;;;EAMd,YAAY;;;;;;EAMZ,WAAW;;;;;;EAMX,eAAe;;;;;;;;;EASf,YAAY;;;;;;;EAOZ;;;;;EAYA,WAAW;;EAEX,cAAc;;EAEd,cAAc;;EAEd,QAAQ;;EAER,gBAAgB;;EAEhB,cAAc;;EAEd,oBAAoB;;;;;EAKpB,mBAAmB;;EAEnB,OAAO;;EAEP,cAAc;;;;;;;;EAQd,cAAc;;;;;;;EAOd,QAAQ;;EAER,SAAS;;EAET,aAAa,cAAc,gCAAgC;;;KAIjD,yBAAyB,6BAA6B;;UAGjD;;;;;;EAMf;;EAEA;;;;;;EAMA,WAAW;;;;;;UAOI;;EAEf;;EAEA;;;;;EAKA;;EAEA;;;;;;;EAOA;;;;;;EAMA;;;;;EAKA;;EAEA;;EAEA;;EAEA,WAAW;;EAEX,aAAa;;;;;;;;;;;iBC3QC,6BAA6B,QAAQ,KAAK;EACxD,WAAW;EACX;;;;;;;;;;;;;;;;;;;;;;;;cAiCW,4BAA4B;;WAC9B;EAYT,YAAY,SAAQ;;;;;EAkBpB,SAAS,QAAQ;;;;;;EAejB,aAAa;;EAoBb,WAAW;;;;;;;EA4BL,cAAc;;;;;;;;;EA8Gd,UAAU;IAAe;IAAqB;IAAkB;aAA6B;;;;;;;;;;EA0C7F,QAAQ,iBAAiB,UAAS,yBAA8B,QAAQ;;EAqHxE,WAAW,kBAAkB;;EAkD7B,qBAAqB,QAAQ;;;;;;EAW7B,gBAAgB,kBAAkB,QAAQ;;;;;;EAUhD;;;;;EAQA,WAAW,yBAAyB;;;;;cCrfzB;;;;;;;;cAmBA;;mBAEQ;mBACA;EAFnB,YACmB,SAAS,iBACT;;EAIb,WAAW,kBAAkB,QAAQ;;EAMrC,eAAe,oBAAoB,QAAQ;;EAM3C,KAAK,cAAc,uBAAuB;;EAK1C,QAAQ,QAAQ;;EAMhB,cAAc,kBAAkB;;;iBA8DxB,mBAAmB,SAAS,uBAAuB;;;;;;;;;iBCzD7C,MAAM,kBAAkB,sBAA6C,QAAQ;;UAqBlF;;EAEf;;EAEA;;EAEA;;EAEA;;;;;;;;iBASoB,WACpB,kBACA,SAAS,mBACT,sBACC;;;;;;;iBAemB,cACpB,kBACA,8BACA,sBACC;;UAOc;;EAEf,UAAU;;EAEV,QAAQ;;EAER;;;;;;;iBAQoB,cACpB,kBACA,SAAS,sBACT,sBACC;;;;;;;;iBAea;;;;;;;cC3JH,2BAA2B;;;;;;;;iBAaxB,kBAAkB,cAAc,gCAAgC"}
|
package/dist/index.js
CHANGED
|
@@ -252,6 +252,7 @@ var TelegramInstallStore = class {
|
|
|
252
252
|
#toRecord(install) {
|
|
253
253
|
const data = {
|
|
254
254
|
botToken: this.#enc(install.botToken),
|
|
255
|
+
botUserId: install.botUserId,
|
|
255
256
|
secretToken: this.#enc(install.secretToken),
|
|
256
257
|
username: install.username,
|
|
257
258
|
webhookUrl: install.webhookUrl,
|
|
@@ -276,6 +277,7 @@ var TelegramInstallStore = class {
|
|
|
276
277
|
webhookId: record.webhookId ?? "",
|
|
277
278
|
status: record.status === "active" ? "active" : "pending",
|
|
278
279
|
botToken: this.#dec(data.botToken),
|
|
280
|
+
botUserId: data.botUserId,
|
|
279
281
|
secretToken: this.#dec(data.secretToken),
|
|
280
282
|
username: data.username,
|
|
281
283
|
webhookUrl: data.webhookUrl,
|
|
@@ -346,6 +348,7 @@ var TelegramProvider = class {
|
|
|
346
348
|
#initPromise = null;
|
|
347
349
|
#connectingBotTokens = /* @__PURE__ */ new Set();
|
|
348
350
|
constructor(config = {}) {
|
|
351
|
+
if ("tokenResolver" in config && config.tokenResolver && "botToken" in config && config.botToken) throw new Error("TelegramProvider cannot be constructed with both `botToken` and `tokenResolver` — pick one credential mode (self-managed or delegated).");
|
|
349
352
|
this.#config = config;
|
|
350
353
|
}
|
|
351
354
|
/**
|
|
@@ -420,15 +423,73 @@ var TelegramProvider = class {
|
|
|
420
423
|
}
|
|
421
424
|
}
|
|
422
425
|
async #doInitialize() {
|
|
423
|
-
const
|
|
426
|
+
const store = await this.#getStore();
|
|
427
|
+
const active = (await store.list()).filter((i) => i.status === "active");
|
|
424
428
|
this.#configured = active.length > 0;
|
|
425
429
|
for (const installation of active) try {
|
|
426
|
-
await this.#
|
|
430
|
+
const prepared = await this.#migrateInstallation(installation, store);
|
|
431
|
+
if (!prepared) continue;
|
|
432
|
+
await this.#activateInstallation(prepared);
|
|
427
433
|
} catch (err) {
|
|
428
434
|
console.error(`[Telegram] Failed to restore installation "${installation.id}":`, err);
|
|
429
435
|
}
|
|
430
436
|
}
|
|
431
437
|
/**
|
|
438
|
+
* Bring a stored installation up to the provider's current credential mode.
|
|
439
|
+
*
|
|
440
|
+
* When {@link TelegramProviderConfig.tokenResolver} is configured but the
|
|
441
|
+
* record was written under self-managed mode, the record still carries a
|
|
442
|
+
* `botToken` and may be missing `botUserId`. Left as-is, the adapter would
|
|
443
|
+
* keep using that stale token (bypassing rotation) and duplicate detection
|
|
444
|
+
* would fall back to token comparison. Resolve the current token, verify it
|
|
445
|
+
* points at the same bot, populate `botUserId` if missing, and drop the
|
|
446
|
+
* persisted token so future rotations flow through the resolver.
|
|
447
|
+
*
|
|
448
|
+
* For a legacy record with no `botUserId`, the "same bot" check needs an
|
|
449
|
+
* expected identity — so we `getMe` the stored `botToken` first and compare
|
|
450
|
+
* that identity to the resolver's. A stored-token lookup failure leaves the
|
|
451
|
+
* record untouched (we cannot prove it's still the same bot, and silently
|
|
452
|
+
* assigning `me.id` would let a repointed resolver retarget the install and
|
|
453
|
+
* orphan the old bot's webhook).
|
|
454
|
+
*
|
|
455
|
+
* A resolver failure — or an identity mismatch — is not fatal here: we log
|
|
456
|
+
* and leave the record untouched, so the operator can investigate before
|
|
457
|
+
* connect/disconnect on that installation.
|
|
458
|
+
*/
|
|
459
|
+
async #migrateInstallation(installation, store) {
|
|
460
|
+
if (!this.#config.tokenResolver) return installation;
|
|
461
|
+
const needsMigration = installation.botToken !== void 0 || installation.botUserId === void 0;
|
|
462
|
+
const needsIdentityCheck = installation.botUserId !== void 0;
|
|
463
|
+
if (!needsMigration && !needsIdentityCheck) return installation;
|
|
464
|
+
try {
|
|
465
|
+
const resolved = await this.#config.tokenResolver();
|
|
466
|
+
if (!resolved) return installation;
|
|
467
|
+
const me = await getMe(resolved, this.#apiBaseUrl());
|
|
468
|
+
let expectedBotUserId = installation.botUserId;
|
|
469
|
+
if (expectedBotUserId === void 0 && installation.botToken) try {
|
|
470
|
+
expectedBotUserId = (await getMe(installation.botToken, this.#apiBaseUrl())).id;
|
|
471
|
+
} catch (err) {
|
|
472
|
+
console.warn(`[Telegram] Could not verify stored bot identity for installation "${installation.id}" during delegated-mode migration; leaving the record untouched.`, err);
|
|
473
|
+
return installation;
|
|
474
|
+
}
|
|
475
|
+
if (expectedBotUserId !== void 0 && expectedBotUserId !== me.id) {
|
|
476
|
+
console.warn(`[Telegram] Delegated credential for installation "${installation.id}" now resolves to bot ${me.id} but was bot ${expectedBotUserId}. Disconnect and reconnect the agent to adopt the new bot.`);
|
|
477
|
+
return null;
|
|
478
|
+
}
|
|
479
|
+
if (!needsMigration) return installation;
|
|
480
|
+
const { botToken: _dropped, ...rest } = installation;
|
|
481
|
+
const migrated = {
|
|
482
|
+
...rest,
|
|
483
|
+
botUserId: me.id
|
|
484
|
+
};
|
|
485
|
+
await store.save(migrated);
|
|
486
|
+
return migrated;
|
|
487
|
+
} catch (err) {
|
|
488
|
+
console.warn(`[Telegram] Delegated-mode migration failed for installation "${installation.id}":`, err);
|
|
489
|
+
return installation;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
432
493
|
* Update runtime provider settings. Pass `botToken` to change the default
|
|
433
494
|
* bot token new {@link connect} calls fall back to when none is supplied
|
|
434
495
|
* per-agent (matching {@link SlackProvider.configure}'s rotation pattern);
|
|
@@ -437,6 +498,7 @@ var TelegramProvider = class {
|
|
|
437
498
|
* via {@link connect}/{@link disconnect}.
|
|
438
499
|
*/
|
|
439
500
|
async configure(credentials) {
|
|
501
|
+
if (this.#config.tokenResolver && credentials?.botToken !== void 0) throw new Error("TelegramProvider was constructed with a tokenResolver — bot tokens are managed externally. Remove the tokenResolver to manage credentials manually via configure().");
|
|
440
502
|
if (credentials === null) {
|
|
441
503
|
this.#config = {
|
|
442
504
|
...this.#config,
|
|
@@ -473,7 +535,13 @@ var TelegramProvider = class {
|
|
|
473
535
|
const store = await this.#getStore();
|
|
474
536
|
const existing = await store.getByAgent(agentId);
|
|
475
537
|
if (existing?.status === "active") throw new Error(`Agent "${agentId}" is already connected to Telegram. Disconnect first to reconnect.`);
|
|
476
|
-
|
|
538
|
+
if (this.#config.tokenResolver && options.botToken !== void 0) throw new Error("TelegramProvider was constructed with a tokenResolver — bot tokens are managed externally and cannot be supplied per connect() call.");
|
|
539
|
+
let botToken;
|
|
540
|
+
if (this.#config.tokenResolver) {
|
|
541
|
+
const resolved = await this.#config.tokenResolver();
|
|
542
|
+
if (!resolved) throw new Error("TelegramProvider tokenResolver returned an empty bot token. Attach a Telegram bot credential upstream before connecting an agent.");
|
|
543
|
+
botToken = resolved;
|
|
544
|
+
} else botToken = options.botToken ?? this.#config.botToken;
|
|
477
545
|
if (!botToken) {
|
|
478
546
|
const installationId = existing?.id ?? randomUUID();
|
|
479
547
|
await store.save({
|
|
@@ -497,11 +565,11 @@ var TelegramProvider = class {
|
|
|
497
565
|
this.#connectingBotTokens.add(botToken);
|
|
498
566
|
}
|
|
499
567
|
try {
|
|
568
|
+
const me = await getMe(botToken, this.#apiBaseUrl());
|
|
500
569
|
if (mode === "webhook") {
|
|
501
|
-
const duplicate = (await store.list()).find((i) => i.status === "active" && i.botToken === botToken);
|
|
570
|
+
const duplicate = (await store.list()).find((i) => i.status === "active" && i.agentId !== agentId && (i.botUserId !== void 0 ? i.botUserId === me.id : i.botToken === botToken));
|
|
502
571
|
if (duplicate) throw new Error(`This Telegram bot is already connected to agent "${duplicate.agentId}". Disconnect it before connecting another agent.`);
|
|
503
572
|
}
|
|
504
|
-
const me = await getMe(botToken, this.#apiBaseUrl());
|
|
505
573
|
const installationId = existing?.id ?? randomUUID();
|
|
506
574
|
const webhookId = existing?.webhookId ?? randomUUID();
|
|
507
575
|
const webhookUrl = mode === "webhook" ? `${baseUrl}/${PLATFORM}/events/${webhookId}` : void 0;
|
|
@@ -511,15 +579,16 @@ var TelegramProvider = class {
|
|
|
511
579
|
agentId,
|
|
512
580
|
webhookId,
|
|
513
581
|
status: "active",
|
|
514
|
-
botToken,
|
|
582
|
+
...this.#config.tokenResolver ? {} : { botToken },
|
|
583
|
+
botUserId: me.id,
|
|
515
584
|
secretToken: generateSecretToken(),
|
|
516
585
|
username: options.name ?? me.username ?? me.first_name,
|
|
517
586
|
webhookUrl,
|
|
518
587
|
commands: commands.length ? commands : void 0,
|
|
519
588
|
installedAt: existing?.installedAt ?? /* @__PURE__ */ new Date()
|
|
520
589
|
};
|
|
521
|
-
await this.#registerTransport(installation, mode);
|
|
522
|
-
await this.#registerCommands(installation);
|
|
590
|
+
await this.#registerTransport(installation, mode, botToken);
|
|
591
|
+
await this.#registerCommands(installation, botToken);
|
|
523
592
|
await store.save(installation);
|
|
524
593
|
await this.#activateInstallation(installation);
|
|
525
594
|
this.#configured = true;
|
|
@@ -543,8 +612,18 @@ var TelegramProvider = class {
|
|
|
543
612
|
} catch (err) {
|
|
544
613
|
console.warn(`[Telegram] Failed to stop polling for agent "${agentId}":`, err);
|
|
545
614
|
}
|
|
546
|
-
|
|
547
|
-
|
|
615
|
+
try {
|
|
616
|
+
let botToken;
|
|
617
|
+
if (existing.botToken) botToken = existing.botToken;
|
|
618
|
+
else if (this.#config.tokenResolver) {
|
|
619
|
+
const resolved = await this.#config.tokenResolver();
|
|
620
|
+
if (resolved && existing.botUserId !== void 0) {
|
|
621
|
+
const me = await getMe(resolved, this.#apiBaseUrl());
|
|
622
|
+
if (me.id !== existing.botUserId) console.warn(`[Telegram] Skipping deleteWebhook for agent "${agentId}": resolver now points at bot ${me.id} but this installation was bot ${existing.botUserId}.`);
|
|
623
|
+
else botToken = resolved;
|
|
624
|
+
} else if (resolved) botToken = resolved;
|
|
625
|
+
}
|
|
626
|
+
if (botToken) await deleteWebhook(botToken, true, this.#apiBaseUrl());
|
|
548
627
|
} catch (err) {
|
|
549
628
|
console.warn(`[Telegram] Failed to delete webhook for agent "${agentId}":`, err);
|
|
550
629
|
}
|
|
@@ -618,22 +697,25 @@ var TelegramProvider = class {
|
|
|
618
697
|
if (mode === "auto") return baseUrl ? "webhook" : "polling";
|
|
619
698
|
return mode;
|
|
620
699
|
}
|
|
621
|
-
/**
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
700
|
+
/**
|
|
701
|
+
* Register (or clear) the receive transport for a bot, enforcing the
|
|
702
|
+
* exclusion. The token is passed explicitly — delegated-mode installations
|
|
703
|
+
* do not persist one.
|
|
704
|
+
*/
|
|
705
|
+
async #registerTransport(installation, mode, botToken) {
|
|
706
|
+
if (mode === "webhook" && installation.webhookUrl && installation.secretToken) await setWebhook(botToken, {
|
|
625
707
|
url: installation.webhookUrl,
|
|
626
708
|
secretToken: installation.secretToken,
|
|
627
709
|
allowedUpdates: this.#config.allowedUpdates ?? [...DEFAULT_ALLOWED_UPDATES],
|
|
628
710
|
dropPendingUpdates: true
|
|
629
711
|
}, this.#apiBaseUrl());
|
|
630
|
-
else await deleteWebhook(
|
|
712
|
+
else await deleteWebhook(botToken, true, this.#apiBaseUrl());
|
|
631
713
|
}
|
|
632
714
|
/** Publish the bot's command list (best-effort — a failure won't block connect). */
|
|
633
|
-
async #registerCommands(installation) {
|
|
634
|
-
if (!installation.
|
|
715
|
+
async #registerCommands(installation, botToken) {
|
|
716
|
+
if (!installation.commands?.length) return;
|
|
635
717
|
try {
|
|
636
|
-
await setMyCommands(
|
|
718
|
+
await setMyCommands(botToken, {
|
|
637
719
|
commands: installation.commands,
|
|
638
720
|
scope: this.#config.commandScope
|
|
639
721
|
}, this.#apiBaseUrl());
|
|
@@ -645,7 +727,7 @@ var TelegramProvider = class {
|
|
|
645
727
|
const existing = this.#adapters.get(installation.id);
|
|
646
728
|
if (existing) return existing;
|
|
647
729
|
const adapter = createTelegramAdapter$1({
|
|
648
|
-
botToken: installation.botToken,
|
|
730
|
+
botToken: installation.botToken ?? this.#config.tokenResolver,
|
|
649
731
|
secretToken: installation.secretToken,
|
|
650
732
|
userName: installation.username,
|
|
651
733
|
apiBaseUrl: this.#apiBaseUrl(),
|