@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.
- package/dist/index.js +54 -39
- 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":
|
|
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": "
|
|
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": "^
|
|
39
|
+
"@spectrum-ts/core": "^9.0.0",
|
|
40
40
|
"typescript": "^5 || ^6.0.0"
|
|
41
41
|
},
|
|
42
42
|
"license": "MIT"
|