@spectrum-ts/telegram 9.0.0 → 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 +50 -38
- package/package.json +1 -1
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";
|
|
@@ -908,6 +919,7 @@ const telegram = definePlatform(TELEGRAM_PLATFORM, {
|
|
|
908
919
|
} },
|
|
909
920
|
user: { resolve: resolveUser },
|
|
910
921
|
space: { create: createSpace },
|
|
922
|
+
actions: { getDisplayName: async ({ config }, space) => await getChatDisplayName(config, space.id) },
|
|
911
923
|
messages: handleMessages,
|
|
912
924
|
send
|
|
913
925
|
});
|