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
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telegix - Adjustable Link Preview Builder (Bot API 7.0+)
|
|
3
|
+
* Provides fluent options to control link preview rendering, media size,
|
|
4
|
+
* positioning above/below text, or disabling link previews.
|
|
5
|
+
* @module telegix/link-preview
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export class LinkPreview {
|
|
9
|
+
/**
|
|
10
|
+
* @param {object} [options]
|
|
11
|
+
* @param {boolean} [options.is_disabled]
|
|
12
|
+
* @param {string} [options.url]
|
|
13
|
+
* @param {boolean} [options.prefer_small_media]
|
|
14
|
+
* @param {boolean} [options.prefer_large_media]
|
|
15
|
+
* @param {boolean} [options.show_above_text]
|
|
16
|
+
*/
|
|
17
|
+
constructor(options = {}) {
|
|
18
|
+
this._options = { ...options };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Disable the link preview entirely
|
|
23
|
+
* @param {boolean} [disabled=true]
|
|
24
|
+
* @returns {this}
|
|
25
|
+
*/
|
|
26
|
+
disable(disabled = true) {
|
|
27
|
+
if (disabled) {
|
|
28
|
+
this._options.is_disabled = true;
|
|
29
|
+
} else {
|
|
30
|
+
delete this._options.is_disabled;
|
|
31
|
+
}
|
|
32
|
+
return this;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Set specific URL to preview
|
|
37
|
+
* @param {string} url
|
|
38
|
+
* @returns {this}
|
|
39
|
+
*/
|
|
40
|
+
url(url) {
|
|
41
|
+
this._options.url = String(url);
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Shrink preview media into a small square thumbnail
|
|
47
|
+
* @param {boolean} [prefer=true]
|
|
48
|
+
* @returns {this}
|
|
49
|
+
*/
|
|
50
|
+
smallMedia(prefer = true) {
|
|
51
|
+
if (prefer) {
|
|
52
|
+
this._options.prefer_small_media = true;
|
|
53
|
+
delete this._options.prefer_large_media;
|
|
54
|
+
} else {
|
|
55
|
+
delete this._options.prefer_small_media;
|
|
56
|
+
}
|
|
57
|
+
return this;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Expand preview media into a large preview card
|
|
62
|
+
* @param {boolean} [prefer=true]
|
|
63
|
+
* @returns {this}
|
|
64
|
+
*/
|
|
65
|
+
largeMedia(prefer = true) {
|
|
66
|
+
if (prefer) {
|
|
67
|
+
this._options.prefer_large_media = true;
|
|
68
|
+
delete this._options.prefer_small_media;
|
|
69
|
+
} else {
|
|
70
|
+
delete this._options.prefer_large_media;
|
|
71
|
+
}
|
|
72
|
+
return this;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Position the link preview card ABOVE the message text
|
|
77
|
+
* @param {boolean} [above=true]
|
|
78
|
+
* @returns {this}
|
|
79
|
+
*/
|
|
80
|
+
showAbove(above = true) {
|
|
81
|
+
if (above) {
|
|
82
|
+
this._options.show_above_text = true;
|
|
83
|
+
} else {
|
|
84
|
+
delete this._options.show_above_text;
|
|
85
|
+
}
|
|
86
|
+
return this;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Position the link preview card ABOVE the message text (alias)
|
|
91
|
+
* @param {boolean} [above=true]
|
|
92
|
+
* @returns {this}
|
|
93
|
+
*/
|
|
94
|
+
aboveText(above = true) {
|
|
95
|
+
return this.showAbove(above);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Position the link preview card BELOW the message text
|
|
100
|
+
* @param {boolean} [below=true]
|
|
101
|
+
* @returns {this}
|
|
102
|
+
*/
|
|
103
|
+
showBelow(below = true) {
|
|
104
|
+
if (below) {
|
|
105
|
+
delete this._options.show_above_text;
|
|
106
|
+
} else {
|
|
107
|
+
this._options.show_above_text = true;
|
|
108
|
+
}
|
|
109
|
+
return this;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Position the link preview card BELOW the message text (alias)
|
|
114
|
+
* @param {boolean} [below=true]
|
|
115
|
+
* @returns {this}
|
|
116
|
+
*/
|
|
117
|
+
belowText(below = true) {
|
|
118
|
+
return this.showBelow(below);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Disable the link preview entirely (alias)
|
|
123
|
+
* @param {boolean} [disabled=true]
|
|
124
|
+
* @returns {this}
|
|
125
|
+
*/
|
|
126
|
+
disabled(disabled = true) {
|
|
127
|
+
return this.disable(disabled);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Enable the link preview
|
|
132
|
+
* @returns {this}
|
|
133
|
+
*/
|
|
134
|
+
enable() {
|
|
135
|
+
return this.disable(false);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Returns LinkPreviewOptions payload object
|
|
140
|
+
* @returns {object}
|
|
141
|
+
*/
|
|
142
|
+
toJSON() {
|
|
143
|
+
const res = {};
|
|
144
|
+
if (this._options.is_disabled !== undefined && this._options.is_disabled !== null) {
|
|
145
|
+
res.is_disabled = Boolean(this._options.is_disabled);
|
|
146
|
+
}
|
|
147
|
+
if (this._options.url) {
|
|
148
|
+
res.url = String(this._options.url);
|
|
149
|
+
}
|
|
150
|
+
if (this._options.prefer_small_media) {
|
|
151
|
+
res.prefer_small_media = true;
|
|
152
|
+
}
|
|
153
|
+
if (this._options.prefer_large_media) {
|
|
154
|
+
res.prefer_large_media = true;
|
|
155
|
+
}
|
|
156
|
+
if (this._options.show_above_text) {
|
|
157
|
+
res.show_above_text = true;
|
|
158
|
+
}
|
|
159
|
+
return res;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Wraps as Telegram extra parameter
|
|
164
|
+
* @returns {{ link_preview_options: object }}
|
|
165
|
+
*/
|
|
166
|
+
toExtra() {
|
|
167
|
+
return {
|
|
168
|
+
link_preview_options: this.toJSON(),
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// --- Static Factory Methods ---
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Create LinkPreview builder instance
|
|
176
|
+
* @param {string|object} [urlOrOptions]
|
|
177
|
+
* @param {object} [options]
|
|
178
|
+
* @returns {LinkPreview}
|
|
179
|
+
*/
|
|
180
|
+
static create(urlOrOptions, options = {}) {
|
|
181
|
+
if (typeof urlOrOptions === 'string') {
|
|
182
|
+
const lp = new LinkPreview(options);
|
|
183
|
+
lp.url(urlOrOptions);
|
|
184
|
+
return lp;
|
|
185
|
+
}
|
|
186
|
+
if (typeof urlOrOptions === 'object' && urlOrOptions !== null) {
|
|
187
|
+
return new LinkPreview({ ...urlOrOptions, ...options });
|
|
188
|
+
}
|
|
189
|
+
return new LinkPreview(options);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Create LinkPreview with options
|
|
194
|
+
* @param {object} options
|
|
195
|
+
* @returns {LinkPreview}
|
|
196
|
+
*/
|
|
197
|
+
static options(options = {}) {
|
|
198
|
+
return new LinkPreview(options);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Create disabled link preview options
|
|
203
|
+
* @returns {LinkPreview}
|
|
204
|
+
*/
|
|
205
|
+
static disabled() {
|
|
206
|
+
return new LinkPreview({ is_disabled: true });
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Create link preview with small media thumbnail
|
|
211
|
+
* @param {string} [url]
|
|
212
|
+
* @param {boolean} [showAbove=false]
|
|
213
|
+
* @returns {LinkPreview}
|
|
214
|
+
*/
|
|
215
|
+
static small(url, showAbove = false) {
|
|
216
|
+
const lp = new LinkPreview({ prefer_small_media: true, show_above_text: Boolean(showAbove) });
|
|
217
|
+
if (url) lp.url(url);
|
|
218
|
+
return lp;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Create link preview with large media card
|
|
223
|
+
* @param {string} [url]
|
|
224
|
+
* @param {boolean} [showAbove=false]
|
|
225
|
+
* @returns {LinkPreview}
|
|
226
|
+
*/
|
|
227
|
+
static large(url, showAbove = false) {
|
|
228
|
+
const lp = new LinkPreview({ prefer_large_media: true, show_above_text: Boolean(showAbove) });
|
|
229
|
+
if (url) lp.url(url);
|
|
230
|
+
return lp;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Create link preview positioned above message text
|
|
235
|
+
* @param {string} [url]
|
|
236
|
+
* @param {object} [options]
|
|
237
|
+
* @returns {LinkPreview}
|
|
238
|
+
*/
|
|
239
|
+
static above(url, options = {}) {
|
|
240
|
+
const lp = new LinkPreview({ show_above_text: true, ...options });
|
|
241
|
+
if (url) lp.url(url);
|
|
242
|
+
return lp;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Create link preview positioned below message text
|
|
247
|
+
* @param {string} [url]
|
|
248
|
+
* @param {object} [options]
|
|
249
|
+
* @returns {LinkPreview}
|
|
250
|
+
*/
|
|
251
|
+
static below(url, options = {}) {
|
|
252
|
+
const lp = new LinkPreview({ show_above_text: false, ...options });
|
|
253
|
+
if (url) lp.url(url);
|
|
254
|
+
return lp;
|
|
255
|
+
}
|
|
256
|
+
}
|
package/lib/markdownv2.js
CHANGED
|
@@ -26,4 +26,7 @@ export const mdv2 = {
|
|
|
26
26
|
code: (text) => `\`${text.replace(/`/g, '\\`')}\``,
|
|
27
27
|
pre: (text, language = '') => `\`\`\`${language}\n${text}\n\`\`\``,
|
|
28
28
|
link: (text, url) => `[${escapeMarkdownV2(text)}](${url})`,
|
|
29
|
+
quote: (text) => text.split('\n').map((line) => `>${escapeMarkdownV2(line)}`).join('\n'),
|
|
30
|
+
expandableQuote: (text) => `**>${escapeMarkdownV2(text)}||`,
|
|
31
|
+
collapsibleQuote: (text) => `**>${escapeMarkdownV2(text)}||`,
|
|
29
32
|
};
|
package/lib/markup.js
CHANGED
|
@@ -170,22 +170,134 @@ export class Markup {
|
|
|
170
170
|
/**
|
|
171
171
|
* Standard text button for reply keyboard
|
|
172
172
|
* @param {string} text
|
|
173
|
+
* @param {object} [options]
|
|
173
174
|
*/
|
|
174
|
-
text: (text) => ({ text }),
|
|
175
|
+
text: (text, options = {}) => ({ text, ...options }),
|
|
175
176
|
|
|
176
177
|
/**
|
|
177
178
|
* Inline callback button
|
|
178
179
|
* @param {string} text
|
|
179
|
-
* @param {string} data
|
|
180
|
+
* @param {string|number} data
|
|
181
|
+
* @param {object} [options]
|
|
180
182
|
*/
|
|
181
|
-
callback: (text, data) => ({ text, callback_data: String(data) }),
|
|
183
|
+
callback: (text, data, options = {}) => ({ text, callback_data: String(data), ...options }),
|
|
182
184
|
|
|
183
185
|
/**
|
|
184
186
|
* Inline URL button
|
|
185
187
|
* @param {string} text
|
|
186
188
|
* @param {string} url
|
|
189
|
+
* @param {object} [options]
|
|
190
|
+
*/
|
|
191
|
+
url: (text, url, options = {}) => ({ text, url, ...options }),
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Primary colored button (Blue / Main Action - Bot API 9.4+)
|
|
195
|
+
* @param {string} text
|
|
196
|
+
* @param {string|number|object} [dataOrUrl]
|
|
197
|
+
* @param {object} [options]
|
|
198
|
+
*/
|
|
199
|
+
primary: (text, dataOrUrl, options = {}) => {
|
|
200
|
+
let base = {};
|
|
201
|
+
if (typeof dataOrUrl === 'string') {
|
|
202
|
+
if (/^(https?:\/\/|tg:\/\/)/i.test(dataOrUrl)) {
|
|
203
|
+
base = { url: dataOrUrl };
|
|
204
|
+
} else {
|
|
205
|
+
base = { callback_data: dataOrUrl };
|
|
206
|
+
}
|
|
207
|
+
} else if (typeof dataOrUrl === 'number') {
|
|
208
|
+
base = { callback_data: String(dataOrUrl) };
|
|
209
|
+
} else if (typeof dataOrUrl === 'object' && dataOrUrl !== null) {
|
|
210
|
+
base = dataOrUrl;
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
text,
|
|
214
|
+
style: 'primary',
|
|
215
|
+
...base,
|
|
216
|
+
...options,
|
|
217
|
+
};
|
|
218
|
+
},
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Danger colored button (Red / Destructive Action - Bot API 9.4+)
|
|
222
|
+
* @param {string} text
|
|
223
|
+
* @param {string|number|object} [dataOrUrl]
|
|
224
|
+
* @param {object} [options]
|
|
225
|
+
*/
|
|
226
|
+
danger: (text, dataOrUrl, options = {}) => {
|
|
227
|
+
let base = {};
|
|
228
|
+
if (typeof dataOrUrl === 'string') {
|
|
229
|
+
if (/^(https?:\/\/|tg:\/\/)/i.test(dataOrUrl)) {
|
|
230
|
+
base = { url: dataOrUrl };
|
|
231
|
+
} else {
|
|
232
|
+
base = { callback_data: dataOrUrl };
|
|
233
|
+
}
|
|
234
|
+
} else if (typeof dataOrUrl === 'number') {
|
|
235
|
+
base = { callback_data: String(dataOrUrl) };
|
|
236
|
+
} else if (typeof dataOrUrl === 'object' && dataOrUrl !== null) {
|
|
237
|
+
base = dataOrUrl;
|
|
238
|
+
}
|
|
239
|
+
return {
|
|
240
|
+
text,
|
|
241
|
+
style: 'danger',
|
|
242
|
+
...base,
|
|
243
|
+
...options,
|
|
244
|
+
};
|
|
245
|
+
},
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Success colored button (Green / Positive Action - Bot API 9.4+)
|
|
249
|
+
* @param {string} text
|
|
250
|
+
* @param {string|number|object} [dataOrUrl]
|
|
251
|
+
* @param {object} [options]
|
|
252
|
+
*/
|
|
253
|
+
success: (text, dataOrUrl, options = {}) => {
|
|
254
|
+
let base = {};
|
|
255
|
+
if (typeof dataOrUrl === 'string') {
|
|
256
|
+
if (/^(https?:\/\/|tg:\/\/)/i.test(dataOrUrl)) {
|
|
257
|
+
base = { url: dataOrUrl };
|
|
258
|
+
} else {
|
|
259
|
+
base = { callback_data: dataOrUrl };
|
|
260
|
+
}
|
|
261
|
+
} else if (typeof dataOrUrl === 'number') {
|
|
262
|
+
base = { callback_data: String(dataOrUrl) };
|
|
263
|
+
} else if (typeof dataOrUrl === 'object' && dataOrUrl !== null) {
|
|
264
|
+
base = dataOrUrl;
|
|
265
|
+
}
|
|
266
|
+
return {
|
|
267
|
+
text,
|
|
268
|
+
style: 'success',
|
|
269
|
+
...base,
|
|
270
|
+
...options,
|
|
271
|
+
};
|
|
272
|
+
},
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Generic colored button helper (Bot API 9.4+)
|
|
276
|
+
* @param {string} text
|
|
277
|
+
* @param {'primary'|'danger'|'success'} style
|
|
278
|
+
* @param {string|number|object} [dataOrUrl]
|
|
279
|
+
* @param {object} [options]
|
|
187
280
|
*/
|
|
188
|
-
|
|
281
|
+
colored: (text, style, dataOrUrl, options = {}) => {
|
|
282
|
+
let base = {};
|
|
283
|
+
if (typeof dataOrUrl === 'string') {
|
|
284
|
+
if (/^(https?:\/\/|tg:\/\/)/i.test(dataOrUrl)) {
|
|
285
|
+
base = { url: dataOrUrl };
|
|
286
|
+
} else {
|
|
287
|
+
base = { callback_data: dataOrUrl };
|
|
288
|
+
}
|
|
289
|
+
} else if (typeof dataOrUrl === 'number') {
|
|
290
|
+
base = { callback_data: String(dataOrUrl) };
|
|
291
|
+
} else if (typeof dataOrUrl === 'object' && dataOrUrl !== null) {
|
|
292
|
+
base = dataOrUrl;
|
|
293
|
+
}
|
|
294
|
+
return {
|
|
295
|
+
text,
|
|
296
|
+
style,
|
|
297
|
+
...base,
|
|
298
|
+
...options,
|
|
299
|
+
};
|
|
300
|
+
},
|
|
189
301
|
|
|
190
302
|
/**
|
|
191
303
|
* Web App button
|
package/lib/rich.js
CHANGED
|
@@ -171,6 +171,15 @@ export class RichMessageBuilder {
|
|
|
171
171
|
return this.quote(text, true);
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
+
/**
|
|
175
|
+
* Add a collapsible / expandable blockquote (alias)
|
|
176
|
+
* @param {string} text
|
|
177
|
+
* @returns {this}
|
|
178
|
+
*/
|
|
179
|
+
collapsibleQuote(text) {
|
|
180
|
+
return this.quote(text, true);
|
|
181
|
+
}
|
|
182
|
+
|
|
174
183
|
/**
|
|
175
184
|
* Add spoiler block
|
|
176
185
|
* @param {string} text
|
|
@@ -370,6 +379,51 @@ export class RichMessageBuilder {
|
|
|
370
379
|
return this.button(Markup.button.url(text, url));
|
|
371
380
|
}
|
|
372
381
|
|
|
382
|
+
/**
|
|
383
|
+
* Add primary colored button (Blue - Bot API 9.4+)
|
|
384
|
+
* @param {string} text
|
|
385
|
+
* @param {string|number|object} dataOrUrl
|
|
386
|
+
* @param {object} [options]
|
|
387
|
+
* @returns {this}
|
|
388
|
+
*/
|
|
389
|
+
primary(text, dataOrUrl, options = {}) {
|
|
390
|
+
return this.button(Markup.button.primary(text, dataOrUrl, options));
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Add danger colored button (Red - Bot API 9.4+)
|
|
395
|
+
* @param {string} text
|
|
396
|
+
* @param {string|number|object} dataOrUrl
|
|
397
|
+
* @param {object} [options]
|
|
398
|
+
* @returns {this}
|
|
399
|
+
*/
|
|
400
|
+
danger(text, dataOrUrl, options = {}) {
|
|
401
|
+
return this.button(Markup.button.danger(text, dataOrUrl, options));
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Add success colored button (Green - Bot API 9.4+)
|
|
406
|
+
* @param {string} text
|
|
407
|
+
* @param {string|number|object} dataOrUrl
|
|
408
|
+
* @param {object} [options]
|
|
409
|
+
* @returns {this}
|
|
410
|
+
*/
|
|
411
|
+
success(text, dataOrUrl, options = {}) {
|
|
412
|
+
return this.button(Markup.button.success(text, dataOrUrl, options));
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Add generic colored button (Bot API 9.4+)
|
|
417
|
+
* @param {string} text
|
|
418
|
+
* @param {'primary'|'danger'|'success'} style
|
|
419
|
+
* @param {string|number|object} dataOrUrl
|
|
420
|
+
* @param {object} [options]
|
|
421
|
+
* @returns {this}
|
|
422
|
+
*/
|
|
423
|
+
colored(text, style, dataOrUrl, options = {}) {
|
|
424
|
+
return this.button(Markup.button.colored(text, style, dataOrUrl, options));
|
|
425
|
+
}
|
|
426
|
+
|
|
373
427
|
/**
|
|
374
428
|
* Add Bot API 10.3 disabled button
|
|
375
429
|
* @param {string} text
|