telegix 1.1.1 → 1.1.2
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/README.md +539 -63
- package/index.cjs +6305 -0
- package/index.d.ts +120 -0
- package/index.js +11 -2
- package/lib/api.js +97 -19
- package/lib/context.js +111 -0
- package/lib/format.js +6 -0
- package/lib/link-preview.js +256 -0
- package/lib/markdownv2.js +3 -0
- package/lib/markup.js +116 -4
- package/lib/rich.js +54 -0
- package/lib/stream.js +251 -0
- package/lib/webapp.js +511 -2
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -92,6 +92,10 @@ export class Markup {
|
|
|
92
92
|
text(text: string): object;
|
|
93
93
|
callback(text: string, data: string): object;
|
|
94
94
|
url(text: string, url: string): object;
|
|
95
|
+
primary(text: string, dataOrUrl?: string | number | object, options?: object): object;
|
|
96
|
+
danger(text: string, dataOrUrl?: string | number | object, options?: object): object;
|
|
97
|
+
success(text: string, dataOrUrl?: string | number | object, options?: object): object;
|
|
98
|
+
colored(text: string, style: 'primary' | 'danger' | 'success', dataOrUrl?: string | number | object, options?: object): object;
|
|
95
99
|
webApp(text: string, url: string): object;
|
|
96
100
|
contactRequest(text: string): object;
|
|
97
101
|
locationRequest(text: string): object;
|
|
@@ -208,6 +212,14 @@ export class Context {
|
|
|
208
212
|
replyWithPaidMedia(starCount: number, media: any[], extra?: object): Promise<Message>;
|
|
209
213
|
replyWithSticker(sticker: any, extra?: object): Promise<Message>;
|
|
210
214
|
replyWithGame(gameShortName: string, extra?: object): Promise<Message>;
|
|
215
|
+
replyWithLinkPreview(text: string, linkPreviewOptions: LinkPreview | object, extra?: object): Promise<Message>;
|
|
216
|
+
replyWithCollapsibleQuote(text: string, extra?: object): Promise<Message>;
|
|
217
|
+
replyWithExpandableQuote(text: string, extra?: object): Promise<Message>;
|
|
218
|
+
replyWithWebApp(text: string, webAppUrl: string, buttonText?: string, extra?: object): Promise<Message>;
|
|
219
|
+
streamText(textStream: any, options?: object): Promise<any>;
|
|
220
|
+
streamDraft(textStream: any, options?: object): Promise<any>;
|
|
221
|
+
savePreparedInlineMessage(result: object, options?: object): Promise<{ id: string; expiration_date: number }>;
|
|
222
|
+
validateWebAppInitData(initDataStr: string, options?: object): any;
|
|
211
223
|
createForumTopic(name: string, extra?: object): Promise<any>;
|
|
212
224
|
editForumTopic(messageThreadId?: number, extra?: object): Promise<boolean>;
|
|
213
225
|
closeForumTopic(messageThreadId?: number): Promise<boolean>;
|
|
@@ -228,6 +240,7 @@ export class Context {
|
|
|
228
240
|
sendRichMessageDraft(draft: any, extra?: object): Promise<boolean>;
|
|
229
241
|
react(emoji: string | any[]): Promise<boolean>;
|
|
230
242
|
answerCallbackQuery(text?: string, options?: object): Promise<boolean>;
|
|
243
|
+
answerCbQuery(text?: string, options?: object): Promise<boolean>;
|
|
231
244
|
answerInlineQuery(results: any[], options?: object): Promise<boolean>;
|
|
232
245
|
editMessageText(text: string, extra?: object): Promise<Message | boolean>;
|
|
233
246
|
editMessageCaption(caption: string, extra?: object): Promise<Message | boolean>;
|
|
@@ -332,6 +345,7 @@ export class RichMessageBuilder {
|
|
|
332
345
|
code(codeText: string, language?: string): this;
|
|
333
346
|
quote(text: string, expandable?: boolean): this;
|
|
334
347
|
expandableQuote(text: string): this;
|
|
348
|
+
collapsibleQuote(text: string): this;
|
|
335
349
|
spoiler(text: string): this;
|
|
336
350
|
link(text: string, url: string): this;
|
|
337
351
|
mention(text: string, userId: number | string): this;
|
|
@@ -347,6 +361,10 @@ export class RichMessageBuilder {
|
|
|
347
361
|
row(...buttons: object[]): this;
|
|
348
362
|
callback(text: string, data: string): this;
|
|
349
363
|
url(text: string, url: string): this;
|
|
364
|
+
primary(text: string, dataOrUrl?: string | number | object, options?: object): this;
|
|
365
|
+
danger(text: string, dataOrUrl?: string | number | object, options?: object): this;
|
|
366
|
+
success(text: string, dataOrUrl?: string | number | object, options?: object): this;
|
|
367
|
+
colored(text: string, style: 'primary' | 'danger' | 'success', dataOrUrl?: string | number | object, options?: object): this;
|
|
350
368
|
disabled(text: string): this;
|
|
351
369
|
webApp(text: string, webAppUrl: string): this;
|
|
352
370
|
copyText(text: string, textToCopy: string): this;
|
|
@@ -402,6 +420,9 @@ export class Telegram {
|
|
|
402
420
|
setManagedBotAccessSettings(userId: number, settings?: object, extra?: object): Promise<boolean>;
|
|
403
421
|
getUserPersonalChatMessages(userId: number, extra?: object): Promise<any>;
|
|
404
422
|
sendMessageDraft(chatId: number | string, text: string, extra?: object): Promise<boolean>;
|
|
423
|
+
savePreparedInlineMessage(userId: number, result: object, options?: object): Promise<{ id: string; expiration_date: number }>;
|
|
424
|
+
streamText(chatId: number | string, textStream: any, options?: object): Promise<{ message_id?: number; text: string; done: boolean }>;
|
|
425
|
+
streamDraft(chatId: number | string, textStream: any, options?: object): Promise<{ message_id?: number; text: string; done: boolean }>;
|
|
405
426
|
setWebhook(url: string, extra?: object): Promise<boolean>;
|
|
406
427
|
deleteWebhook(extra?: object): Promise<boolean>;
|
|
407
428
|
getWebhookInfo(): Promise<any>;
|
|
@@ -481,7 +502,106 @@ export function paginateInlineQuery(ctx: Context, items: any[], formatterFn: (it
|
|
|
481
502
|
|
|
482
503
|
export function albumMiddleware(options?: { windowMs?: number }): Middleware;
|
|
483
504
|
|
|
505
|
+
export interface LinkPreviewOptions {
|
|
506
|
+
is_disabled?: boolean;
|
|
507
|
+
url?: string;
|
|
508
|
+
prefer_small_media?: boolean;
|
|
509
|
+
prefer_large_media?: boolean;
|
|
510
|
+
show_above_text?: boolean;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
export class LinkPreview {
|
|
514
|
+
constructor(url?: string);
|
|
515
|
+
url(url: string): this;
|
|
516
|
+
disabled(disabled?: boolean): this;
|
|
517
|
+
disable(): this;
|
|
518
|
+
enable(): this;
|
|
519
|
+
smallMedia(small?: boolean): this;
|
|
520
|
+
largeMedia(large?: boolean): this;
|
|
521
|
+
aboveText(above?: boolean): this;
|
|
522
|
+
belowText(): this;
|
|
523
|
+
toJSON(): LinkPreviewOptions;
|
|
524
|
+
static create(url?: string): LinkPreview;
|
|
525
|
+
static disabled(): LinkPreview;
|
|
526
|
+
static small(url?: string): LinkPreview;
|
|
527
|
+
static large(url?: string): LinkPreview;
|
|
528
|
+
static above(url?: string): LinkPreview;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
export function toTextStream(input: any): AsyncIterable<string>;
|
|
532
|
+
export function streamText(
|
|
533
|
+
telegram: Telegram,
|
|
534
|
+
chatId: number | string,
|
|
535
|
+
textStream: any,
|
|
536
|
+
options?: {
|
|
537
|
+
intervalMs?: number;
|
|
538
|
+
minDeltaChars?: number;
|
|
539
|
+
useDraft?: boolean;
|
|
540
|
+
extra?: object;
|
|
541
|
+
draftId?: number;
|
|
542
|
+
initialMessage?: string;
|
|
543
|
+
onProgress?: (text: string, count: number) => void;
|
|
544
|
+
onError?: (err: Error) => void;
|
|
545
|
+
}
|
|
546
|
+
): Promise<{ message_id?: number; text: string; done: boolean }>;
|
|
547
|
+
|
|
484
548
|
export function validateWebAppInitData(initDataStr: string, botToken: string, options?: { maxAgeSeconds?: number }): any;
|
|
549
|
+
export function parseWebAppInitData(initDataStr: string): any;
|
|
550
|
+
export function createMiniAppLaunchUrl(botUsername: string, appShortName: string, startParam?: string): string;
|
|
551
|
+
|
|
552
|
+
export class MiniAppLoadingScreen {
|
|
553
|
+
constructor(options?: {
|
|
554
|
+
title?: string;
|
|
555
|
+
icon?: string;
|
|
556
|
+
lightColor?: string;
|
|
557
|
+
darkColor?: string;
|
|
558
|
+
lightBg?: string;
|
|
559
|
+
darkBg?: string;
|
|
560
|
+
skeleton?: boolean;
|
|
561
|
+
});
|
|
562
|
+
setIcon(icon: string): this;
|
|
563
|
+
setTitle(title: string): this;
|
|
564
|
+
setColors(lightColor: string, darkColor: string): this;
|
|
565
|
+
setSkeleton(enabled?: boolean): this;
|
|
566
|
+
toCSS(): string;
|
|
567
|
+
toHTML(): string;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
export function generateMiniAppLoadingScreen(options?: any): string;
|
|
571
|
+
|
|
572
|
+
export const MiniApp: {
|
|
573
|
+
isInsideTelegram(): boolean;
|
|
574
|
+
webApp: any;
|
|
575
|
+
fullscreen: {
|
|
576
|
+
request(): boolean;
|
|
577
|
+
exit(): boolean;
|
|
578
|
+
isActive(): boolean;
|
|
579
|
+
onChange(callback: (isFullscreen: boolean) => void): void;
|
|
580
|
+
onFailed(callback: (err: any) => void): void;
|
|
581
|
+
};
|
|
582
|
+
motion: {
|
|
583
|
+
startAccelerometer(options?: { refresh_rate?: number }): boolean;
|
|
584
|
+
stopAccelerometer(): boolean;
|
|
585
|
+
onAccelerometer(callback: (data: { x: number; y: number; z: number }) => void): void;
|
|
586
|
+
startDeviceOrientation(options?: { refresh_rate?: number; need_absolute?: boolean }): boolean;
|
|
587
|
+
stopDeviceOrientation(): boolean;
|
|
588
|
+
onOrientation(callback: (data: { alpha: number; beta: number; gamma: number; absolute: boolean }) => void): void;
|
|
589
|
+
startGyroscope(options?: { refresh_rate?: number }): boolean;
|
|
590
|
+
stopGyroscope(): boolean;
|
|
591
|
+
onGyroscope(callback: (data: { x: number; y: number; z: number }) => void): void;
|
|
592
|
+
};
|
|
593
|
+
homeScreen: {
|
|
594
|
+
addToHomeScreen(): boolean;
|
|
595
|
+
checkStatus(callback: (status: 'unsupported' | 'unknown' | 'added' | 'missed') => void): void;
|
|
596
|
+
};
|
|
597
|
+
sharePreparedMessage(preparedMessageId: string): boolean;
|
|
598
|
+
downloadFile(params: { url: string; file_name: string }): boolean;
|
|
599
|
+
haptics: {
|
|
600
|
+
impact(style?: string): void;
|
|
601
|
+
notification(type?: string): void;
|
|
602
|
+
selection(): void;
|
|
603
|
+
};
|
|
604
|
+
};
|
|
485
605
|
|
|
486
606
|
export function promptMiddleware(): Middleware;
|
|
487
607
|
|
package/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Telegix - Lightweight Telegram Bot API Framework
|
|
2
|
+
* Telegix - Lightweight, Pure JavaScript Telegram Bot API Framework
|
|
3
3
|
* @author KazeDevID
|
|
4
4
|
* @license MIT
|
|
5
5
|
*/
|
|
@@ -20,7 +20,16 @@ export { RateLimiter, rateLimit } from './lib/ratelimit.js';
|
|
|
20
20
|
export { serializeMessage, serializeUpdate } from './lib/serialize.js';
|
|
21
21
|
export { InlineQueryResultBuilder, paginateInlineQuery } from './lib/inline.js';
|
|
22
22
|
export { albumMiddleware } from './lib/album.js';
|
|
23
|
-
export {
|
|
23
|
+
export {
|
|
24
|
+
validateWebAppInitData,
|
|
25
|
+
parseWebAppInitData,
|
|
26
|
+
createMiniAppLaunchUrl,
|
|
27
|
+
MiniAppLoadingScreen,
|
|
28
|
+
generateMiniAppLoadingScreen,
|
|
29
|
+
MiniApp,
|
|
30
|
+
} from './lib/webapp.js';
|
|
31
|
+
export { streamText, toTextStream } from './lib/stream.js';
|
|
32
|
+
export { LinkPreview } from './lib/link-preview.js';
|
|
24
33
|
export { promptMiddleware } from './lib/prompt.js';
|
|
25
34
|
export { escapeMarkdownV2, mdv2 } from './lib/markdownv2.js';
|
|
26
35
|
export { inlineDebounceMiddleware } from './lib/inline-debounce.js';
|
package/lib/api.js
CHANGED
|
@@ -4,20 +4,38 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { TelegramError, NetworkError } from './errors.js';
|
|
7
|
+
import { streamText as runStreamText } from './stream.js';
|
|
7
8
|
import fs from 'node:fs';
|
|
8
9
|
import path from 'node:path';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Checks if value is a file/stream/buffer that needs multipart/form-data upload
|
|
12
13
|
* @param {any} value
|
|
14
|
+
* @param {string} [key='']
|
|
13
15
|
* @returns {boolean}
|
|
14
16
|
*/
|
|
15
|
-
export function isUploadableFile(value) {
|
|
17
|
+
export function isUploadableFile(value, key = '') {
|
|
16
18
|
if (!value) return false;
|
|
17
19
|
if (typeof value === 'string') return false;
|
|
20
|
+
if (key === 'link_preview_options' || key === 'reply_parameters' || key === 'reply_markup') {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
18
23
|
if (value instanceof Blob || value instanceof Uint8Array || Buffer.isBuffer(value)) return true;
|
|
19
|
-
if (typeof value === 'object'
|
|
20
|
-
|
|
24
|
+
if (typeof value === 'object') {
|
|
25
|
+
// If it's a LinkPreview or has link preview options properties, it's not a file
|
|
26
|
+
if (
|
|
27
|
+
value._options !== undefined ||
|
|
28
|
+
value.prefer_small_media !== undefined ||
|
|
29
|
+
value.prefer_large_media !== undefined ||
|
|
30
|
+
value.show_above_text !== undefined ||
|
|
31
|
+
value.is_disabled !== undefined
|
|
32
|
+
) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
if ('source' in value) return true;
|
|
36
|
+
if (typeof value.pipe === 'function') return true; // Stream
|
|
37
|
+
if ('url' in value && key !== 'link_preview_options') return true;
|
|
38
|
+
}
|
|
21
39
|
return false;
|
|
22
40
|
}
|
|
23
41
|
|
|
@@ -201,6 +219,15 @@ export function normalizeTelegramPayload(payload) {
|
|
|
201
219
|
}
|
|
202
220
|
}
|
|
203
221
|
|
|
222
|
+
// 6. Handle link_preview_options and legacy disable_web_page_preview
|
|
223
|
+
if (norm.link_preview_options && typeof norm.link_preview_options.toJSON === 'function') {
|
|
224
|
+
norm.link_preview_options = norm.link_preview_options.toJSON();
|
|
225
|
+
}
|
|
226
|
+
if (norm.disable_web_page_preview !== undefined && !norm.link_preview_options) {
|
|
227
|
+
norm.link_preview_options = { is_disabled: Boolean(norm.disable_web_page_preview) };
|
|
228
|
+
delete norm.disable_web_page_preview;
|
|
229
|
+
}
|
|
230
|
+
|
|
204
231
|
return norm;
|
|
205
232
|
}
|
|
206
233
|
|
|
@@ -253,7 +280,7 @@ export class Telegram {
|
|
|
253
280
|
|
|
254
281
|
// Check if any payload property is an uploadable file
|
|
255
282
|
for (const key of Object.keys(normalizedPayload)) {
|
|
256
|
-
if (isUploadableFile(normalizedPayload[key])) {
|
|
283
|
+
if (isUploadableFile(normalizedPayload[key], key)) {
|
|
257
284
|
hasUpload = true;
|
|
258
285
|
break;
|
|
259
286
|
}
|
|
@@ -269,7 +296,7 @@ export class Telegram {
|
|
|
269
296
|
for (const [key, value] of Object.entries(normalizedPayload)) {
|
|
270
297
|
if (value === undefined || value === null) continue;
|
|
271
298
|
|
|
272
|
-
if (isUploadableFile(value)) {
|
|
299
|
+
if (isUploadableFile(value, key)) {
|
|
273
300
|
const { blob, filename } = await normalizeFileSource(value, key);
|
|
274
301
|
if (typeof blob === 'string') {
|
|
275
302
|
formData.append(key, blob);
|
|
@@ -298,6 +325,14 @@ export class Telegram {
|
|
|
298
325
|
}
|
|
299
326
|
delete cleanPayload.toJSON;
|
|
300
327
|
|
|
328
|
+
// Special Telegram API parameters that Telegram requires as JSON-serialized strings
|
|
329
|
+
const jsonStringParams = ['link_preview_options', 'reply_parameters', 'reply_markup'];
|
|
330
|
+
for (const param of jsonStringParams) {
|
|
331
|
+
if (cleanPayload[param] && typeof cleanPayload[param] === 'object') {
|
|
332
|
+
cleanPayload[param] = JSON.stringify(cleanPayload[param]);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
301
336
|
requestInit.headers = {
|
|
302
337
|
'Content-Type': 'application/json',
|
|
303
338
|
};
|
|
@@ -802,6 +837,13 @@ export class Telegram {
|
|
|
802
837
|
});
|
|
803
838
|
}
|
|
804
839
|
|
|
840
|
+
/**
|
|
841
|
+
* Alias for answerCallbackQuery
|
|
842
|
+
*/
|
|
843
|
+
answerCbQuery(callbackQueryId, extra = {}) {
|
|
844
|
+
return this.answerCallbackQuery(callbackQueryId, extra);
|
|
845
|
+
}
|
|
846
|
+
|
|
805
847
|
/**
|
|
806
848
|
* Edit message text
|
|
807
849
|
*/
|
|
@@ -1345,20 +1387,6 @@ export class Telegram {
|
|
|
1345
1387
|
});
|
|
1346
1388
|
}
|
|
1347
1389
|
|
|
1348
|
-
/**
|
|
1349
|
-
* Save prepared inline message for mini-app sharing
|
|
1350
|
-
* @param {number} userId
|
|
1351
|
-
* @param {object} result - InlineQueryResult
|
|
1352
|
-
* @param {object} [extra] - allow_user_chats, allow_bot_chats, allow_group_chats, allow_channel_chats
|
|
1353
|
-
*/
|
|
1354
|
-
savePreparedInlineMessage(userId, result, extra = {}) {
|
|
1355
|
-
return this.call('savePreparedInlineMessage', {
|
|
1356
|
-
user_id: userId,
|
|
1357
|
-
result,
|
|
1358
|
-
...extra,
|
|
1359
|
-
});
|
|
1360
|
-
}
|
|
1361
|
-
|
|
1362
1390
|
// ==========================================
|
|
1363
1391
|
// Stickers & Custom Emojis
|
|
1364
1392
|
// ==========================================
|
|
@@ -1837,4 +1865,54 @@ export class Telegram {
|
|
|
1837
1865
|
...extra,
|
|
1838
1866
|
});
|
|
1839
1867
|
}
|
|
1868
|
+
|
|
1869
|
+
/**
|
|
1870
|
+
* Save a prepared inline message for a Telegram Mini App user (Bot API 8.0+)
|
|
1871
|
+
* @param {number} userId - Unique identifier of target user who can send the message
|
|
1872
|
+
* @param {object} result - InlineQueryResult object describing the message to be sent
|
|
1873
|
+
* @param {object} [options] - Allowed chats options (allow_user_chats, allow_bot_chats, allow_group_chats, allow_channel_chats)
|
|
1874
|
+
* @returns {Promise<{ id: string, expiration_date: number }>}
|
|
1875
|
+
*/
|
|
1876
|
+
savePreparedInlineMessage(userId, result, options = {}) {
|
|
1877
|
+
if (!userId) {
|
|
1878
|
+
throw new Error('Telegram.savePreparedInlineMessage(userId, result) requires a valid userId.');
|
|
1879
|
+
}
|
|
1880
|
+
if (!result) {
|
|
1881
|
+
throw new Error('Telegram.savePreparedInlineMessage(userId, result) requires a valid result object.');
|
|
1882
|
+
}
|
|
1883
|
+
|
|
1884
|
+
const payload = {
|
|
1885
|
+
user_id: userId,
|
|
1886
|
+
result: typeof result.toJSON === 'function' ? result.toJSON() : result,
|
|
1887
|
+
allow_user_chats: options.allow_user_chats ?? true,
|
|
1888
|
+
allow_bot_chats: options.allow_bot_chats ?? true,
|
|
1889
|
+
allow_group_chats: options.allow_group_chats ?? true,
|
|
1890
|
+
allow_channel_chats: options.allow_channel_chats ?? true,
|
|
1891
|
+
...options,
|
|
1892
|
+
};
|
|
1893
|
+
|
|
1894
|
+
return this.call('savePreparedInlineMessage', payload);
|
|
1895
|
+
}
|
|
1896
|
+
|
|
1897
|
+
/**
|
|
1898
|
+
* Stream text response into a Telegram chat with throttling, token buffering, and rate limit protection
|
|
1899
|
+
* @param {number|string} chatId
|
|
1900
|
+
* @param {AsyncIterable<string>|Iterable<string>|ReadableStream|Array<string>} textStream
|
|
1901
|
+
* @param {object} [options]
|
|
1902
|
+
* @returns {Promise<{ message_id?: number, text: string, done: boolean }>}
|
|
1903
|
+
*/
|
|
1904
|
+
streamText(chatId, textStream, options = {}) {
|
|
1905
|
+
return runStreamText(this, chatId, textStream, options);
|
|
1906
|
+
}
|
|
1907
|
+
|
|
1908
|
+
/**
|
|
1909
|
+
* Stream live draft response into a Telegram chat (using Bot API live draft updates)
|
|
1910
|
+
* @param {number|string} chatId
|
|
1911
|
+
* @param {AsyncIterable<string>|Iterable<string>|ReadableStream|Array<string>} textStream
|
|
1912
|
+
* @param {object} [options]
|
|
1913
|
+
* @returns {Promise<{ message_id?: number, text: string, done: boolean }>}
|
|
1914
|
+
*/
|
|
1915
|
+
streamDraft(chatId, textStream, options = {}) {
|
|
1916
|
+
return runStreamText(this, chatId, textStream, { ...options, useDraft: true });
|
|
1917
|
+
}
|
|
1840
1918
|
}
|
package/lib/context.js
CHANGED
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { serializeMessage, serializeUpdate } from './serialize.js';
|
|
7
|
+
import { escapeHtml } from './format.js';
|
|
8
|
+
import { validateWebAppInitData } from './webapp.js';
|
|
9
|
+
import { LinkPreview } from './link-preview.js';
|
|
7
10
|
|
|
8
11
|
export class Context {
|
|
9
12
|
/**
|
|
@@ -505,6 +508,15 @@ export class Context {
|
|
|
505
508
|
});
|
|
506
509
|
}
|
|
507
510
|
|
|
511
|
+
/**
|
|
512
|
+
* Answer callback query (alias for answerCallbackQuery)
|
|
513
|
+
* @param {string} [text]
|
|
514
|
+
* @param {object} [options]
|
|
515
|
+
*/
|
|
516
|
+
answerCbQuery(text = '', options = {}) {
|
|
517
|
+
return this.answerCallbackQuery(text, options);
|
|
518
|
+
}
|
|
519
|
+
|
|
508
520
|
/**
|
|
509
521
|
* Answer inline query
|
|
510
522
|
* @param {Array<object>} results
|
|
@@ -967,4 +979,103 @@ export class Context {
|
|
|
967
979
|
}
|
|
968
980
|
return this.telegram.setManagedBotAccessSettings(userId, settings);
|
|
969
981
|
}
|
|
982
|
+
|
|
983
|
+
/**
|
|
984
|
+
* Stream text response to the current chat with rate-limit protection and token buffering
|
|
985
|
+
* @param {AsyncIterable<string>|Iterable<string>|ReadableStream|Array<string>} textStream
|
|
986
|
+
* @param {object} [options]
|
|
987
|
+
* @returns {Promise<{ message_id?: number, text: string, done: boolean }>}
|
|
988
|
+
*/
|
|
989
|
+
streamText(textStream, options = {}) {
|
|
990
|
+
return this.telegram.streamText(this._assertChat(), textStream, options);
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
/**
|
|
994
|
+
* Stream live draft response to the current chat
|
|
995
|
+
* @param {AsyncIterable<string>|Iterable<string>|ReadableStream|Array<string>} textStream
|
|
996
|
+
* @param {object} [options]
|
|
997
|
+
* @returns {Promise<{ message_id?: number, text: string, done: boolean }>}
|
|
998
|
+
*/
|
|
999
|
+
streamDraft(textStream, options = {}) {
|
|
1000
|
+
return this.telegram.streamDraft(this._assertChat(), textStream, options);
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
/**
|
|
1004
|
+
* Reply with customizable link preview options (Bot API 7.0+)
|
|
1005
|
+
* @param {string} text
|
|
1006
|
+
* @param {LinkPreview|object} linkPreviewOptions
|
|
1007
|
+
* @param {object} [extra]
|
|
1008
|
+
*/
|
|
1009
|
+
replyWithLinkPreview(text, linkPreviewOptions, extra = {}) {
|
|
1010
|
+
const previewOptions = typeof linkPreviewOptions?.toJSON === 'function'
|
|
1011
|
+
? linkPreviewOptions.toJSON()
|
|
1012
|
+
: linkPreviewOptions;
|
|
1013
|
+
return this.reply(text, {
|
|
1014
|
+
link_preview_options: previewOptions,
|
|
1015
|
+
...extra,
|
|
1016
|
+
});
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
/**
|
|
1020
|
+
* Reply with collapsible quote blockquote (HTML format)
|
|
1021
|
+
* @param {string} text - Quoted text content
|
|
1022
|
+
* @param {object} [extra]
|
|
1023
|
+
*/
|
|
1024
|
+
replyWithCollapsibleQuote(text, extra = {}) {
|
|
1025
|
+
const formatted = `<blockquote expandable>${escapeHtml(text)}</blockquote>`;
|
|
1026
|
+
return this.reply(formatted, {
|
|
1027
|
+
parse_mode: 'HTML',
|
|
1028
|
+
...extra,
|
|
1029
|
+
});
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
/**
|
|
1033
|
+
* Reply with expandable quote blockquote (alias for replyWithCollapsibleQuote)
|
|
1034
|
+
* @param {string} text
|
|
1035
|
+
* @param {object} [extra]
|
|
1036
|
+
*/
|
|
1037
|
+
replyWithExpandableQuote(text, extra = {}) {
|
|
1038
|
+
return this.replyWithCollapsibleQuote(text, extra);
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
/**
|
|
1042
|
+
* Save a prepared inline message for the current user (Bot API 8.0+)
|
|
1043
|
+
* @param {object} result - InlineQueryResult object
|
|
1044
|
+
* @param {object} [options]
|
|
1045
|
+
* @returns {Promise<{ id: string, expiration_date: number }>}
|
|
1046
|
+
*/
|
|
1047
|
+
savePreparedInlineMessage(result, options = {}) {
|
|
1048
|
+
if (!this.userId) {
|
|
1049
|
+
throw new Error('Telegix Context: savePreparedInlineMessage() requires user context.');
|
|
1050
|
+
}
|
|
1051
|
+
return this.telegram.savePreparedInlineMessage(this.userId, result, options);
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
/**
|
|
1055
|
+
* Validate Web App initData string with the bot token
|
|
1056
|
+
* @param {string} initDataStr
|
|
1057
|
+
* @param {object} [options]
|
|
1058
|
+
* @returns {object|null}
|
|
1059
|
+
*/
|
|
1060
|
+
validateWebAppInitData(initDataStr, options = {}) {
|
|
1061
|
+
return validateWebAppInitData(initDataStr, this.telegram.token, options);
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
/**
|
|
1065
|
+
* Reply with a message containing a Telegram Mini App button
|
|
1066
|
+
* @param {string} text
|
|
1067
|
+
* @param {string} webAppUrl
|
|
1068
|
+
* @param {string} [buttonText='Open App']
|
|
1069
|
+
* @param {object} [extra]
|
|
1070
|
+
*/
|
|
1071
|
+
replyWithWebApp(text, webAppUrl, buttonText = 'Open App', extra = {}) {
|
|
1072
|
+
return this.reply(text, {
|
|
1073
|
+
reply_markup: {
|
|
1074
|
+
inline_keyboard: [
|
|
1075
|
+
[{ text: buttonText, web_app: { url: webAppUrl } }],
|
|
1076
|
+
],
|
|
1077
|
+
},
|
|
1078
|
+
...extra,
|
|
1079
|
+
});
|
|
1080
|
+
}
|
|
970
1081
|
}
|
package/lib/format.js
CHANGED
|
@@ -47,6 +47,8 @@ export const html = {
|
|
|
47
47
|
customEmoji: (text, customEmojiId) => `<tg-emoji emoji-id="${customEmojiId}">${escapeHtml(text)}</tg-emoji>`,
|
|
48
48
|
quote: (text) => `<blockquote>${escapeHtml(text)}</blockquote>`,
|
|
49
49
|
expandableBlockquote: (text) => `<blockquote expandable>${escapeHtml(text)}</blockquote>`,
|
|
50
|
+
expandableQuote: (text) => `<blockquote expandable>${escapeHtml(text)}</blockquote>`,
|
|
51
|
+
collapsibleQuote: (text) => `<blockquote expandable>${escapeHtml(text)}</blockquote>`,
|
|
50
52
|
};
|
|
51
53
|
|
|
52
54
|
/**
|
|
@@ -66,6 +68,8 @@ export const markdown = {
|
|
|
66
68
|
customEmoji: (text, customEmojiId) => ``,
|
|
67
69
|
quote: (text) => text.split('\n').map((line) => `>${escapeMarkdown(line)}`).join('\n'),
|
|
68
70
|
expandableBlockquote: (text) => `**>${escapeMarkdown(text)}||`,
|
|
71
|
+
expandableQuote: (text) => `**>${escapeMarkdown(text)}||`,
|
|
72
|
+
collapsibleQuote: (text) => `**>${escapeMarkdown(text)}||`,
|
|
69
73
|
};
|
|
70
74
|
|
|
71
75
|
/**
|
|
@@ -107,6 +111,8 @@ fmt.mention = html.mention;
|
|
|
107
111
|
fmt.customEmoji = html.customEmoji;
|
|
108
112
|
fmt.quote = html.quote;
|
|
109
113
|
fmt.expandableBlockquote = html.expandableBlockquote;
|
|
114
|
+
fmt.expandableQuote = html.expandableQuote;
|
|
115
|
+
fmt.collapsibleQuote = html.collapsibleQuote;
|
|
110
116
|
fmt.escape = escapeHtml;
|
|
111
117
|
fmt.html = html;
|
|
112
118
|
fmt.markdown = markdown;
|