@chatman-media/channel-telegram 1.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/LICENSE +21 -0
- package/README.md +22 -0
- package/dist/bot-api/adapter.d.ts +43 -0
- package/dist/bot-api/adapter.d.ts.map +1 -0
- package/dist/bot-api/adapter.test.d.ts +2 -0
- package/dist/bot-api/adapter.test.d.ts.map +1 -0
- package/dist/bot-api/client.d.ts +135 -0
- package/dist/bot-api/client.d.ts.map +1 -0
- package/dist/bot-api/types.d.ts +120 -0
- package/dist/bot-api/types.d.ts.map +1 -0
- package/dist/bot-api/update-parser.d.ts +9 -0
- package/dist/bot-api/update-parser.d.ts.map +1 -0
- package/dist/bot-api/update-parser.test.d.ts +2 -0
- package/dist/bot-api/update-parser.test.d.ts.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33407 -0
- package/dist/userbot/adapter.d.ts +121 -0
- package/dist/userbot/adapter.d.ts.map +1 -0
- package/dist/userbot/login.d.ts +62 -0
- package/dist/userbot/login.d.ts.map +1 -0
- package/package.json +70 -0
- package/src/bot-api/adapter.test.ts +105 -0
- package/src/bot-api/adapter.ts +242 -0
- package/src/bot-api/client.ts +275 -0
- package/src/bot-api/types.ts +134 -0
- package/src/bot-api/update-parser.test.ts +142 -0
- package/src/bot-api/update-parser.ts +112 -0
- package/src/index.ts +38 -0
- package/src/userbot/adapter.ts +517 -0
- package/src/userbot/login.ts +160 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Alexander Kireev
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# @chatman-media/channel-telegram
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@chatman-media/channel-telegram)
|
|
4
|
+
[](https://github.com/chatman-media/lead-engine/actions/workflows/ci.yml)
|
|
5
|
+
[](https://www.typescriptlang.org/)
|
|
6
|
+
[](https://bun.sh/)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
|
|
9
|
+
Telegram channels (Bot API + MTProto userbot) implementing the `ChannelAdapter` contract from `@chatman-media/channel-core`.
|
|
10
|
+
|
|
11
|
+
Part of the [**lead-engine**](https://github.com/chatman-media/lead-engine) monorepo — a multi-tenant SaaS platform for AI sales bots on Telegram / WhatsApp.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
bun add @chatman-media/channel-telegram # Bun
|
|
17
|
+
npm install @chatman-media/channel-telegram # npm / pnpm / yarn
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## License
|
|
21
|
+
|
|
22
|
+
[MIT](LICENSE) — Alexander Kireev / [chatman-media](https://github.com/chatman-media)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ChannelAdapter, ChannelCapabilities, DeleteOpts, EditOpts, Inbound, MediaRef, OutboundEnvelope, Sent } from "@chatman-media/channel-core";
|
|
2
|
+
import { TelegramClient, type TelegramClientOptions } from "./client.ts";
|
|
3
|
+
import type { TgUpdate } from "./types.ts";
|
|
4
|
+
export interface TelegramBotAdapterOptions extends TelegramClientOptions {
|
|
5
|
+
/** Уникальный id канала в платформе (соответствует `channels.id` в БД). */
|
|
6
|
+
id: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Telegram Bot API адаптер. Получает входящие через `pushUpdate()` (HTTP webhook
|
|
10
|
+
* в apps/api дёргает этот метод на каждый incoming POST), отправляет исходящие
|
|
11
|
+
* через TelegramClient.
|
|
12
|
+
*
|
|
13
|
+
* Адаптер не делает rate-limiting и retry сам — это ответственность outbound-
|
|
14
|
+
* dispatcher'а в apps/worker (использует `attempts`/`sent_at` в outbound_queue).
|
|
15
|
+
*/
|
|
16
|
+
export declare class TelegramBotAdapter implements ChannelAdapter {
|
|
17
|
+
readonly kind: "telegram_bot";
|
|
18
|
+
readonly id: string;
|
|
19
|
+
readonly capabilities: ChannelCapabilities;
|
|
20
|
+
private readonly client;
|
|
21
|
+
private readonly inbox;
|
|
22
|
+
private waiters;
|
|
23
|
+
private closed;
|
|
24
|
+
constructor(opts: TelegramBotAdapterOptions);
|
|
25
|
+
/** Доступ к raw-клиенту для admin-операций (setWebhook, getMe, и т.д.). */
|
|
26
|
+
get rawClient(): TelegramClient;
|
|
27
|
+
/**
|
|
28
|
+
* Пушит сырой Telegram update в очередь. Парсится в Inbound; если update
|
|
29
|
+
* нерелевантен (нет сообщения и нет callback_query) — silent drop.
|
|
30
|
+
* Вызывается из HTTP-хэндлера webhook'а.
|
|
31
|
+
*/
|
|
32
|
+
pushUpdate(update: TgUpdate): void;
|
|
33
|
+
private enqueue;
|
|
34
|
+
/** Закрыть стрим: receive() завершится после дренажа очереди. */
|
|
35
|
+
close(): void;
|
|
36
|
+
receive(signal?: AbortSignal): AsyncIterable<Inbound>;
|
|
37
|
+
send(envelope: OutboundEnvelope): Promise<Sent>;
|
|
38
|
+
edit(opts: EditOpts): Promise<void>;
|
|
39
|
+
delete(opts: DeleteOpts): Promise<void>;
|
|
40
|
+
downloadMedia(mediaRef: MediaRef): Promise<Response>;
|
|
41
|
+
signalTyping(externalUserId: string): Promise<void>;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/bot-api/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,mBAAmB,EACnB,UAAU,EACV,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,gBAAgB,EAGhB,IAAI,EACL,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,KAAK,EAAiB,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG1D,MAAM,WAAW,yBAA0B,SAAQ,qBAAqB;IACtE,2EAA2E;IAC3E,EAAE,EAAE,MAAM,CAAC;CACZ;AAgCD;;;;;;;GAOG;AACH,qBAAa,kBAAmB,YAAW,cAAc;IACvD,QAAQ,CAAC,IAAI,EAAG,cAAc,CAAU;IACxC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,YAAY,sBAAuB;IAE5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiB;IACvC,OAAO,CAAC,OAAO,CAAmD;IAClE,OAAO,CAAC,MAAM,CAAS;gBAEX,IAAI,EAAE,yBAAyB;IAK3C,2EAA2E;IAC3E,IAAI,SAAS,IAAI,cAAc,CAE9B;IAED;;;;OAIG;IACH,UAAU,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI;IAMlC,OAAO,CAAC,OAAO;IASf,iEAAiE;IACjE,KAAK,IAAI,IAAI;IAQb,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,aAAa,CAAC,OAAO,CAAC;IAoC/C,IAAI,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IA8D/C,IAAI,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBnC,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAS7C,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAI9C,YAAY,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAK1D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.test.d.ts","sourceRoot":"","sources":["../../src/bot-api/adapter.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { TgFile, TgReplyMarkup, TgSendMessageResult, TgUser } from "./types.ts";
|
|
2
|
+
export type FetchLike = typeof fetch;
|
|
3
|
+
export interface TelegramClientOptions {
|
|
4
|
+
token: string;
|
|
5
|
+
baseUrl?: string;
|
|
6
|
+
fetch?: FetchLike;
|
|
7
|
+
}
|
|
8
|
+
export declare class TelegramApiError extends Error {
|
|
9
|
+
method: string;
|
|
10
|
+
statusCode: number;
|
|
11
|
+
errorCode: number | undefined;
|
|
12
|
+
description: string;
|
|
13
|
+
constructor(method: string, statusCode: number, errorCode: number | undefined, description: string);
|
|
14
|
+
}
|
|
15
|
+
export declare class TelegramClient {
|
|
16
|
+
private readonly token;
|
|
17
|
+
private readonly baseUrl;
|
|
18
|
+
private readonly fetchImpl;
|
|
19
|
+
constructor(opts: TelegramClientOptions);
|
|
20
|
+
private call;
|
|
21
|
+
getMe(): Promise<TgUser>;
|
|
22
|
+
/**
|
|
23
|
+
* Resolve a file_id to a downloadable path. The path returned is
|
|
24
|
+
* appended to `<baseUrl>/file/bot<token>/...` (NOT the regular
|
|
25
|
+
* `<baseUrl>/bot<token>/...` API endpoint) — see `downloadFile` for
|
|
26
|
+
* the right URL shape.
|
|
27
|
+
*/
|
|
28
|
+
getFile(fileId: string): Promise<TgFile>;
|
|
29
|
+
/**
|
|
30
|
+
* Two-step download for any file_id we hold:
|
|
31
|
+
* 1. getFile → returns `file_path`
|
|
32
|
+
* 2. fetch the bytes from `<baseUrl>/file/bot<token>/<file_path>`
|
|
33
|
+
*
|
|
34
|
+
* Returns the raw `Response` so the admin layer can stream the body
|
|
35
|
+
* straight to the browser without buffering. Throws when the file is
|
|
36
|
+
* too large for the Bot Download API (Telegram's ~20 MB cap leaves
|
|
37
|
+
* `file_path` undefined).
|
|
38
|
+
*
|
|
39
|
+
* The token is held privately by the client — the admin endpoint
|
|
40
|
+
* proxies through this helper rather than getting the token directly,
|
|
41
|
+
* so secrets never leave the server.
|
|
42
|
+
*/
|
|
43
|
+
downloadFile(fileId: string): Promise<Response>;
|
|
44
|
+
sendMessage(input: {
|
|
45
|
+
chatId: number | string;
|
|
46
|
+
text: string;
|
|
47
|
+
parseMode?: "MarkdownV2" | "HTML" | "Markdown";
|
|
48
|
+
replyMarkup?: TgReplyMarkup;
|
|
49
|
+
disableWebPagePreview?: boolean;
|
|
50
|
+
replyToMessageId?: number;
|
|
51
|
+
}): Promise<TgSendMessageResult>;
|
|
52
|
+
/**
|
|
53
|
+
* Re-send a photo by file_id. Used by the operator-relay path: when the
|
|
54
|
+
* operator uploads a photo to the ops chat as a reply to a lead card,
|
|
55
|
+
* the webhook hands the largest size's file_id straight to this method
|
|
56
|
+
* — Telegram is happy to re-deliver media we've already seen, no need
|
|
57
|
+
* to download and re-upload bytes.
|
|
58
|
+
*/
|
|
59
|
+
sendPhoto(input: {
|
|
60
|
+
chatId: number | string;
|
|
61
|
+
photoFileId: string;
|
|
62
|
+
caption?: string;
|
|
63
|
+
}): Promise<TgSendMessageResult>;
|
|
64
|
+
sendVideo(input: {
|
|
65
|
+
chatId: number | string;
|
|
66
|
+
videoFileId: string;
|
|
67
|
+
caption?: string;
|
|
68
|
+
}): Promise<TgSendMessageResult>;
|
|
69
|
+
/**
|
|
70
|
+
* Send a video from a local file on disk (not a Telegram `file_id`).
|
|
71
|
+
* Bot API supports this via multipart upload, but our funnel goes through
|
|
72
|
+
* the userbot — implemented as a stub here so the symbol resolves; the
|
|
73
|
+
* real impl lives in `makeUserbotSender` in `userbot.ts` and uses gramjs
|
|
74
|
+
* `sendFile` under the hood.
|
|
75
|
+
*/
|
|
76
|
+
sendLocalVideo(_input: {
|
|
77
|
+
chatId: number | string;
|
|
78
|
+
localFilePath: string;
|
|
79
|
+
caption?: string;
|
|
80
|
+
}): Promise<TgSendMessageResult>;
|
|
81
|
+
sendDocument(input: {
|
|
82
|
+
chatId: number | string;
|
|
83
|
+
documentFileId: string;
|
|
84
|
+
caption?: string;
|
|
85
|
+
}): Promise<TgSendMessageResult>;
|
|
86
|
+
/**
|
|
87
|
+
* Edit a message we previously sent (commonly the lead card after the
|
|
88
|
+
* operator clicks approve/reject — the card stays in the ops chat with
|
|
89
|
+
* the new state visible). `text` replaces the body; `replyMarkup`
|
|
90
|
+
* replaces the inline keyboard (pass `{}` to remove the buttons
|
|
91
|
+
* entirely on a finalized state).
|
|
92
|
+
*/
|
|
93
|
+
editMessageText(input: {
|
|
94
|
+
chatId: number | string;
|
|
95
|
+
messageId: number;
|
|
96
|
+
text: string;
|
|
97
|
+
parseMode?: "MarkdownV2" | "HTML" | "Markdown";
|
|
98
|
+
replyMarkup?: TgReplyMarkup;
|
|
99
|
+
}): Promise<TgSendMessageResult | true>;
|
|
100
|
+
/**
|
|
101
|
+
* Delete a message we previously sent. Used by the admin "delete message"
|
|
102
|
+
* action on the Bot-API channel. Telegram lets a bot delete its own
|
|
103
|
+
* outgoing messages in a private chat with no time limit.
|
|
104
|
+
*/
|
|
105
|
+
deleteMessage(input: {
|
|
106
|
+
chatId: number | string;
|
|
107
|
+
messageId: number;
|
|
108
|
+
}): Promise<true>;
|
|
109
|
+
/**
|
|
110
|
+
* Acknowledge an inline-keyboard click. Telegram requires a response
|
|
111
|
+
* within a few seconds or the spinner on the user's button keeps
|
|
112
|
+
* rotating. Pass `text` to flash a small notification ("Approved!").
|
|
113
|
+
*/
|
|
114
|
+
answerCallbackQuery(input: {
|
|
115
|
+
callbackQueryId: string;
|
|
116
|
+
text?: string;
|
|
117
|
+
showAlert?: boolean;
|
|
118
|
+
}): Promise<true>;
|
|
119
|
+
sendChatAction(input: {
|
|
120
|
+
chatId: number | string;
|
|
121
|
+
action: "typing" | "upload_photo" | "record_video" | "upload_voice" | "upload_document";
|
|
122
|
+
}): Promise<true>;
|
|
123
|
+
setWebhook(input: {
|
|
124
|
+
url: string;
|
|
125
|
+
secretToken?: string;
|
|
126
|
+
allowedUpdates?: string[];
|
|
127
|
+
dropPendingUpdates?: boolean;
|
|
128
|
+
}): Promise<true>;
|
|
129
|
+
deleteWebhook(dropPending?: boolean): Promise<true>;
|
|
130
|
+
getWebhookInfo(): Promise<{
|
|
131
|
+
url: string;
|
|
132
|
+
pending_update_count: number;
|
|
133
|
+
}>;
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/bot-api/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
export interface TgUser {
|
|
2
|
+
id: number;
|
|
3
|
+
is_bot?: boolean;
|
|
4
|
+
first_name?: string;
|
|
5
|
+
last_name?: string;
|
|
6
|
+
username?: string;
|
|
7
|
+
language_code?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface TgChat {
|
|
10
|
+
id: number;
|
|
11
|
+
type: "private" | "group" | "supergroup" | "channel";
|
|
12
|
+
title?: string;
|
|
13
|
+
username?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* One frame of a Telegram photo upload. Telegram delivers an array of
|
|
17
|
+
* sizes per photo (thumbnail / medium / original) — we record the
|
|
18
|
+
* largest for diagnostic purposes; counting is by message, not by size.
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Result of `getFile`. `file_path` is a relative path the Bot File API
|
|
22
|
+
* appends to `https://api.telegram.org/file/bot<TOKEN>/...` to download
|
|
23
|
+
* the bytes. The path is short-lived (~1 hour) and tied to the token.
|
|
24
|
+
*/
|
|
25
|
+
export interface TgFile {
|
|
26
|
+
file_id: string;
|
|
27
|
+
file_unique_id: string;
|
|
28
|
+
file_size?: number;
|
|
29
|
+
/** Relative path. Undefined when the file is too large (Telegram caps
|
|
30
|
+
* download API at ~20 MB). */
|
|
31
|
+
file_path?: string;
|
|
32
|
+
}
|
|
33
|
+
export interface TgPhotoSize {
|
|
34
|
+
file_id: string;
|
|
35
|
+
file_unique_id: string;
|
|
36
|
+
width: number;
|
|
37
|
+
height: number;
|
|
38
|
+
file_size?: number;
|
|
39
|
+
}
|
|
40
|
+
export interface TgVideo {
|
|
41
|
+
file_id: string;
|
|
42
|
+
file_unique_id: string;
|
|
43
|
+
width: number;
|
|
44
|
+
height: number;
|
|
45
|
+
duration: number;
|
|
46
|
+
mime_type?: string;
|
|
47
|
+
file_size?: number;
|
|
48
|
+
}
|
|
49
|
+
export interface TgVoice {
|
|
50
|
+
file_id: string;
|
|
51
|
+
file_unique_id: string;
|
|
52
|
+
duration: number;
|
|
53
|
+
mime_type?: string;
|
|
54
|
+
file_size?: number;
|
|
55
|
+
}
|
|
56
|
+
/** «Кружок» — видео-сообщение Telegram (квадратное короткое видео). */
|
|
57
|
+
export interface TgVideoNote {
|
|
58
|
+
file_id: string;
|
|
59
|
+
file_unique_id: string;
|
|
60
|
+
length: number;
|
|
61
|
+
duration: number;
|
|
62
|
+
file_size?: number;
|
|
63
|
+
}
|
|
64
|
+
export interface TgDocument {
|
|
65
|
+
file_id: string;
|
|
66
|
+
file_unique_id: string;
|
|
67
|
+
file_name?: string;
|
|
68
|
+
mime_type?: string;
|
|
69
|
+
file_size?: number;
|
|
70
|
+
}
|
|
71
|
+
export interface TgMessage {
|
|
72
|
+
message_id: number;
|
|
73
|
+
from?: TgUser;
|
|
74
|
+
chat: TgChat;
|
|
75
|
+
date: number;
|
|
76
|
+
text?: string;
|
|
77
|
+
/** Caption that can accompany media uploads (photo / video / document /
|
|
78
|
+
* voice). Treated as the message's "text" by the persistence layer
|
|
79
|
+
* so RAG / extractors see the candidate's words. */
|
|
80
|
+
caption?: string;
|
|
81
|
+
/** Photo upload — present on photo messages, includes all delivered sizes. */
|
|
82
|
+
photo?: TgPhotoSize[];
|
|
83
|
+
video?: TgVideo;
|
|
84
|
+
voice?: TgVoice;
|
|
85
|
+
/** «Кружок» — видео-сообщение (video note). Для видео-верификации. */
|
|
86
|
+
video_note?: TgVideoNote;
|
|
87
|
+
document?: TgDocument;
|
|
88
|
+
/** When this message is a reply to another, Telegram inlines the
|
|
89
|
+
* parent message here. We use it to detect operator replies to lead
|
|
90
|
+
* cards (matched by the parent's `message_id` against
|
|
91
|
+
* `leads.ops_message_id`). */
|
|
92
|
+
reply_to_message?: TgMessage;
|
|
93
|
+
}
|
|
94
|
+
export interface TgCallbackQuery {
|
|
95
|
+
id: string;
|
|
96
|
+
from: TgUser;
|
|
97
|
+
data?: string;
|
|
98
|
+
message?: TgMessage;
|
|
99
|
+
}
|
|
100
|
+
export interface TgUpdate {
|
|
101
|
+
update_id: number;
|
|
102
|
+
message?: TgMessage;
|
|
103
|
+
edited_message?: TgMessage;
|
|
104
|
+
callback_query?: TgCallbackQuery;
|
|
105
|
+
}
|
|
106
|
+
export interface TgSendMessageResult {
|
|
107
|
+
message_id: number;
|
|
108
|
+
chat: TgChat;
|
|
109
|
+
date: number;
|
|
110
|
+
text?: string;
|
|
111
|
+
}
|
|
112
|
+
export interface TgInlineKeyboardButton {
|
|
113
|
+
text: string;
|
|
114
|
+
url?: string;
|
|
115
|
+
callback_data?: string;
|
|
116
|
+
}
|
|
117
|
+
export interface TgReplyMarkup {
|
|
118
|
+
inline_keyboard?: TgInlineKeyboardButton[][];
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/bot-api/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,MAAM;IACrB,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,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,YAAY,GAAG,SAAS,CAAC;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH;;;;GAIG;AACH,MAAM,WAAW,MAAM;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;mCAC+B;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,uEAAuE;AACvE,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;yDAEqD;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,sEAAsE;IACtE,UAAU,CAAC,EAAE,WAAW,CAAC;IACzB,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB;;;mCAG+B;IAC/B,gBAAgB,CAAC,EAAE,SAAS,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,cAAc,CAAC,EAAE,SAAS,CAAC;IAC3B,cAAc,CAAC,EAAE,eAAe,CAAC;CAClC;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,eAAe,CAAC,EAAE,sBAAsB,EAAE,EAAE,CAAC;CAC9C"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Inbound } from "@chatman-media/channel-core";
|
|
2
|
+
import type { TgUpdate } from "./types.ts";
|
|
3
|
+
/**
|
|
4
|
+
* Маппит сырой Telegram Update в канал-агностичный Inbound (или null если
|
|
5
|
+
* update не относится к диалогу — например, чисто edited_message без изменений
|
|
6
|
+
* нашему пайплайну неинтересен).
|
|
7
|
+
*/
|
|
8
|
+
export declare function parseUpdate(channelId: string, update: TgUpdate): Inbound | null;
|
|
9
|
+
//# sourceMappingURL=update-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-parser.d.ts","sourceRoot":"","sources":["../../src/bot-api/update-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAyB,MAAM,6BAA6B,CAAC;AAClF,OAAO,KAAK,EAA0B,QAAQ,EAAE,MAAM,YAAY,CAAC;AAuEnE;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,GAAG,IAAI,CAkC/E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-parser.test.d.ts","sourceRoot":"","sources":["../../src/bot-api/update-parser.test.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { TelegramBotAdapter, type TelegramBotAdapterOptions, } from "./bot-api/adapter.ts";
|
|
2
|
+
export type { FetchLike, TelegramClientOptions } from "./bot-api/client.ts";
|
|
3
|
+
export { TelegramApiError, TelegramClient } from "./bot-api/client.ts";
|
|
4
|
+
export type { TgCallbackQuery, TgChat, TgDocument, TgFile, TgInlineKeyboardButton, TgMessage, TgPhotoSize, TgReplyMarkup, TgSendMessageResult, TgUpdate, TgUser, TgVideo, TgVoice, } from "./bot-api/types.ts";
|
|
5
|
+
export { parseUpdate } from "./bot-api/update-parser.ts";
|
|
6
|
+
export { TelegramUserbotAdapter, type TelegramUserbotAdapterOptions, type UserbotHealthEvent, type UserbotHealthStatus, } from "./userbot/adapter.ts";
|
|
7
|
+
export { type FinishedUserbotLogin, finishUserbotLogin, type StartedUserbotLogin, startUserbotLogin, submitUserbot2fa, submitUserbotCode, UserbotLoginError, type UserbotLoginErrorCode, } from "./userbot/login.ts";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,KAAK,yBAAyB,GAC/B,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACvE,YAAY,EACV,eAAe,EACf,MAAM,EACN,UAAU,EACV,MAAM,EACN,sBAAsB,EACtB,SAAS,EACT,WAAW,EACX,aAAa,EACb,mBAAmB,EACnB,QAAQ,EACR,MAAM,EACN,OAAO,EACP,OAAO,GACR,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EACL,sBAAsB,EACtB,KAAK,6BAA6B,EAClC,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,GACzB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,KAAK,oBAAoB,EACzB,kBAAkB,EAClB,KAAK,mBAAmB,EACxB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,KAAK,qBAAqB,GAC3B,MAAM,oBAAoB,CAAC"}
|