@mono-agent/telegram-adapter 0.2.1 → 0.2.2

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.
Files changed (48) hide show
  1. package/README.md +2 -0
  2. package/dist/adapter.d.ts +35 -57
  3. package/dist/adapter.d.ts.map +1 -1
  4. package/dist/adapter.js +37 -179
  5. package/dist/adapter.js.map +1 -1
  6. package/dist/bot.d.ts +50 -0
  7. package/dist/bot.d.ts.map +1 -0
  8. package/dist/bot.js +214 -0
  9. package/dist/bot.js.map +1 -0
  10. package/dist/config.d.ts +2 -0
  11. package/dist/config.d.ts.map +1 -1
  12. package/dist/config.js +18 -2
  13. package/dist/config.js.map +1 -1
  14. package/dist/grammy-client.d.ts +14 -0
  15. package/dist/grammy-client.d.ts.map +1 -0
  16. package/dist/grammy-client.js +103 -0
  17. package/dist/grammy-client.js.map +1 -0
  18. package/dist/index.d.ts +11 -10
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +5 -4
  21. package/dist/index.js.map +1 -1
  22. package/dist/message-stream.d.ts +80 -7
  23. package/dist/message-stream.d.ts.map +1 -1
  24. package/dist/message-stream.js +381 -34
  25. package/dist/message-stream.js.map +1 -1
  26. package/dist/start.d.ts +23 -34
  27. package/dist/start.d.ts.map +1 -1
  28. package/dist/start.js +25 -43
  29. package/dist/start.js.map +1 -1
  30. package/dist/telegram-error.d.ts +34 -0
  31. package/dist/telegram-error.d.ts.map +1 -0
  32. package/dist/telegram-error.js +39 -0
  33. package/dist/telegram-error.js.map +1 -0
  34. package/dist/telegram-markdown.d.ts +17 -0
  35. package/dist/telegram-markdown.d.ts.map +1 -0
  36. package/dist/telegram-markdown.js +20 -0
  37. package/dist/telegram-markdown.js.map +1 -0
  38. package/dist/types.d.ts +8 -1
  39. package/dist/types.d.ts.map +1 -1
  40. package/package.json +6 -3
  41. package/dist/long-poller.d.ts +0 -55
  42. package/dist/long-poller.d.ts.map +0 -1
  43. package/dist/long-poller.js +0 -156
  44. package/dist/long-poller.js.map +0 -1
  45. package/dist/telegram-client.d.ts +0 -38
  46. package/dist/telegram-client.d.ts.map +0 -1
  47. package/dist/telegram-client.js +0 -183
  48. package/dist/telegram-client.js.map +0 -1
