@spectrum-ts/telegram 8.2.2 → 9.1.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.
Files changed (2) hide show
  1. package/dist/index.js +54 -39
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -1,45 +1,9 @@
1
1
  import { UnsupportedError, definePlatform, fusor, toVCard } from "@spectrum-ts/core";
2
- import z from "zod";
3
- import { asAttachment, asCustom, asGroup, asMarkdown, asReaction, asText, asVoice, renderInlineTokens, tracedFetch } from "@spectrum-ts/core/authoring";
4
2
  import { createTelegramClient, editMessageText, getFile, getWebhookInfo, sendChatAction, sendMessageDraft, setMessageReaction, setWebhook } from "@photon-ai/telegram-ts";
3
+ import { asAttachment, asCustom, asGroup, asMarkdown, asReaction, asText, asVoice, renderInlineTokens, tracedFetch } from "@spectrum-ts/core/authoring";
4
+ import z from "zod";
5
5
  import { Marked } from "marked";
6
6
  import { timingSafeEqual } from "node:crypto";
7
- //#region src/config.ts
8
- /**
9
- * The platform identifier — used for ALL THREE of:
10
- *
11
- * - the `definePlatform` name (so `message.platform` / `__platform` and
12
- * the `platformStates` key are this value),
13
- * - the `fusor(...)` routing key the handler is registered under, and
14
- * - the value Fusor tags inbound Telegram events with (`event.platform`).
15
- *
16
- * Spectrum's webhook delivery looks the runtime up by `event.platform` against
17
- * the platform name (`platformStates.get(event.platform)`), while routing is by
18
- * the fusor key — so these MUST be the same string. It must also match Fusor's
19
- * configured platform identifier for Telegram (the `<platform>` path segment
20
- * the webhook is delivered under).
21
- */
22
- const TELEGRAM_PLATFORM = "telegram";
23
- const configSchema = z.object({
24
- /** Bot token from @BotFather (outbound API calls + media downloads). */
25
- botToken: z.string().regex(/^\d+:[A-Za-z0-9_-]+$/, "botToken must be in the form '<id>:<token>'"),
26
- /**
27
- * The `secret_token` passed to `setWebhook`. When present, inbound webhooks
28
- * are verified against the `X-Telegram-Bot-Api-Secret-Token` header; when
29
- * omitted, the check is skipped. Telegram does not HMAC-sign the body, so
30
- * this shared token is the only inbound authentication.
31
- */
32
- webhookSecret: z.string().regex(/^[A-Za-z0-9_-]{1,256}$/).optional(),
33
- /** Override the Bot API base URL. Defaults to `https://api.telegram.org`. */
34
- baseUrl: z.url().default("https://api.telegram.org")
35
- });
36
- /**
37
- * The bot's own numeric id is the prefix of the token (`<id>:<hash>`). Used to
38
- * drop inbound updates the bot itself produced, so a bot never echoes its own
39
- * sends.
40
- */
41
- const botIdFromToken = (botToken) => botToken.split(":")[0] ?? "";
42
- //#endregion
43
7
  //#region src/client.ts
44
8
  const REQUEST_TIMEOUT_MS = 3e4;
45
9
  const TRAILING_SLASHES = /\/+$/;
@@ -117,6 +81,53 @@ const downloadFile = async (config, fileId) => {
117
81
  if (!res.ok) throw new Error(`Telegram media download failed: ${res.status} ${res.statusText}`);
118
82
  return Buffer.from(await res.arrayBuffer());
119
83
  };
84
+ /**
85
+ * A chat's `title` via `getChat`. Only groups/supergroups/channels have one;
86
+ * private chats return a name instead, so those resolve `undefined`.
87
+ */
88
+ const getChatDisplayName = async (config, chatId) => {
89
+ return (await telegramClient(config).post({
90
+ body: { chat_id: chatId },
91
+ throwOnError: true,
92
+ url: "/getChat"
93
+ })).data.result?.title ?? void 0;
94
+ };
95
+ //#endregion
96
+ //#region src/config.ts
97
+ /**
98
+ * The platform identifier — used for ALL THREE of:
99
+ *
100
+ * - the `definePlatform` name (so `message.platform` / `__platform` and
101
+ * the `platformStates` key are this value),
102
+ * - the `fusor(...)` routing key the handler is registered under, and
103
+ * - the value Fusor tags inbound Telegram events with (`event.platform`).
104
+ *
105
+ * Spectrum's webhook delivery looks the runtime up by `event.platform` against
106
+ * the platform name (`platformStates.get(event.platform)`), while routing is by
107
+ * the fusor key — so these MUST be the same string. It must also match Fusor's
108
+ * configured platform identifier for Telegram (the `<platform>` path segment
109
+ * the webhook is delivered under).
110
+ */
111
+ const TELEGRAM_PLATFORM = "telegram";
112
+ const configSchema = z.object({
113
+ /** Bot token from @BotFather (outbound API calls + media downloads). */
114
+ botToken: z.string().regex(/^\d+:[A-Za-z0-9_-]+$/, "botToken must be in the form '<id>:<token>'"),
115
+ /**
116
+ * The `secret_token` passed to `setWebhook`. When present, inbound webhooks
117
+ * are verified against the `X-Telegram-Bot-Api-Secret-Token` header; when
118
+ * omitted, the check is skipped. Telegram does not HMAC-sign the body, so
119
+ * this shared token is the only inbound authentication.
120
+ */
121
+ webhookSecret: z.string().regex(/^[A-Za-z0-9_-]{1,256}$/).optional(),
122
+ /** Override the Bot API base URL. Defaults to `https://api.telegram.org`. */
123
+ baseUrl: z.url().default("https://api.telegram.org")
124
+ });
125
+ /**
126
+ * The bot's own numeric id is the prefix of the token (`<id>:<hash>`). Used to
127
+ * drop inbound updates the bot itself produced, so a bot never echoes its own
128
+ * sends.
129
+ */
130
+ const botIdFromToken = (botToken) => botToken.split(":")[0] ?? "";
120
131
  //#endregion
121
132
  //#region src/inbound/media.ts
122
133
  const DEFAULT_VIDEO_MIME = "video/mp4";
@@ -763,7 +774,10 @@ const send = async ({ space, content, config }) => {
763
774
  case "poll_option":
764
775
  case "effect":
765
776
  case "rename":
766
- case "avatar": throw UnsupportedError.content(content.type, TELEGRAM_PLATFORM);
777
+ case "avatar":
778
+ case "addMember":
779
+ case "removeMember":
780
+ case "leaveSpace": throw UnsupportedError.content(content.type, TELEGRAM_PLATFORM);
767
781
  default: return await sendContent(client, space, content);
768
782
  }
769
783
  };
@@ -905,6 +919,7 @@ const telegram = definePlatform(TELEGRAM_PLATFORM, {
905
919
  } },
906
920
  user: { resolve: resolveUser },
907
921
  space: { create: createSpace },
922
+ actions: { getDisplayName: async ({ config }, space) => await getChatDisplayName(config, space.id) },
908
923
  messages: handleMessages,
909
924
  send
910
925
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spectrum-ts/telegram",
3
- "version": "8.2.2",
3
+ "version": "9.1.0",
4
4
  "description": "Telegram provider for spectrum-ts.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -36,7 +36,7 @@
36
36
  "zod": "^4.2.1"
37
37
  },
38
38
  "peerDependencies": {
39
- "@spectrum-ts/core": "^8.0.0",
39
+ "@spectrum-ts/core": "^9.0.0",
40
40
  "typescript": "^5 || ^6.0.0"
41
41
  },
42
42
  "license": "MIT"