@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
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const indexBackup = {};
|
|
4
|
+
exports.default = indexBackup;
|
|
5
|
+
/*
|
|
6
|
+
import TelegramApi from '@skroz/telegram-api';
|
|
7
|
+
import {
|
|
8
|
+
TG_BotCommand,
|
|
9
|
+
TG_CallbackQuery,
|
|
10
|
+
TG_ChatResponse,
|
|
11
|
+
TG_DeleteMessageInput,
|
|
12
|
+
TG_Message,
|
|
13
|
+
TG_PreCheckoutQuery,
|
|
14
|
+
TG_SendActionInput,
|
|
15
|
+
TG_SendMessageInput,
|
|
16
|
+
TG_SendMessageResponse,
|
|
17
|
+
TG_SendPhotoInput,
|
|
18
|
+
TG_SetMyCommandsResponse,
|
|
19
|
+
TG_SuccessfulPayment,
|
|
20
|
+
TG_Update,
|
|
21
|
+
} from '@skroz/telegram-api/dist/TelegramTypes';
|
|
22
|
+
|
|
23
|
+
/!* eslint-disable @typescript-eslint/naming-convention *!/
|
|
24
|
+
|
|
25
|
+
/!* хранит уникальные колбэки, чтобы исключить повторное нажатие *!/
|
|
26
|
+
const processedCallbacks = new Set();
|
|
27
|
+
/!* разделитель для параметров колбэка *!/
|
|
28
|
+
const callbackDivider = '^:^:^';
|
|
29
|
+
/!* по умолчанию истекающее сообщение *!/
|
|
30
|
+
const expiresSecondsDefault = 5 * 60; // 5 минут
|
|
31
|
+
|
|
32
|
+
/!* не больше 64 символов по документации, внутри защита от повторных кликов *!/
|
|
33
|
+
export const createCallbackData = (
|
|
34
|
+
telegramId: number | string,
|
|
35
|
+
data: (string | number)[]
|
|
36
|
+
): string =>
|
|
37
|
+
[`${Date.now()}_${telegramId}`, ...data].join(callbackDivider).slice(0, 64);
|
|
38
|
+
|
|
39
|
+
/!* не больше 64 символов по документации, внутри защита от повторных кликов *!/
|
|
40
|
+
export const getCallbackData = (data: string): string[] =>
|
|
41
|
+
data.split(callbackDivider).slice(1);
|
|
42
|
+
|
|
43
|
+
const expiredMessagesList: {
|
|
44
|
+
message: TG_Message;
|
|
45
|
+
// user: TG_User;
|
|
46
|
+
expiresAt: number;
|
|
47
|
+
onExpire: (message: TG_Message) => void;
|
|
48
|
+
}[] = [];
|
|
49
|
+
|
|
50
|
+
const pushMessageToExpireList = (
|
|
51
|
+
message: TG_Message,
|
|
52
|
+
// user: TG_User,
|
|
53
|
+
expires: ExpiresInput
|
|
54
|
+
) => {
|
|
55
|
+
const expiresAt =
|
|
56
|
+
Date.now() + (expires.seconds || expiresSecondsDefault) * 1000;
|
|
57
|
+
|
|
58
|
+
expiredMessagesList.push({
|
|
59
|
+
message,
|
|
60
|
+
// user,
|
|
61
|
+
expiresAt,
|
|
62
|
+
onExpire: expires.onExpire,
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// забирает и сразу удаляет
|
|
67
|
+
const shiftExpiredMessages = (): {
|
|
68
|
+
message: TG_Message;
|
|
69
|
+
// user: TG_User;
|
|
70
|
+
// from: TG_User;
|
|
71
|
+
onExpire: (
|
|
72
|
+
message: TG_Message
|
|
73
|
+
// , user: TG_User
|
|
74
|
+
) => void;
|
|
75
|
+
}[] => {
|
|
76
|
+
const now = Date.now();
|
|
77
|
+
const expired = expiredMessagesList.filter((msg) => msg.expiresAt <= now);
|
|
78
|
+
expiredMessagesList.splice(0, expired.length);
|
|
79
|
+
return expired;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
// убираем из списка удаленные сообщения
|
|
83
|
+
const deleteMessageFromExpiringList = (message: TG_Message) => {
|
|
84
|
+
const index = expiredMessagesList.findIndex(
|
|
85
|
+
(msg) => msg.message.message_id === message.message_id
|
|
86
|
+
);
|
|
87
|
+
if (index !== -1) {
|
|
88
|
+
expiredMessagesList.splice(index, 1);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
/!* обрабатываем истекшие сообщения по таймеру *!/
|
|
93
|
+
setInterval(async () => {
|
|
94
|
+
const expired = shiftExpiredMessages();
|
|
95
|
+
if (expired.length > 0) {
|
|
96
|
+
await Promise.all(
|
|
97
|
+
expired.map(async (ex) => {
|
|
98
|
+
await ex.onExpire(ex.message);
|
|
99
|
+
})
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
}, 15000);
|
|
103
|
+
|
|
104
|
+
type ExpiresInput = {
|
|
105
|
+
seconds?: number;
|
|
106
|
+
onExpire: (resultMessage: TG_Message) => void;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
/!* Тип функции отправки в телеграм *!/
|
|
110
|
+
/!* type TelegramSendFunction<TInput, TResponse> = (
|
|
111
|
+
input: TInput
|
|
112
|
+
) => Promise<TResponse>; *!/
|
|
113
|
+
|
|
114
|
+
/!* Тип типов функций отправки *!/
|
|
115
|
+
/!* type TG_SendFunction =
|
|
116
|
+
| TelegramSendFunction<TG_SendMessageInput, TG_SendMessageResponse>
|
|
117
|
+
| TelegramSendFunction<TG_SendPhotoInput, TG_SendMessageResponse>; *!/
|
|
118
|
+
// в будущем:
|
|
119
|
+
// | TelegramSendFunction<TG_SendDocumentInput, TG_SendDocumentResponse>
|
|
120
|
+
|
|
121
|
+
// interface TelegramMessageHandler<TInput, TResponse> {
|
|
122
|
+
// send: (input: TInput) => Promise<TResponse>;
|
|
123
|
+
// }
|
|
124
|
+
|
|
125
|
+
class TelegramBot {
|
|
126
|
+
constructor(
|
|
127
|
+
private readonly botToken: string,
|
|
128
|
+
/!* messages: {
|
|
129
|
+
text?: Record<
|
|
130
|
+
string,
|
|
131
|
+
(input: TG_SendMessageInput) => TG_SendMessageInput
|
|
132
|
+
>;
|
|
133
|
+
photo?: Record<string, (input: TG_SendPhotoInput) => TG_SendPhotoInput>;
|
|
134
|
+
}, *!/
|
|
135
|
+
private readonly expiresMessageSeconds?: number,
|
|
136
|
+
private readonly protect_content?: boolean
|
|
137
|
+
) {
|
|
138
|
+
/!* this.messages = {
|
|
139
|
+
text: this.wrapTextMessages(messages.text ?? {}),
|
|
140
|
+
photo: this.wrapPhotoMessages(messages.photo ?? {}),
|
|
141
|
+
}; *!/
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// публичный контейнер
|
|
145
|
+
/!* readonly messages: {
|
|
146
|
+
text: Record<
|
|
147
|
+
string,
|
|
148
|
+
{
|
|
149
|
+
send: (
|
|
150
|
+
input: TG_SendMessageInput,
|
|
151
|
+
message?: TG_Message,
|
|
152
|
+
onExpire?: (resultMessage: TG_Message) => void
|
|
153
|
+
) => Promise<TG_SendMessageResponse>;
|
|
154
|
+
}
|
|
155
|
+
>;
|
|
156
|
+
photo: Record<
|
|
157
|
+
string,
|
|
158
|
+
{
|
|
159
|
+
send: (
|
|
160
|
+
input: TG_SendPhotoInput,
|
|
161
|
+
message?: TG_Message,
|
|
162
|
+
onExpire?: (resultMessage: TG_Message) => void
|
|
163
|
+
) => Promise<TG_SendMessageResponse>;
|
|
164
|
+
}
|
|
165
|
+
>;
|
|
166
|
+
}; *!/
|
|
167
|
+
|
|
168
|
+
async handleUpdate(
|
|
169
|
+
update: TG_Update,
|
|
170
|
+
handleCallback: (
|
|
171
|
+
callbackQuery: TG_CallbackQuery,
|
|
172
|
+
callbackDataParams: string[]
|
|
173
|
+
) => Promise<void>,
|
|
174
|
+
handleMessage: (message: TG_Message) => void,
|
|
175
|
+
handlePreCheckoutQuery: (
|
|
176
|
+
preCheckoutQuery: TG_PreCheckoutQuery
|
|
177
|
+
) => Promise<{ ok: boolean; error_message?: string }>,
|
|
178
|
+
handleSuccessfulPayment: (
|
|
179
|
+
successfulPayment: TG_SuccessfulPayment,
|
|
180
|
+
message: TG_Message
|
|
181
|
+
) => Promise<void>
|
|
182
|
+
): Promise<void> {
|
|
183
|
+
const callbackQuery = update.callback_query;
|
|
184
|
+
if (callbackQuery) {
|
|
185
|
+
const { data } = callbackQuery;
|
|
186
|
+
|
|
187
|
+
if (!data) {
|
|
188
|
+
// 1. Коллбэк пришел от WebApp
|
|
189
|
+
// 2. Игровая кнопка
|
|
190
|
+
// 3. Кнопка с удаленным сообщением
|
|
191
|
+
return; // todo sendError
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// data - всегда уникален, потому что в начале стоит текущий Date.now()
|
|
195
|
+
if (processedCallbacks.has(data)) {
|
|
196
|
+
// чтобы избежать дублирования нажатия на кнопку
|
|
197
|
+
return; // Уже обработан
|
|
198
|
+
}
|
|
199
|
+
processedCallbacks.add(data);
|
|
200
|
+
|
|
201
|
+
// Удаляем из памяти через 60 секунд
|
|
202
|
+
setTimeout(() => {
|
|
203
|
+
processedCallbacks.delete(data);
|
|
204
|
+
}, 60 * 1000);
|
|
205
|
+
|
|
206
|
+
await handleCallback(callbackQuery, getCallbackData(data));
|
|
207
|
+
}
|
|
208
|
+
/!* Часть оплаты *!/
|
|
209
|
+
const preCheckoutQuery = update.pre_checkout_query;
|
|
210
|
+
if (preCheckoutQuery) {
|
|
211
|
+
/!* Нужно ответить в течение 10 секунд внутри метода или заказ отменяется автоматически *!/
|
|
212
|
+
const { ok, error_message } = await handlePreCheckoutQuery(
|
|
213
|
+
preCheckoutQuery
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
await TelegramApi.answerPreCheckoutQuery(
|
|
217
|
+
{
|
|
218
|
+
pre_checkout_query_id: preCheckoutQuery.id,
|
|
219
|
+
ok,
|
|
220
|
+
error_message,
|
|
221
|
+
},
|
|
222
|
+
this.botToken
|
|
223
|
+
);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/!* обработаем сообщение *!/
|
|
228
|
+
const { message } = update; // его нет, если это нажатие на кнопку callback_query или при редактировании предыдущего сообщения
|
|
229
|
+
|
|
230
|
+
if (message) {
|
|
231
|
+
const { successful_payment } = message;
|
|
232
|
+
if (successful_payment) {
|
|
233
|
+
/!* Успешная оплата *!/
|
|
234
|
+
await handleSuccessfulPayment(successful_payment, message);
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (!callbackQuery) {
|
|
239
|
+
/!* разбираем входящий текст *!/
|
|
240
|
+
await handleMessage(message);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
async sendPhoto(
|
|
246
|
+
input: TG_SendPhotoInput,
|
|
247
|
+
message?: TG_Message,
|
|
248
|
+
onExpire?: (resultMessage: TG_Message) => void
|
|
249
|
+
): Promise<TG_SendMessageResponse> {
|
|
250
|
+
let sendResult: TG_SendMessageResponse;
|
|
251
|
+
|
|
252
|
+
const sendPhotoFunction = () =>
|
|
253
|
+
TelegramApi.sendPhoto(
|
|
254
|
+
{
|
|
255
|
+
protect_content: this.protect_content, // переписывается инпутом
|
|
256
|
+
parse_mode: 'HTML',
|
|
257
|
+
...input,
|
|
258
|
+
},
|
|
259
|
+
this.botToken
|
|
260
|
+
);
|
|
261
|
+
|
|
262
|
+
if (message) {
|
|
263
|
+
try {
|
|
264
|
+
sendResult = await TelegramApi.editMessageMedia(
|
|
265
|
+
{
|
|
266
|
+
media: {
|
|
267
|
+
type: 'photo',
|
|
268
|
+
media: input.photo as string,
|
|
269
|
+
caption: input.caption,
|
|
270
|
+
parse_mode: 'HTML',
|
|
271
|
+
},
|
|
272
|
+
...input,
|
|
273
|
+
message_id: message.message_id,
|
|
274
|
+
},
|
|
275
|
+
this.botToken
|
|
276
|
+
);
|
|
277
|
+
} catch (e) {
|
|
278
|
+
sendResult = await sendPhotoFunction();
|
|
279
|
+
}
|
|
280
|
+
} else {
|
|
281
|
+
sendResult = await sendPhotoFunction();
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (sendResult.ok && sendResult.result) {
|
|
285
|
+
if (onExpire) {
|
|
286
|
+
pushMessageToExpireList(sendResult.result, {
|
|
287
|
+
seconds: this.expiresMessageSeconds,
|
|
288
|
+
onExpire,
|
|
289
|
+
});
|
|
290
|
+
} else {
|
|
291
|
+
deleteMessageFromExpiringList(sendResult.result);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
return sendResult;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
async sendMessage(
|
|
299
|
+
input: TG_SendMessageInput,
|
|
300
|
+
message?: TG_Message,
|
|
301
|
+
onExpire?: (resultMessage: TG_Message) => void
|
|
302
|
+
): Promise<TG_SendMessageResponse> {
|
|
303
|
+
let sendResult: TG_SendMessageResponse;
|
|
304
|
+
|
|
305
|
+
const sendPhotoFunction = () =>
|
|
306
|
+
TelegramApi.sendMessage(
|
|
307
|
+
{
|
|
308
|
+
parse_mode: 'HTML',
|
|
309
|
+
protect_content: this.protect_content, // переписывается инпутом
|
|
310
|
+
...input,
|
|
311
|
+
},
|
|
312
|
+
this.botToken
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
if (message) {
|
|
316
|
+
try {
|
|
317
|
+
sendResult = await TelegramApi.editMessageText(
|
|
318
|
+
{
|
|
319
|
+
message_id: message.message_id,
|
|
320
|
+
...input,
|
|
321
|
+
},
|
|
322
|
+
this.botToken
|
|
323
|
+
);
|
|
324
|
+
} catch (e) {
|
|
325
|
+
sendResult = await sendPhotoFunction();
|
|
326
|
+
}
|
|
327
|
+
} else {
|
|
328
|
+
sendResult = await sendPhotoFunction();
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
if (sendResult.ok && sendResult.result) {
|
|
332
|
+
if (onExpire) {
|
|
333
|
+
pushMessageToExpireList(sendResult.result, {
|
|
334
|
+
seconds: this.expiresMessageSeconds,
|
|
335
|
+
onExpire,
|
|
336
|
+
});
|
|
337
|
+
} else {
|
|
338
|
+
deleteMessageFromExpiringList(sendResult.result);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
return sendResult;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
async getUpdates(offset?: number) {
|
|
346
|
+
return TelegramApi.getUpdates(this.botToken, offset);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
async setWebhook(webhookUrl: string) {
|
|
350
|
+
return TelegramApi.setWebhook(this.botToken, webhookUrl);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
async deleteWebhook() {
|
|
354
|
+
return TelegramApi.deleteWebhook(this.botToken);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
async setMyCommands(
|
|
358
|
+
commands: TG_BotCommand[]
|
|
359
|
+
): Promise<TG_SetMyCommandsResponse> {
|
|
360
|
+
return TelegramApi.setMyCommands(commands, this.botToken);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
async getChatInfo(telegramId: string | number): Promise<TG_ChatResponse> {
|
|
364
|
+
return TelegramApi.getChat(telegramId, this.botToken);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
async sendChatAction(input: TG_SendActionInput): Promise<boolean> {
|
|
368
|
+
return TelegramApi.sendChatAction(input, this.botToken);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
async deleteMessage(input: TG_DeleteMessageInput): Promise<boolean> {
|
|
372
|
+
return TelegramApi.deleteMessage(input, this.botToken);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// генераторы типовых методов
|
|
376
|
+
/!* private wrapTextMessages(
|
|
377
|
+
defs: Record<string, (input: TG_SendMessageInput) => TG_SendMessageInput>
|
|
378
|
+
) {
|
|
379
|
+
const result: Record<
|
|
380
|
+
string,
|
|
381
|
+
{
|
|
382
|
+
send: (
|
|
383
|
+
input: TG_SendMessageInput,
|
|
384
|
+
message?: TG_Message,
|
|
385
|
+
onExpire?: (m: TG_Message) => void
|
|
386
|
+
) => Promise<TG_SendMessageResponse>;
|
|
387
|
+
}
|
|
388
|
+
> = {};
|
|
389
|
+
|
|
390
|
+
Object.entries(defs).forEach(([key, builder]) => {
|
|
391
|
+
result[key] = {
|
|
392
|
+
send: (input, message, onExpire) =>
|
|
393
|
+
this.sendMessage(
|
|
394
|
+
builder(input ?? ({} as TG_SendMessageInput)),
|
|
395
|
+
message,
|
|
396
|
+
onExpire
|
|
397
|
+
),
|
|
398
|
+
};
|
|
399
|
+
});
|
|
400
|
+
return result;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
private wrapPhotoMessages(
|
|
404
|
+
defs: Record<string, (input: TG_SendPhotoInput) => TG_SendPhotoInput>
|
|
405
|
+
) {
|
|
406
|
+
const result: Record<
|
|
407
|
+
string,
|
|
408
|
+
{
|
|
409
|
+
send: (
|
|
410
|
+
input: TG_SendPhotoInput,
|
|
411
|
+
message?: TG_Message,
|
|
412
|
+
onExpire?: (m: TG_Message) => void
|
|
413
|
+
) => Promise<TG_SendMessageResponse>;
|
|
414
|
+
}
|
|
415
|
+
> = {};
|
|
416
|
+
|
|
417
|
+
Object.entries(defs).forEach(([key, builder]) => {
|
|
418
|
+
result[key] = {
|
|
419
|
+
send: (input, message, onExpire) =>
|
|
420
|
+
this.sendPhoto(
|
|
421
|
+
builder(input ?? ({} as TG_SendPhotoInput)),
|
|
422
|
+
message,
|
|
423
|
+
onExpire
|
|
424
|
+
),
|
|
425
|
+
};
|
|
426
|
+
});
|
|
427
|
+
return result;
|
|
428
|
+
} *!/
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
export default TelegramBot;
|
|
432
|
+
*/
|
|
433
|
+
//# sourceMappingURL=index_backup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index_backup.js","sourceRoot":"","sources":["../src/index_backup.ts"],"names":[],"mappings":";;AAAA,MAAM,WAAW,GAAG,EAAE,CAAC;AACvB,kBAAe,WAAW,CAAC;AAC3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2aE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skroz/telegram-bot",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": "git@gitlab.com:skroz/libs/utils.git",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -18,8 +18,5 @@
|
|
|
18
18
|
"publishConfig": {
|
|
19
19
|
"access": "public"
|
|
20
20
|
},
|
|
21
|
-
"
|
|
22
|
-
"@skroz/telegram-api": "^1.0.14"
|
|
23
|
-
},
|
|
24
|
-
"gitHead": "0c39573cfdd1a4bcb4666b8ce6dbda86d12e4e08"
|
|
21
|
+
"gitHead": "c1fdf97b9d0f1755497f1ce8fa4eeb59b61e2e1a"
|
|
25
22
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Readable } from 'stream';
|
|
2
|
+
|
|
3
|
+
interface Options {
|
|
4
|
+
encoding?: string;
|
|
5
|
+
highWaterMark?: number;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface FileUpload {
|
|
9
|
+
filename: string;
|
|
10
|
+
mimetype: string;
|
|
11
|
+
encoding: string;
|
|
12
|
+
createReadStream: (options?: Options) => Readable;
|
|
13
|
+
}
|