package/dist/start.d.ts CHANGED
@@ -1,56 +1,45 @@
1
- import { type AgentResponder, type TelegramAdapterLogger, type TelegramAdapterMessages, type TelegramAdapterStreamOptions } from "./adapter.js";
2
- import { type TelegramLongPollerOptions, type TelegramLongPollerStartOptions } from "./long-poller.js";
3
- import { type TelegramBotApiClientOptions } from "./telegram-client.js";
4
- import type { TelegramBotApi, TelegramChatId } from "./types.js";
5
- /**
6
- * Minimal surface a long poller must expose for {@link startTelegramAdapter} to
7
- * drive it. The real {@link TelegramLongPoller} satisfies this, and tests can
8
- * supply a fake via {@link TelegramAdapterStartOptions.pollerFactory}.
9
- */
10
- export interface TelegramPollerLike {
11
- start(options?: TelegramLongPollerStartOptions): Promise<void>;
12
- }
1
+ import type { RunnerHandle } from "@grammyjs/runner";
2
+ import type { Bot } from "grammy";
3
+ import type { AgentResponder, TelegramAdapterLogger, TelegramAdapterMessages, TelegramAdapterStreamOptions } from "./adapter.js";
4
+ import type { TelegramChatId } from "./types.js";
13
5
  export interface TelegramAdapterStartOptions {
14
- /** Bot API token, used to construct the default {@link TelegramBotApiClient}. */
6
+ /** Bot API token used to construct the grammY {@link Bot}. */
15
7
  readonly botToken: string;
16
8
  /** Allowlisted chat ids. Required unless {@link allowAllChats} is true. */
17
9
  readonly allowedChatIds?: readonly TelegramChatId[];
18
10
  /** Explicitly permit every chat. Leave off when using an allowlist. */
19
11
  readonly allowAllChats?: boolean;
20
- /** Responder the adapter routes authorized text updates to. */
12
+ /** Responder the bot routes authorized text messages to. */
21
13
  readonly responder: AgentResponder;
22
- /** Optional per-response stream tuning forwarded to the adapter. */
14
+ /** Optional per-response stream tuning. */
23
15
  readonly stream?: TelegramAdapterStreamOptions;
24
- /** Optional message-copy overrides forwarded to the adapter. */
16
+ /** Optional message-copy overrides. */
25
17
  readonly messages?: TelegramAdapterMessages;
26
- /** Optional logger shared by the adapter, stream, and poller. */
18
+ /** Optional logger shared by the bot and stream. */
27
19
  readonly logger?: TelegramAdapterLogger;
28
- /** Restrict the update types requested from Telegram. Defaults to messages only. */
20
+ /** Restrict the update types polled from Telegram. Defaults to messages only. */
29
21
  readonly allowedUpdates?: readonly string[];
30
22
  /** Delete any configured webhook before polling. Defaults to true. */
31
23
  readonly deleteWebhookOnStart?: boolean;
32
- /**
33
- * Override how the {@link TelegramBotApi} client is built. Defaults to a real
34
- * {@link TelegramBotApiClient}. Tests inject a fake to avoid hitting Telegram.
35
- */
36
- readonly clientFactory?: (options: TelegramBotApiClientOptions) => TelegramBotApi;
37
- /**
38
- * Override how the long poller is built. Defaults to a real
39
- * {@link TelegramLongPoller}. Tests inject a fake to assert wiring and stop.
40
- */
41
- readonly pollerFactory?: (options: TelegramLongPollerOptions) => TelegramPollerLike;
24
+ /** Drop updates queued before start. Defaults to false. */
25
+ readonly dropPendingUpdates?: boolean;
26
+ /** Called when polling crashes after a successful start (lets the host mark the channel failed). */
27
+ readonly onPollingError?: (error: unknown) => void;
28
+ /** Test seam: build the grammY {@link Bot}. */
29
+ readonly botFactory?: (token: string) => Bot;
30
+ /** Test seam: build the polling runner. */
31
+ readonly runnerFactory?: (bot: Bot) => RunnerHandle;
42
32
  }
43
33
  export interface TelegramAdapterStartResult {
44
- /** Stops the long poller cleanly and waits for the polling loop to settle. */
34
+ /** Stops polling and waits for the runner to settle. */
45
35
  stop(): Promise<void>;
46
36
  }
47
37
  /**
48
- * Composition-root entrypoint: builds the Telegram client, adapter, and long
49
- * poller from a single options bag and starts polling. Mirrors the HTTP
50
- * adapters' `startX(options): Promise<{ stop }>` shape so a host can launch
51
- * Telegram with one call.
38
+ * Composition-root entrypoint: builds and starts a grammY-backed Telegram bot
39
+ * from a single options bag. Mirrors the HTTP adapters' `startX(options):
40
+ * Promise<{ stop }>` shape so a host can launch Telegram with one call.
52
41
  *
53
- * Fail-closed: the underlying {@link TelegramAdapter} throws when neither
42
+ * Fail-closed: {@link createTelegramBot} throws when neither
54
43
  * {@link TelegramAdapterStartOptions.allowedChatIds} nor
55
44
  * {@link TelegramAdapterStartOptions.allowAllChats} is provided.
56
45
  */
