@skroz/telegram-bot 1.0.28 → 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/dist/FileUpload.d.ts +14 -0
- package/dist/FileUpload.d.ts.map +1 -0
- package/dist/FileUpload.js +3 -0
- package/dist/FileUpload.js.map +1 -0
- package/dist/ResultAndDescription.d.ts +6 -0
- package/dist/ResultAndDescription.d.ts.map +1 -0
- package/dist/ResultAndDescription.js +6 -0
- package/dist/ResultAndDescription.js.map +1 -0
- package/dist/TelegramTypes.d.ts +885 -0
- package/dist/TelegramTypes.d.ts.map +1 -0
- package/dist/TelegramTypes.js +3 -0
- package/dist/TelegramTypes.js.map +1 -0
- package/dist/index.d.ts +23 -21
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +179 -84
- package/dist/index.js.map +1 -1
- package/dist/index_backup.d.ts +3 -0
- package/dist/index_backup.d.ts.map +1 -0
- package/dist/index_backup.js +433 -0
- package/dist/index_backup.js.map +1 -0
- package/package.json +2 -5
- package/src/FileUpload.ts +13 -0
- package/src/ResultAndDescription.ts +7 -0
- package/src/TelegramTypes.ts +1161 -0
- package/src/index.ts +246 -108
- package/src/index_backup.ts +430 -0
package/src/index.ts
CHANGED
|
@@ -1,22 +1,37 @@
|
|
|
1
|
-
import TelegramApi from '@skroz/telegram-api';
|
|
2
1
|
import {
|
|
2
|
+
TG_AnswerPreCheckoutQueryInput,
|
|
3
|
+
TG_AnswerPreCheckoutQueryResponse,
|
|
3
4
|
TG_BotCommand,
|
|
4
5
|
TG_CallbackQuery,
|
|
5
6
|
TG_ChatResponse,
|
|
7
|
+
TG_CreateInvoiceInput,
|
|
6
8
|
TG_DeleteMessageInput,
|
|
9
|
+
TG_EditMessageCaptionInput,
|
|
10
|
+
TG_EditMessageMediaInput,
|
|
11
|
+
TG_EditMessageTextInput,
|
|
12
|
+
TG_GetFileResponse,
|
|
13
|
+
TG_GetMeResponse,
|
|
14
|
+
TG_GetUpdatesResponse,
|
|
7
15
|
TG_Message,
|
|
8
16
|
TG_PreCheckoutQuery,
|
|
9
17
|
TG_SendActionInput,
|
|
18
|
+
TG_SendMediaGroupInput,
|
|
19
|
+
TG_SendMediaGroupResponse,
|
|
10
20
|
TG_SendMessageInput,
|
|
11
21
|
TG_SendMessageResponse,
|
|
12
22
|
TG_SendPhotoInput,
|
|
23
|
+
TG_SendVideoInput,
|
|
13
24
|
TG_SetMyCommandsResponse,
|
|
14
25
|
TG_SuccessfulPayment,
|
|
15
26
|
TG_Update,
|
|
16
|
-
} from '
|
|
27
|
+
} from './TelegramTypes';
|
|
28
|
+
import ResultAndDescription from './ResultAndDescription';
|
|
17
29
|
|
|
18
30
|
/* eslint-disable @typescript-eslint/naming-convention */
|
|
19
31
|
|
|
32
|
+
const TELEGRAM_MAX_TEXT_LENGTH = 4096; // Максимальная длина текста в телеграм сообщении
|
|
33
|
+
const TELEGRAM_MAX_CAPTION_LENGTH = 1024;
|
|
34
|
+
|
|
20
35
|
/* хранит уникальные колбэки, чтобы исключить повторное нажатие */
|
|
21
36
|
const processedCallbacks = new Set();
|
|
22
37
|
/* разделитель для параметров колбэка */
|
|
@@ -101,64 +116,211 @@ type ExpiresInput = {
|
|
|
101
116
|
onExpire: (resultMessage: TG_Message) => void;
|
|
102
117
|
};
|
|
103
118
|
|
|
104
|
-
/* Тип функции отправки в телеграм */
|
|
105
|
-
/* type TelegramSendFunction<TInput, TResponse> = (
|
|
106
|
-
input: TInput
|
|
107
|
-
) => Promise<TResponse>; */
|
|
108
|
-
|
|
109
|
-
/* Тип типов функций отправки */
|
|
110
|
-
/* type TG_SendFunction =
|
|
111
|
-
| TelegramSendFunction<TG_SendMessageInput, TG_SendMessageResponse>
|
|
112
|
-
| TelegramSendFunction<TG_SendPhotoInput, TG_SendMessageResponse>; */
|
|
113
|
-
// в будущем:
|
|
114
|
-
// | TelegramSendFunction<TG_SendDocumentInput, TG_SendDocumentResponse>
|
|
115
|
-
|
|
116
|
-
// interface TelegramMessageHandler<TInput, TResponse> {
|
|
117
|
-
// send: (input: TInput) => Promise<TResponse>;
|
|
118
|
-
// }
|
|
119
|
-
|
|
120
119
|
class TelegramBot {
|
|
121
120
|
constructor(
|
|
122
121
|
private readonly botToken: string,
|
|
123
|
-
messages: {
|
|
124
|
-
text?: Record<
|
|
125
|
-
string,
|
|
126
|
-
(input: TG_SendMessageInput) => TG_SendMessageInput
|
|
127
|
-
>;
|
|
128
|
-
photo?: Record<string, (input: TG_SendPhotoInput) => TG_SendPhotoInput>;
|
|
129
|
-
},
|
|
130
122
|
private readonly expiresMessageSeconds?: number,
|
|
131
123
|
private readonly protect_content?: boolean
|
|
132
|
-
) {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
124
|
+
) {}
|
|
125
|
+
|
|
126
|
+
/* Отправка данных в Телеграм */
|
|
127
|
+
private async request<T extends { ok: boolean; description?: string }>(
|
|
128
|
+
method: string,
|
|
129
|
+
options: {
|
|
130
|
+
method?: 'GET' | 'POST';
|
|
131
|
+
body?: any;
|
|
132
|
+
queryParams?: Record<string, any>;
|
|
133
|
+
} = {}
|
|
134
|
+
): Promise<T> {
|
|
135
|
+
let url = `https://api.telegram.org/bot${this.botToken}/${method}`;
|
|
136
|
+
if (options.queryParams) {
|
|
137
|
+
const params = new URLSearchParams();
|
|
138
|
+
Object.keys(options.queryParams).forEach((key) => {
|
|
139
|
+
const value = options.queryParams![key];
|
|
140
|
+
if (value !== undefined) {
|
|
141
|
+
params.append(key, String(value));
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
url += `?${params.toString()}`;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const fetchOptions: any = {
|
|
148
|
+
method: options.method || 'POST',
|
|
136
149
|
};
|
|
150
|
+
|
|
151
|
+
if (options.body) {
|
|
152
|
+
fetchOptions.headers = {
|
|
153
|
+
'Content-Type': 'application/json',
|
|
154
|
+
};
|
|
155
|
+
fetchOptions.body = JSON.stringify(options.body);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
try {
|
|
159
|
+
const response = await fetch(url, fetchOptions);
|
|
160
|
+
const data = await response.json();
|
|
161
|
+
return data as T;
|
|
162
|
+
} catch (error: any) {
|
|
163
|
+
// console.error(`Error in ${method}:`, error.message);
|
|
164
|
+
return {
|
|
165
|
+
ok: false,
|
|
166
|
+
description: `Request failed: ${error.message}`,
|
|
167
|
+
} as unknown as T;
|
|
168
|
+
}
|
|
137
169
|
}
|
|
138
170
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
171
|
+
async editMessageText(
|
|
172
|
+
input: TG_EditMessageTextInput
|
|
173
|
+
): Promise<TG_SendMessageResponse> {
|
|
174
|
+
if (input.text && input.text.length > TELEGRAM_MAX_TEXT_LENGTH)
|
|
175
|
+
throw new Error(
|
|
176
|
+
`Текст сообщения не может превышать ${TELEGRAM_MAX_TEXT_LENGTH} символов`
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
return this.request<TG_SendMessageResponse>('editMessageText', {
|
|
180
|
+
body: input,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
async editMessageCaption(
|
|
185
|
+
input: TG_EditMessageCaptionInput
|
|
186
|
+
): Promise<TG_SendMessageResponse> {
|
|
187
|
+
if (input.caption && input.caption.length > TELEGRAM_MAX_CAPTION_LENGTH)
|
|
188
|
+
throw new Error(
|
|
189
|
+
`Подпись не может превышать ${TELEGRAM_MAX_CAPTION_LENGTH} символов`
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
return this.request<TG_SendMessageResponse>('editMessageCaption', {
|
|
193
|
+
body: input,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
async sendVideo(input: TG_SendVideoInput): Promise<TG_SendMessageResponse> {
|
|
198
|
+
if (input.caption && input.caption.length > TELEGRAM_MAX_CAPTION_LENGTH)
|
|
199
|
+
throw new Error(
|
|
200
|
+
`Текст рядом с видео по правилам Телеграм не может превышать ${TELEGRAM_MAX_CAPTION_LENGTH} символов`
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
return this.request<TG_SendMessageResponse>('sendVideo', {
|
|
204
|
+
body: input,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
async editMessageMedia(
|
|
209
|
+
input: TG_EditMessageMediaInput
|
|
210
|
+
): Promise<TG_SendMessageResponse> {
|
|
211
|
+
return this.request<TG_SendMessageResponse>('editMessageMedia', {
|
|
212
|
+
body: input,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
async sendMediaGroup(
|
|
217
|
+
input: TG_SendMediaGroupInput
|
|
218
|
+
): Promise<TG_SendMediaGroupResponse> {
|
|
219
|
+
if (input.media.length < 2)
|
|
220
|
+
throw new Error('Минимум 2 фото для метода sendMediaGroup');
|
|
221
|
+
|
|
222
|
+
const { caption } = input.media[0];
|
|
223
|
+
if (caption && caption.length > TELEGRAM_MAX_CAPTION_LENGTH)
|
|
224
|
+
throw new Error(
|
|
225
|
+
`Текст рядом с фото по правилам Телеграм не может превышать ${TELEGRAM_MAX_CAPTION_LENGTH} символов`
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
return this.request<TG_SendMediaGroupResponse>('sendMediaGroup', {
|
|
229
|
+
body: input,
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
async getMe(): Promise<TG_GetMeResponse> {
|
|
234
|
+
return this.request<TG_GetMeResponse>('getMe', {
|
|
235
|
+
method: 'GET',
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
async setWebhook(webhookUrl: string): Promise<ResultAndDescription> {
|
|
240
|
+
return this.request<ResultAndDescription>('setWebhook', {
|
|
241
|
+
method: 'POST',
|
|
242
|
+
queryParams: { url: webhookUrl },
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
async setMyCommands(
|
|
247
|
+
commands: TG_BotCommand[]
|
|
248
|
+
): Promise<TG_SetMyCommandsResponse> {
|
|
249
|
+
return this.request<TG_SetMyCommandsResponse>('setMyCommands', {
|
|
250
|
+
body: { commands },
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
async getUpdates(offset?: number): Promise<TG_GetUpdatesResponse> {
|
|
255
|
+
return this.request<TG_GetUpdatesResponse>('getUpdates', {
|
|
256
|
+
method: 'GET',
|
|
257
|
+
queryParams: offset ? { offset } : undefined,
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
async deleteWebhook(): Promise<void> {
|
|
262
|
+
const data = await this.request<{ ok: boolean; description?: string }>(
|
|
263
|
+
'deleteWebhook',
|
|
143
264
|
{
|
|
144
|
-
|
|
145
|
-
input: TG_SendMessageInput,
|
|
146
|
-
message?: TG_Message,
|
|
147
|
-
onExpire?: (resultMessage: TG_Message) => void
|
|
148
|
-
) => Promise<TG_SendMessageResponse>;
|
|
265
|
+
method: 'GET',
|
|
149
266
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
267
|
+
);
|
|
268
|
+
if (data.ok) {
|
|
269
|
+
console.log('Вебхук успешно удален');
|
|
270
|
+
} else {
|
|
271
|
+
console.error('Ошибка при удалении вебхука:', data.description);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
async sendChatAction(input: TG_SendActionInput): Promise<boolean> {
|
|
276
|
+
const data = await this.request<{ ok: boolean }>('sendChatAction', {
|
|
277
|
+
body: input,
|
|
278
|
+
});
|
|
279
|
+
return data.ok;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
async getChat(chatId: string | number): Promise<TG_ChatResponse> {
|
|
283
|
+
return this.request<TG_ChatResponse>('getChat', {
|
|
284
|
+
body: { chat_id: chatId },
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
async getFile(fileId: string): Promise<TG_GetFileResponse> {
|
|
289
|
+
const data = await this.request<TG_GetFileResponse>('getFile', {
|
|
290
|
+
method: 'GET',
|
|
291
|
+
queryParams: { file_id: fileId },
|
|
292
|
+
});
|
|
293
|
+
if (!data.ok) {
|
|
294
|
+
throw new Error(`Failed to fetch file: ${data.description}`);
|
|
295
|
+
}
|
|
296
|
+
return data;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
async deleteMessage(input: TG_DeleteMessageInput): Promise<boolean> {
|
|
300
|
+
const data = await this.request<{ ok: boolean }>('deleteMessage', {
|
|
301
|
+
body: input,
|
|
302
|
+
});
|
|
303
|
+
return data.ok;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
async createInvoiceLink(
|
|
307
|
+
input: TG_CreateInvoiceInput
|
|
308
|
+
): Promise<{ ok: boolean; result: string }> {
|
|
309
|
+
return this.request<{ ok: boolean; result: string }>('createInvoiceLink', {
|
|
310
|
+
body: input,
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
async answerPreCheckoutQuery(
|
|
315
|
+
input: TG_AnswerPreCheckoutQueryInput
|
|
316
|
+
): Promise<TG_AnswerPreCheckoutQueryResponse> {
|
|
317
|
+
return this.request<TG_AnswerPreCheckoutQueryResponse>(
|
|
318
|
+
'answerPreCheckoutQuery',
|
|
153
319
|
{
|
|
154
|
-
|
|
155
|
-
input: TG_SendPhotoInput,
|
|
156
|
-
message?: TG_Message,
|
|
157
|
-
onExpire?: (resultMessage: TG_Message) => void
|
|
158
|
-
) => Promise<TG_SendMessageResponse>;
|
|
320
|
+
body: input,
|
|
159
321
|
}
|
|
160
|
-
|
|
161
|
-
}
|
|
322
|
+
);
|
|
323
|
+
}
|
|
162
324
|
|
|
163
325
|
async handleUpdate(
|
|
164
326
|
update: TG_Update,
|
|
@@ -208,14 +370,11 @@ class TelegramBot {
|
|
|
208
370
|
preCheckoutQuery
|
|
209
371
|
);
|
|
210
372
|
|
|
211
|
-
await
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
},
|
|
217
|
-
this.botToken
|
|
218
|
-
);
|
|
373
|
+
await this.answerPreCheckoutQuery({
|
|
374
|
+
pre_checkout_query_id: preCheckoutQuery.id,
|
|
375
|
+
ok,
|
|
376
|
+
error_message,
|
|
377
|
+
});
|
|
219
378
|
return;
|
|
220
379
|
}
|
|
221
380
|
|
|
@@ -245,29 +404,30 @@ class TelegramBot {
|
|
|
245
404
|
let sendResult: TG_SendMessageResponse;
|
|
246
405
|
|
|
247
406
|
const sendPhotoFunction = () =>
|
|
248
|
-
|
|
249
|
-
{
|
|
407
|
+
this.request<TG_SendMessageResponse>('sendPhoto', {
|
|
408
|
+
body: {
|
|
250
409
|
protect_content: this.protect_content, // переписывается инпутом
|
|
251
410
|
parse_mode: 'HTML',
|
|
252
411
|
...input,
|
|
253
412
|
},
|
|
254
|
-
|
|
255
|
-
);
|
|
413
|
+
});
|
|
256
414
|
|
|
257
415
|
if (message) {
|
|
258
416
|
try {
|
|
259
|
-
sendResult = await
|
|
417
|
+
sendResult = await this.request<TG_SendMessageResponse>(
|
|
418
|
+
'editMessageMedia',
|
|
260
419
|
{
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
420
|
+
body: {
|
|
421
|
+
media: {
|
|
422
|
+
type: 'photo',
|
|
423
|
+
media: input.photo as string,
|
|
424
|
+
caption: input.caption,
|
|
425
|
+
parse_mode: 'HTML',
|
|
426
|
+
},
|
|
427
|
+
...input,
|
|
428
|
+
message_id: message.message_id,
|
|
266
429
|
},
|
|
267
|
-
|
|
268
|
-
message_id: message.message_id,
|
|
269
|
-
},
|
|
270
|
-
this.botToken
|
|
430
|
+
}
|
|
271
431
|
);
|
|
272
432
|
} catch (e) {
|
|
273
433
|
sendResult = await sendPhotoFunction();
|
|
@@ -295,26 +455,30 @@ class TelegramBot {
|
|
|
295
455
|
message?: TG_Message,
|
|
296
456
|
onExpire?: (resultMessage: TG_Message) => void
|
|
297
457
|
): Promise<TG_SendMessageResponse> {
|
|
458
|
+
if (input.text.length > TELEGRAM_MAX_TEXT_LENGTH)
|
|
459
|
+
throw new Error(`Текст превышает ${TELEGRAM_MAX_TEXT_LENGTH} символов`);
|
|
460
|
+
|
|
298
461
|
let sendResult: TG_SendMessageResponse;
|
|
299
462
|
|
|
300
463
|
const sendPhotoFunction = () =>
|
|
301
|
-
|
|
302
|
-
{
|
|
464
|
+
this.request<TG_SendMessageResponse>('sendMessage', {
|
|
465
|
+
body: {
|
|
303
466
|
parse_mode: 'HTML',
|
|
304
467
|
protect_content: this.protect_content, // переписывается инпутом
|
|
305
468
|
...input,
|
|
306
469
|
},
|
|
307
|
-
|
|
308
|
-
);
|
|
470
|
+
});
|
|
309
471
|
|
|
310
472
|
if (message) {
|
|
311
473
|
try {
|
|
312
|
-
sendResult = await
|
|
474
|
+
sendResult = await this.request<TG_SendMessageResponse>(
|
|
475
|
+
'editMessageText',
|
|
313
476
|
{
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
477
|
+
body: {
|
|
478
|
+
message_id: message.message_id,
|
|
479
|
+
...input,
|
|
480
|
+
},
|
|
481
|
+
}
|
|
318
482
|
);
|
|
319
483
|
} catch (e) {
|
|
320
484
|
sendResult = await sendPhotoFunction();
|
|
@@ -337,38 +501,12 @@ class TelegramBot {
|
|
|
337
501
|
return sendResult;
|
|
338
502
|
}
|
|
339
503
|
|
|
340
|
-
async getUpdates(offset?: number) {
|
|
341
|
-
return TelegramApi.getUpdates(this.botToken, offset);
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
async setWebhook(webhookUrl: string) {
|
|
345
|
-
return TelegramApi.setWebhook(this.botToken, webhookUrl);
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
async deleteWebhook() {
|
|
349
|
-
return TelegramApi.deleteWebhook(this.botToken);
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
async setMyCommands(
|
|
353
|
-
commands: TG_BotCommand[]
|
|
354
|
-
): Promise<TG_SetMyCommandsResponse> {
|
|
355
|
-
return TelegramApi.setMyCommands(commands, this.botToken);
|
|
356
|
-
}
|
|
357
|
-
|
|
358
504
|
async getChatInfo(telegramId: string | number): Promise<TG_ChatResponse> {
|
|
359
|
-
return
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
async sendChatAction(input: TG_SendActionInput): Promise<boolean> {
|
|
363
|
-
return TelegramApi.sendChatAction(input, this.botToken);
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
async deleteMessage(input: TG_DeleteMessageInput): Promise<boolean> {
|
|
367
|
-
return TelegramApi.deleteMessage(input, this.botToken);
|
|
505
|
+
return this.getChat(telegramId);
|
|
368
506
|
}
|
|
369
507
|
|
|
370
508
|
// генераторы типовых методов
|
|
371
|
-
private wrapTextMessages(
|
|
509
|
+
/* private wrapTextMessages(
|
|
372
510
|
defs: Record<string, (input: TG_SendMessageInput) => TG_SendMessageInput>
|
|
373
511
|
) {
|
|
374
512
|
const result: Record<
|
|
@@ -420,7 +558,7 @@ class TelegramBot {
|
|
|
420
558
|
};
|
|
421
559
|
});
|
|
422
560
|
return result;
|
|
423
|
-
}
|
|
561
|
+
} */
|
|
424
562
|
}
|
|
425
563
|
|
|
426
564
|
export default TelegramBot;
|