@@ -1 +1 @@
1
- {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../src/start.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAC5B,KAAK,4BAA4B,EAClC,MAAM,cAAc,CAAC;AACtB,OAAO,EAEL,KAAK,yBAAyB,EAC9B,KAAK,8BAA8B,EACpC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAEL,KAAK,2BAA2B,EACjC,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjE;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,OAAO,CAAC,EAAE,8BAA8B,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChE;AAED,MAAM,WAAW,2BAA2B;IAC1C,iFAAiF;IACjF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IACpD,uEAAuE;IACvE,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,+DAA+D;IAC/D,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC;IACnC,oEAAoE;IACpE,QAAQ,CAAC,MAAM,CAAC,EAAE,4BAA4B,CAAC;IAC/C,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,CAAC,EAAE,uBAAuB,CAAC;IAC5C,iEAAiE;IACjE,QAAQ,CAAC,MAAM,CAAC,EAAE,qBAAqB,CAAC;IACxC,oFAAoF;IACpF,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,sEAAsE;IACtE,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IACxC;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,2BAA2B,KAAK,cAAc,CAAC;IAClF;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,kBAAkB,CAAC;CACrF;AAED,MAAM,WAAW,0BAA0B;IACzC,8EAA8E;IAC9E,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,0BAA0B,CAAC,CA+CrC"}
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../src/start.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAElC,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,uBAAuB,EACvB,4BAA4B,EAC7B,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,2BAA2B;IAC1C,8DAA8D;IAC9D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IACpD,uEAAuE;IACvE,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,4DAA4D;IAC5D,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC;IACnC,2CAA2C;IAC3C,QAAQ,CAAC,MAAM,CAAC,EAAE,4BAA4B,CAAC;IAC/C,uCAAuC;IACvC,QAAQ,CAAC,QAAQ,CAAC,EAAE,uBAAuB,CAAC;IAC5C,oDAAoD;IACpD,QAAQ,CAAC,MAAM,CAAC,EAAE,qBAAqB,CAAC;IACxC,iFAAiF;IACjF,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,sEAAsE;IACtE,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IACxC,2DAA2D;IAC3D,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IACtC,oGAAoG;IACpG,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnD,+CAA+C;IAC/C,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,GAAG,CAAC;IAC7C,2CAA2C;IAC3C,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,YAAY,CAAC;CACrD;AAED,MAAM,WAAW,0BAA0B;IACzC,wDAAwD;IACxD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,0BAA0B,CAAC,CAMrC"}
package/dist/start.js CHANGED
@@ -1,57 +1,39 @@
1
- import { TelegramAdapter, } from "./adapter.js";
2
- import { TelegramLongPoller, } from "./long-poller.js";
3
- import { TelegramBotApiClient, } from "./telegram-client.js";
1
+ import { createTelegramBot } from "./bot.js";
4
2
  /**
5
- * Composition-root entrypoint: builds the Telegram client, adapter, and long
6
- * poller from a single options bag and starts polling. Mirrors the HTTP
7
- * adapters' `startX(options): Promise<{ stop }>` shape so a host can launch
8
- * Telegram with one call.
3
+ * Composition-root entrypoint: builds and starts a grammY-backed Telegram bot
4
+ * from a single options bag. Mirrors the HTTP adapters' `startX(options):
5
+ * Promise<{ stop }>` shape so a host can launch Telegram with one call.
9
6
  *
10
- * Fail-closed: the underlying {@link TelegramAdapter} throws when neither
7
+ * Fail-closed: {@link createTelegramBot} throws when neither
11
8
  * {@link TelegramAdapterStartOptions.allowedChatIds} nor
12
9
  * {@link TelegramAdapterStartOptions.allowAllChats} is provided.
13
10
  */
14
11
  export async function startTelegramAdapter(options) {
15
- const buildClient = options.clientFactory ?? ((clientOptions) => new TelegramBotApiClient(clientOptions));
16
- const buildPoller = options.pollerFactory ?? ((pollerOptions) => new TelegramLongPoller(pollerOptions));
17
- const api = buildClient({ token: options.botToken });
18
- const adapter = new TelegramAdapter({
19
- api,
12
+ const controller = createTelegramBot(toCreateOptions(options));
13
+ await controller.start();
14
+ return {
15
+ stop: () => controller.stop(),
16
+ };
17
+ }
18
+ function toCreateOptions(options) {
19
+ return {
20
+ botToken: options.botToken,
20
21
  responder: options.responder,
21
- ...(options.allowedChatIds === undefined ? {} : { allowedChatIds: [...options.allowedChatIds] }),
22
+ ...(options.allowedChatIds === undefined ? {} : { allowedChatIds: options.allowedChatIds }),
22
23
  ...(options.allowAllChats === undefined ? {} : { allowAllChats: options.allowAllChats }),
23
24
  ...(options.stream === undefined ? {} : { stream: options.stream }),
24
25
  ...(options.messages === undefined ? {} : { messages: options.messages }),
25
26
  ...(options.logger === undefined ? {} : { logger: options.logger }),
26
- });
27
- const poller = buildPoller({
28
- api,
29
- adapter,
30
- deleteWebhookOnStart: options.deleteWebhookOnStart ?? true,
31
- allowedUpdates: options.allowedUpdates === undefined ? ["message"] : [...options.allowedUpdates],
32
- ...(options.logger === undefined ? {} : { logger: options.logger }),
33
- });
34
- const controller = new AbortController();
35
- const running = poller.start({ signal: controller.signal });
36
- // Surface late polling failures to the shared logger without leaving an
37
- // unhandled rejection; stop() still awaits this same promise.
38
- running.catch((error) => {
39
- if (!controller.signal.aborted) {
40
- options.logger?.error?.("Telegram polling stopped with an error.", {
41
- error: error instanceof Error ? error.message : String(error),
42
- });
43
- }
44
- });
45
- let stopped = false;
46
- return {
47
- async stop() {
48
- if (stopped) {
49
- return;
50
- }
51
- stopped = true;
52
- controller.abort();
53
- await running.catch(() => undefined);
54
- },
27
+ ...(options.allowedUpdates === undefined ? {} : { allowedUpdates: options.allowedUpdates }),
28
+ ...(options.deleteWebhookOnStart === undefined
29
+ ? {}
30
+ : { deleteWebhookOnStart: options.deleteWebhookOnStart }),
31
+ ...(options.dropPendingUpdates === undefined
32
+ ? {}
33
+ : { dropPendingUpdates: options.dropPendingUpdates }),
34
+ ...(options.onPollingError === undefined ? {} : { onPollingError: options.onPollingError }),
35
+ ...(options.botFactory === undefined ? {} : { botFactory: options.botFactory }),
36
+ ...(options.runnerFactory === undefined ? {} : { runnerFactory: options.runnerFactory }),
55
37
  };
56
38
  }
57
39
  //# sourceMappingURL=start.js.map
package/dist/start.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"start.js","sourceRoot":"","sources":["../src/start.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../src/start.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,iBAAiB,EAAiC,MAAM,UAAU,CAAC;AAqC5E;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAoC;IAEpC,MAAM,UAAU,GAAG,iBAAiB,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/D,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC;IACzB,OAAO;QACL,IAAI,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE;KAC9B,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,OAAoC;IAC3D,OAAO;QACL,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,GAAG,CAAC,OAAO,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC;QAC3F,GAAG,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC;QACxF,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;QACnE,GAAG,CAAC,OAAO,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC;QACzE,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;QACnE,GAAG,CAAC,OAAO,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC;QAC3F,GAAG,CAAC,OAAO,CAAC,oBAAoB,KAAK,SAAS;YAC5C,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,oBAAoB,EAAE,OAAO,CAAC,oBAAoB,EAAE,CAAC;QAC3D,GAAG,CAAC,OAAO,CAAC,kBAAkB,KAAK,SAAS;YAC1C,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,kBAAkB,EAAE,OAAO,CAAC,kBAAkB,EAAE,CAAC;QACvD,GAAG,CAAC,OAAO,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC;QAC3F,GAAG,CAAC,OAAO,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC;QAC/E,GAAG,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC;KACzF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Transport-agnostic error type for failed Telegram Bot API calls.
3
+ *
4
+ * The streaming delivery logic ({@link import("./message-stream.js")}) and its
5
+ * recovery policy (`classifyTelegramError`) depend only on this shape, never on
6
+ * how the request was made. The grammY-backed client maps `GrammyError` /
7
+ * `HttpError` onto it, so the delivery layer is unaware of the transport.
8
+ */
9
+ export type TelegramApiErrorKind = "http" | "telegram" | "malformed" | "network" | "aborted";
10
+ export interface TelegramApiErrorDetails {
11
+ kind: TelegramApiErrorKind;
12
+ method: string;
13
+ status?: number;
14
+ errorCode?: number;
15
+ telegramDescription?: string;
16
+ /**
17
+ * How long to wait before retrying, in milliseconds. Lifted from a Telegram
18
+ * `parameters.retry_after` value (seconds) when present. Only the integer is
19
+ * carried — never a raw response body — so bot tokens cannot leak.
20
+ */
21
+ retryAfterMs?: number;
22
+ cause?: unknown;
23
+ }
24
+ export declare class TelegramApiError extends Error {
25
+ readonly kind: TelegramApiErrorKind;
26
+ readonly method: string;
27
+ readonly status?: number;
28
+ readonly errorCode?: number;
29
+ readonly telegramDescription?: string;
30
+ readonly retryAfterMs?: number;
31
+ readonly cause?: unknown;
32
+ constructor(message: string, details: TelegramApiErrorDetails);
33
+ }
34
+ //# sourceMappingURL=telegram-error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram-error.d.ts","sourceRoot":"","sources":["../src/telegram-error.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,oBAAoB,GAC5B,MAAM,GACN,UAAU,GACV,WAAW,GACX,SAAS,GACT,SAAS,CAAC;AAEd,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,oBAAoB,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,SAAkB,KAAK,CAAC,EAAE,OAAO,CAAC;gBAEtB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,uBAAuB;CAqB9D"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Transport-agnostic error type for failed Telegram Bot API calls.
3
+ *
4
+ * The streaming delivery logic ({@link import("./message-stream.js")}) and its
5
+ * recovery policy (`classifyTelegramError`) depend only on this shape, never on
6
+ * how the request was made. The grammY-backed client maps `GrammyError` /
7
+ * `HttpError` onto it, so the delivery layer is unaware of the transport.
8
+ */
9
+ export class TelegramApiError extends Error {
10
+ kind;
11
+ method;
12
+ status;
13
+ errorCode;
14
+ telegramDescription;
15
+ retryAfterMs;
16
+ cause;
17
+ constructor(message, details) {
18
+ super(message);
19
+ this.name = "TelegramApiError";
20
+ this.kind = details.kind;
21
+ this.method = details.method;
22
+ if (details.status !== undefined) {
23
+ this.status = details.status;
24
+ }
25
+ if (details.errorCode !== undefined) {
26
+ this.errorCode = details.errorCode;
27
+ }
28
+ if (details.telegramDescription !== undefined) {
29
+ this.telegramDescription = details.telegramDescription;
30
+ }
31
+ if (details.retryAfterMs !== undefined) {
32
+ this.retryAfterMs = details.retryAfterMs;
33
+ }
34
+ if (details.cause !== undefined) {
35
+ this.cause = details.cause;
36
+ }
37
+ }
38
+ }
39
+ //# sourceMappingURL=telegram-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram-error.js","sourceRoot":"","sources":["../src/telegram-error.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAwBH,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IAChC,IAAI,CAAuB;IAC3B,MAAM,CAAS;IACf,MAAM,CAAU;IAChB,SAAS,CAAU;IACnB,mBAAmB,CAAU;IAC7B,YAAY,CAAU;IACb,KAAK,CAAW;IAElC,YAAY,OAAe,EAAE,OAAgC;QAC3D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC/B,CAAC;QACD,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACpC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACrC,CAAC;QACD,IAAI,OAAO,CAAC,mBAAmB,KAAK,SAAS,EAAE,CAAC;YAC9C,IAAI,CAAC,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC;QACzD,CAAC;QACD,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YACvC,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;QAC3C,CAAC;QACD,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAChC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC7B,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Render a Markdown string into the MarkdownV2 dialect Telegram accepts with
3
+ * `parse_mode: "MarkdownV2"`.
4
+ *
5
+ * Delegates to `telegramify-markdown`, which parses Markdown with remark and
6
+ * re-serializes it as MarkdownV2 with every reserved character escaped. Unlike a
7
+ * regex converter it cannot emit overlapping or unbalanced entities that
8
+ * Telegram's parser rejects, so the stream's plain-text fallback is reserved for
9
+ * genuinely exceptional input rather than ordinary formatting.
10
+ *
11
+ * The `"escape"` strategy keeps constructs Telegram cannot render (e.g. tables)
12
+ * as escaped literal text instead of dropping them. telegramify appends a
13
+ * trailing newline; it is stripped so callers receive the trimmed shape the rest
14
+ * of the delivery pipeline expects.
15
+ */
16
+ export declare function renderTelegramMarkdown(markdown: string): string;
17
+ //# sourceMappingURL=telegram-markdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram-markdown.d.ts","sourceRoot":"","sources":["../src/telegram-markdown.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE/D"}
@@ -0,0 +1,20 @@
1
+ import telegramify from "telegramify-markdown";
2
+ /**
3
+ * Render a Markdown string into the MarkdownV2 dialect Telegram accepts with
4
+ * `parse_mode: "MarkdownV2"`.
5
+ *
6
+ * Delegates to `telegramify-markdown`, which parses Markdown with remark and
7
+ * re-serializes it as MarkdownV2 with every reserved character escaped. Unlike a
8
+ * regex converter it cannot emit overlapping or unbalanced entities that
9
+ * Telegram's parser rejects, so the stream's plain-text fallback is reserved for
10
+ * genuinely exceptional input rather than ordinary formatting.
11
+ *
12
+ * The `"escape"` strategy keeps constructs Telegram cannot render (e.g. tables)
13
+ * as escaped literal text instead of dropping them. telegramify appends a
14
+ * trailing newline; it is stripped so callers receive the trimmed shape the rest
15
+ * of the delivery pipeline expects.
16
+ */
17
+ export function renderTelegramMarkdown(markdown) {
18
+ return telegramify(markdown, "escape").replace(/\n+$/u, "");
19
+ }
20
+ //# sourceMappingURL=telegram-markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram-markdown.js","sourceRoot":"","sources":["../src/telegram-markdown.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,sBAAsB,CAAC;AAE/C;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,sBAAsB,CAAC,QAAgB;IACrD,OAAO,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAC9D,CAAC"}
package/dist/types.d.ts CHANGED
@@ -57,9 +57,16 @@ export interface TelegramGetUpdatesParams {
57
57
  export interface TelegramDeleteWebhookParams {
58
58
  drop_pending_updates?: boolean;
59
59
  }
60
- export interface TelegramBotApi {
60
+ /**
61
+ * The minimal Telegram surface the streaming delivery layer needs: sending a
62
+ * message and editing it in place. Update polling lives in the grammY runner, so
63
+ * the delivery layer depends only on these two calls.
64
+ */
65
+ export interface TelegramMessageSender {
61
66
  sendMessage(params: TelegramSendMessageParams, options?: TelegramRequestOptions): Promise<TelegramSentMessage>;
62
67
  editMessageText(params: TelegramEditMessageTextParams, options?: TelegramRequestOptions): Promise<TelegramSentMessage | true>;
68
+ }
69
+ export interface TelegramBotApi extends TelegramMessageSender {
63
70
  getUpdates(params: TelegramGetUpdatesParams, options?: TelegramRequestOptions): Promise<TelegramUpdate[]>;
64
71
  deleteWebhook?(params?: TelegramDeleteWebhookParams, options?: TelegramRequestOptions): Promise<true>;
65
72
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,CAAC;AAE7C,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,cAAc,CAAC,EAAE,eAAe,CAAC;IACjC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,MAAM,mBAAmB,GAAG,eAAe,CAAC;AAElD,MAAM,WAAW,sBAAsB;IACrC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,cAAc,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,wBAAwB,CAAC,EAAE,OAAO,CAAC;CACpC;AAED,MAAM,WAAW,6BAA6B;IAC5C,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wBAAwB,CAAC,EAAE,OAAO,CAAC;CACpC;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,2BAA2B;IAC1C,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,CACT,MAAM,EAAE,yBAAyB,EACjC,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAChC,eAAe,CACb,MAAM,EAAE,6BAA6B,EACrC,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;IACvC,UAAU,CACR,MAAM,EAAE,wBAAwB,EAChC,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAC7B,aAAa,CAAC,CACZ,MAAM,CAAC,EAAE,2BAA2B,EACpC,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mono-agent/telegram-adapter",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Telegram communication adapter for host-compatible runtimes.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",
@@ -18,8 +18,11 @@
18
18
  "README.md"
19
19
  ],
20
20
  "dependencies": {
21
- "@mono-agent/agent-contracts": "0.2.1",
22
- "@mono-agent/settings": "0.2.1"
21
+ "@grammyjs/runner": "^2.0.3",
22
+ "@mono-agent/agent-contracts": "0.2.2",
23
+ "@mono-agent/settings": "0.2.2",
24
+ "grammy": "^1.44.0",
25
+ "telegramify-markdown": "^1.3.3"
23
26
  },
24
27
  "publishConfig": {
25
28
  "access": "public"
@@ -1,55 +0,0 @@
1
- import type { TelegramBotApi, TelegramUpdate } from "./types.js";
2
- import type { TelegramUpdateHandlingResult } from "./adapter.js";
3
- export interface TelegramUpdateHandler {
4
- handleUpdate(update: TelegramUpdate): Promise<TelegramUpdateHandlingResult>;
5
- }
6
- export interface TelegramLongPollerBackoffOptions {
7
- initialMs?: number;
8
- maxMs?: number;
9
- }
10
- export interface TelegramLongPollerLogger {
11
- debug?(message: string, metadata?: Record<string, unknown>): void;
12
- info?(message: string, metadata?: Record<string, unknown>): void;
13
- warn?(message: string, metadata?: Record<string, unknown>): void;
14
- error?(message: string, metadata?: Record<string, unknown>): void;
15
- }
16
- export interface TelegramLongPollerOptions {
17
- api: TelegramBotApi;
18
- adapter: TelegramUpdateHandler;
19
- initialOffset?: number;
20
- limit?: number;
21
- timeoutSeconds?: number;
22
- allowedUpdates?: string[];
23
- deleteWebhookOnStart?: boolean;
24
- dropPendingUpdates?: boolean;
25
- backoff?: TelegramLongPollerBackoffOptions;
26
- onError?: (error: unknown) => void | Promise<void>;
27
- logger?: TelegramLongPollerLogger;
28
- }
29
- export interface TelegramLongPollerStartOptions {
30
- signal?: AbortSignal;
31
- }
32
- export interface TelegramLongPollerPollOptions {
33
- signal?: AbortSignal;
34
- }
35
- export declare class TelegramLongPoller {
36
- private readonly api;
37
- private readonly adapter;
38
- private readonly limit;
39
- private readonly timeoutSeconds;
40
- private readonly allowedUpdates;
41
- private readonly deleteWebhookOnStart;
42
- private readonly dropPendingUpdates;
43
- private readonly initialBackoffMs;
44
- private readonly maxBackoffMs;
45
- private readonly onError;
46
- private readonly logger;
47
- private nextUpdateOffset;
48
- constructor(options: TelegramLongPollerOptions);
49
- get nextOffset(): number | undefined;
50
- start(options?: TelegramLongPollerStartOptions): Promise<void>;
51
- pollOnce(options?: TelegramLongPollerPollOptions): Promise<number>;
52
- private buildGetUpdatesParams;
53
- private deleteWebhook;
54
- }
55
- //# sourceMappingURL=long-poller.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"long-poller.d.ts","sourceRoot":"","sources":["../src/long-poller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EAId,cAAc,EACf,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAC;AAEjE,MAAM,WAAW,qBAAqB;IACpC,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,4BAA4B,CAAC,CAAC;CAC7E;AAED,MAAM,WAAW,gCAAgC;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,wBAAwB;IACvC,KAAK,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAClE,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACjE,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACjE,KAAK,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CACnE;AAED,MAAM,WAAW,yBAAyB;IACxC,GAAG,EAAE,cAAc,CAAC;IACpB,OAAO,EAAE,qBAAqB,CAAC;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,OAAO,CAAC,EAAE,gCAAgC,CAAC;IAC3C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,MAAM,CAAC,EAAE,wBAAwB,CAAC;CACnC;AAED,MAAM,WAAW,8BAA8B;IAC7C,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,6BAA6B;IAC5C,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAOD,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAiB;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAChD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAuB;IACtD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAU;IAC/C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAU;IAC7C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyD;IACjF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAC9D,OAAO,CAAC,gBAAgB,CAAqB;gBAEjC,OAAO,EAAE,yBAAyB;IAoC9C,IAAI,UAAU,IAAI,MAAM,GAAG,SAAS,CAEnC;IAEK,KAAK,CAAC,OAAO,GAAE,8BAAmC,GAAG,OAAO,CAAC,IAAI,CAAC;IAkClE,QAAQ,CAAC,OAAO,GAAE,6BAAkC,GAAG,OAAO,CAAC,MAAM,CAAC;IA0B5E,OAAO,CAAC,qBAAqB;YAcf,aAAa;CAgB5B"}
@@ -1,156 +0,0 @@
1
- const DEFAULT_LIMIT = 100;
2
- const DEFAULT_TIMEOUT_SECONDS = 30;
3
- const DEFAULT_INITIAL_BACKOFF_MS = 500;
4
- const DEFAULT_MAX_BACKOFF_MS = 10_000;
5
- export class TelegramLongPoller {
6
- api;
7
- adapter;
8
- limit;
9
- timeoutSeconds;
10
- allowedUpdates;
11
- deleteWebhookOnStart;
12
- dropPendingUpdates;
13
- initialBackoffMs;
14
- maxBackoffMs;
15
- onError;
16
- logger;
17
- nextUpdateOffset;
18
- constructor(options) {
19
- if (options.api === undefined) {
20
- throw new TypeError("TelegramLongPoller requires a Telegram Bot API client.");
21
- }
22
- if (typeof options.adapter?.handleUpdate !== "function") {
23
- throw new TypeError("TelegramLongPoller requires an adapter with handleUpdate().");
24
- }
25
- this.api = options.api;
26
- this.adapter = options.adapter;
27
- this.limit = options.limit ?? DEFAULT_LIMIT;
28
- this.timeoutSeconds = options.timeoutSeconds ?? DEFAULT_TIMEOUT_SECONDS;
29
- this.allowedUpdates = options.allowedUpdates?.slice();
30
- this.deleteWebhookOnStart = options.deleteWebhookOnStart === true;
31
- this.dropPendingUpdates = options.dropPendingUpdates === true;
32
- this.initialBackoffMs =
33
- options.backoff?.initialMs ?? DEFAULT_INITIAL_BACKOFF_MS;
34
- this.maxBackoffMs = options.backoff?.maxMs ?? DEFAULT_MAX_BACKOFF_MS;
35
- this.onError = options.onError;
36
- this.logger = options.logger;
37
- this.nextUpdateOffset = options.initialOffset;
38
- if (!Number.isInteger(this.limit) || this.limit < 1 || this.limit > 100) {
39
- throw new RangeError("TelegramLongPoller limit must be an integer between 1 and 100.");
40
- }
41
- if (!Number.isFinite(this.timeoutSeconds) || this.timeoutSeconds < 0) {
42
- throw new RangeError("TelegramLongPoller timeoutSeconds must be non-negative.");
43
- }
44
- if (!Number.isFinite(this.initialBackoffMs) || this.initialBackoffMs < 0) {
45
- throw new RangeError("TelegramLongPoller initial backoff must be non-negative.");
46
- }
47
- if (!Number.isFinite(this.maxBackoffMs) || this.maxBackoffMs < this.initialBackoffMs) {
48
- throw new RangeError("TelegramLongPoller max backoff must be at least the initial backoff.");
49
- }
50
- }
51
- get nextOffset() {
52
- return this.nextUpdateOffset;
53
- }
54
- async start(options = {}) {
55
- if (isSignalAborted(options.signal)) {
56
- return;
57
- }
58
- if (this.deleteWebhookOnStart) {
59
- await this.deleteWebhook(options.signal);
60
- }
61
- let backoffMs = this.initialBackoffMs;
62
- while (!isSignalAborted(options.signal)) {
63
- try {
64
- const pollOptions = {};
65
- if (options.signal !== undefined) {
66
- pollOptions.signal = options.signal;
67
- }
68
- await this.pollOnce(pollOptions);
69
- backoffMs = this.initialBackoffMs;
70
- }
71
- catch (error) {
72
- if (isSignalAborted(options.signal) || isAbortError(error)) {
73
- return;
74
- }
75
- this.logger?.warn?.("Telegram long polling failed; backing off.", {
76
- error: error instanceof Error ? error.message : String(error),
77
- backoffMs,
78
- });
79
- await this.onError?.(error);
80
- await abortableDelay(backoffMs, options.signal);
81
- backoffMs = Math.min(this.maxBackoffMs, Math.max(backoffMs * 2, 1));
82
- }
83
- }
84
- }
85
- async pollOnce(options = {}) {
86
- if (isSignalAborted(options.signal)) {
87
- throw new DOMException("Telegram polling was aborted.", "AbortError");
88
- }
89
- const params = this.buildGetUpdatesParams();
90
- const requestOptions = {};
91
- if (options.signal !== undefined) {
92
- requestOptions.signal = options.signal;
93
- }
94
- const updates = await this.api.getUpdates(params, requestOptions);
95
- let handled = 0;
96
- for (const update of updates) {
97
- if (isSignalAborted(options.signal)) {
98
- throw new DOMException("Telegram polling was aborted.", "AbortError");
99
- }
100
- await this.adapter.handleUpdate(update);
101
- this.nextUpdateOffset = update.update_id + 1;
102
- handled += 1;
103
- }
104
- return handled;
105
- }
106
- buildGetUpdatesParams() {
107
- const params = {
108
- limit: this.limit,
109
- timeout: this.timeoutSeconds,
110
- };
111
- if (this.nextUpdateOffset !== undefined) {
112
- params.offset = this.nextUpdateOffset;
113
- }
114
- if (this.allowedUpdates !== undefined) {
115
- params.allowed_updates = this.allowedUpdates;
116
- }
117
- return params;
118
- }
119
- async deleteWebhook(signal) {
120
- if (typeof this.api.deleteWebhook !== "function") {
121
- throw new TypeError("TelegramLongPoller deleteWebhookOnStart requires api.deleteWebhook().");
122
- }
123
- const params = {
124
- drop_pending_updates: this.dropPendingUpdates,
125
- };
126
- const requestOptions = {};
127
- if (signal !== undefined) {
128
- requestOptions.signal = signal;
129
- }
130
- await this.api.deleteWebhook(params, requestOptions);
131
- }
132
- }
133
- function isAbortError(error) {
134
- return (error instanceof DOMException && error.name === "AbortError") || (error instanceof Error && error.name === "AbortError");
135
- }
136
- function isSignalAborted(signal) {
137
- return signal?.aborted === true;
138
- }
139
- function abortableDelay(ms, signal) {
140
- if (ms <= 0 || signal?.aborted === true) {
141
- return Promise.resolve();
142
- }
143
- return new Promise((resolve) => {
144
- const timeout = setTimeout(() => {
145
- signal?.removeEventListener("abort", onAbort);
146
- resolve();
147
- }, ms);
148
- const onAbort = () => {
149
- clearTimeout(timeout);
150
- signal?.removeEventListener("abort", onAbort);
151
- resolve();
152
- };
153
- signal?.addEventListener("abort", onAbort, { once: true });
154
- });
155
- }
156
- //# sourceMappingURL=long-poller.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"long-poller.js","sourceRoot":"","sources":["../src/long-poller.ts"],"names":[],"mappings":"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"}