@codebam/cf-workers-telegram-bot 11.13.0 → 12.0.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/main.d.ts +1 -21
- package/dist/main.js +1 -7
- package/dist/telegram_api.d.ts +24 -13
- package/dist/telegram_api.js +52 -25
- package/dist/telegram_bot.d.ts +2 -3
- package/dist/telegram_bot.js +5 -3
- package/dist/telegram_execution_context.d.ts +16 -11
- package/dist/telegram_execution_context.js +229 -201
- package/dist/types/PartialTelegramUpdate.d.ts +6 -6
- package/dist/types/TelegramCommand.d.ts +1 -1
- package/dist/types/TelegramGuestMessage.d.ts +1 -1
- package/dist/types.d.ts +1 -13
- package/dist/types.js +1 -5
- package/dist/utils.js +4 -3
- package/package.json +3 -3
- package/dist/types/ChatPermissions.d.ts +0 -17
- package/dist/types/ChatPermissions.js +0 -1
- package/dist/types/TelegramBusinessConnection.d.ts +0 -10
- package/dist/types/TelegramBusinessConnection.js +0 -1
- package/dist/types/TelegramBusinessMessage.d.ts +0 -47
- package/dist/types/TelegramBusinessMessage.js +0 -1
- package/dist/types/TelegramCallbackQuery.d.ts +0 -15
- package/dist/types/TelegramCallbackQuery.js +0 -1
- package/dist/types/TelegramChat.d.ts +0 -21
- package/dist/types/TelegramChat.js +0 -1
- package/dist/types/TelegramDocument.d.ts +0 -10
- package/dist/types/TelegramDocument.js +0 -1
- package/dist/types/TelegramFrom.d.ts +0 -8
- package/dist/types/TelegramFrom.js +0 -1
- package/dist/types/TelegramInlineQuery.d.ts +0 -9
- package/dist/types/TelegramInlineQuery.js +0 -1
- package/dist/types/TelegramInlineQueryResult.d.ts +0 -6
- package/dist/types/TelegramInlineQueryResult.js +0 -8
- package/dist/types/TelegramInlineQueryResultArticle.d.ts +0 -13
- package/dist/types/TelegramInlineQueryResultArticle.js +0 -15
- package/dist/types/TelegramInlineQueryResultPhoto.d.ts +0 -21
- package/dist/types/TelegramInlineQueryResultPhoto.js +0 -23
- package/dist/types/TelegramInlineQueryResultVideo.d.ts +0 -21
- package/dist/types/TelegramInlineQueryResultVideo.js +0 -23
- package/dist/types/TelegramInlineQueryResultVoice.d.ts +0 -13
- package/dist/types/TelegramInlineQueryResultVoice.js +0 -14
- package/dist/types/TelegramInputMessageContent.d.ts +0 -5
- package/dist/types/TelegramInputMessageContent.js +0 -1
- package/dist/types/TelegramMessage.d.ts +0 -53
- package/dist/types/TelegramMessage.js +0 -1
- package/dist/types/TelegramMessageEntity.d.ts +0 -10
- package/dist/types/TelegramMessageEntity.js +0 -1
- package/dist/types/TelegramPhotoSize.d.ts +0 -8
- package/dist/types/TelegramPhotoSize.js +0 -1
- package/dist/types/TelegramPreCheckoutQuery.d.ts +0 -23
- package/dist/types/TelegramPreCheckoutQuery.js +0 -1
- package/dist/types/TelegramSuccessfulPayment.d.ts +0 -22
- package/dist/types/TelegramSuccessfulPayment.js +0 -1
- package/dist/types/TelegramUpdate.d.ts +0 -22
- package/dist/types/TelegramUpdate.js +0 -40
- package/dist/types/TelegramUser.d.ts +0 -13
- package/dist/types/TelegramUser.js +0 -1
- package/dist/types/TelegramVoice.d.ts +0 -7
- package/dist/types/TelegramVoice.js +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import TelegramApi from './telegram_api.js';
|
|
2
|
-
import TelegramInlineQueryResultArticle from './types/TelegramInlineQueryResultArticle.js';
|
|
3
|
-
import TelegramInlineQueryResultPhoto from './types/TelegramInlineQueryResultPhoto.js';
|
|
4
|
-
import TelegramInlineQueryResultVideo from './types/TelegramInlineQueryResultVideo.js';
|
|
5
|
-
import TelegramInlineQueryResultVoice from './types/TelegramInlineQueryResultVoice.js';
|
|
6
2
|
/** Class representing the context of execution */
|
|
7
3
|
export default class TelegramExecutionContext {
|
|
4
|
+
/** Cache for business connection owners */
|
|
5
|
+
static businessOwners = new Map();
|
|
6
|
+
/** Cache for dead business connections */
|
|
7
|
+
static poisonedConnections = new Set();
|
|
8
8
|
/** an instance of the telegram bot */
|
|
9
9
|
bot;
|
|
10
10
|
/** an instance of the telegram update */
|
|
@@ -45,7 +45,7 @@ export default class TelegramExecutionContext {
|
|
|
45
45
|
* @returns The user ID or undefined if not available
|
|
46
46
|
*/
|
|
47
47
|
get userId() {
|
|
48
|
-
return this.update.message?.from
|
|
48
|
+
return this.update.message?.from?.id ?? this.update.business_message?.from?.id ?? this.update.guest_message?.from?.id;
|
|
49
49
|
}
|
|
50
50
|
/**
|
|
51
51
|
* Parse arguments from the update
|
|
@@ -67,6 +67,54 @@ export default class TelegramExecutionContext {
|
|
|
67
67
|
* Determine the type of update received
|
|
68
68
|
* @returns The update type as a string
|
|
69
69
|
*/
|
|
70
|
+
/**
|
|
71
|
+
* Determine if the current update should be processed.
|
|
72
|
+
* For business messages, this checks if the connection is valid and has reply permissions.
|
|
73
|
+
*/
|
|
74
|
+
async shouldProcess() {
|
|
75
|
+
if (this.update_type !== 'business_message') {
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
const connectionId = this.update.business_message?.business_connection_id?.toString();
|
|
79
|
+
if (!connectionId) {
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
if (TelegramExecutionContext.poisonedConnections.has(connectionId)) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
let ownerId = TelegramExecutionContext.businessOwners.get(connectionId);
|
|
86
|
+
if (ownerId === undefined) {
|
|
87
|
+
try {
|
|
88
|
+
const response = await this.api.getBusinessConnection(this.bot.api.toString(), connectionId);
|
|
89
|
+
if (response.status === 200) {
|
|
90
|
+
const json = await response.json();
|
|
91
|
+
if (json.ok && json.result) {
|
|
92
|
+
ownerId = json.result.user?.id || json.result.user_chat_id;
|
|
93
|
+
if (ownerId) {
|
|
94
|
+
TelegramExecutionContext.businessOwners.set(connectionId, ownerId);
|
|
95
|
+
}
|
|
96
|
+
if (json.result.can_reply === false) {
|
|
97
|
+
console.warn('Business connection ' + connectionId + ' lacks reply permissions, poisoning connection');
|
|
98
|
+
TelegramExecutionContext.poisonedConnections.add(connectionId);
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch (e) {
|
|
105
|
+
if (e instanceof Error && e.message === 'BUSINESS_CONNECTION_INVALID') {
|
|
106
|
+
console.warn('Business connection ' + connectionId + ' is invalid, poisoning connection');
|
|
107
|
+
TelegramExecutionContext.poisonedConnections.add(connectionId);
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
console.warn('Failed to fetch business connection info:', e);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (ownerId !== undefined && this.getChatId() === ownerId.toString()) {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
70
118
|
determineUpdateType() {
|
|
71
119
|
if (this.update.message?.photo) {
|
|
72
120
|
return 'photo';
|
|
@@ -127,6 +175,9 @@ export default class TelegramExecutionContext {
|
|
|
127
175
|
if (this.update.message?.message_id) {
|
|
128
176
|
return this.update.message.message_id.toString();
|
|
129
177
|
}
|
|
178
|
+
else if (this.update.business_message?.message_id) {
|
|
179
|
+
return this.update.business_message.message_id.toString();
|
|
180
|
+
}
|
|
130
181
|
else if (this.update.guest_message?.message_id) {
|
|
131
182
|
return this.update.guest_message.message_id.toString();
|
|
132
183
|
}
|
|
@@ -137,7 +188,7 @@ export default class TelegramExecutionContext {
|
|
|
137
188
|
* @returns The message thread ID as a number or undefined
|
|
138
189
|
*/
|
|
139
190
|
getThreadId() {
|
|
140
|
-
return this.update.message?.message_thread_id;
|
|
191
|
+
return this.update.message?.message_thread_id ?? this.update.business_message?.message_thread_id;
|
|
141
192
|
}
|
|
142
193
|
/**
|
|
143
194
|
* Reply to the last message with a video
|
|
@@ -145,36 +196,85 @@ export default class TelegramExecutionContext {
|
|
|
145
196
|
* @param options - any additional options to pass to sendVideo
|
|
146
197
|
* @returns Promise with the API response
|
|
147
198
|
*/
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
|
|
199
|
+
/**
|
|
200
|
+
* Helper to handle business connection fallbacks
|
|
201
|
+
*/
|
|
202
|
+
async withBusinessFallback(params, apiMethod) {
|
|
203
|
+
const connectionId = params.business_connection_id?.toString();
|
|
204
|
+
if (connectionId) {
|
|
205
|
+
if (TelegramExecutionContext.poisonedConnections.has(connectionId)) {
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
let ownerId = TelegramExecutionContext.businessOwners.get(connectionId);
|
|
209
|
+
if (ownerId === undefined) {
|
|
210
|
+
try {
|
|
211
|
+
const response = await this.api.getBusinessConnection(this.bot.api.toString(), connectionId);
|
|
212
|
+
if (response.status === 200) {
|
|
213
|
+
const json = await response.json();
|
|
214
|
+
if (json.ok && json.result) {
|
|
215
|
+
ownerId = json.result.user?.id || json.result.user_chat_id;
|
|
216
|
+
if (ownerId) {
|
|
217
|
+
TelegramExecutionContext.businessOwners.set(connectionId, ownerId);
|
|
218
|
+
}
|
|
219
|
+
if (json.result.can_reply === false) {
|
|
220
|
+
TelegramExecutionContext.poisonedConnections.add(connectionId);
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
catch (e) {
|
|
227
|
+
if (e instanceof Error && e.message === 'BUSINESS_CONNECTION_INVALID') {
|
|
228
|
+
TelegramExecutionContext.poisonedConnections.add(connectionId);
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (ownerId !== undefined && params.chat_id?.toString() === ownerId.toString()) {
|
|
176
234
|
return null;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
try {
|
|
238
|
+
return await apiMethod(this.bot.api.toString(), params);
|
|
177
239
|
}
|
|
240
|
+
catch (e) {
|
|
241
|
+
if (e instanceof Error) {
|
|
242
|
+
if (e.message === 'BUSINESS_CONNECTION_INVALID') {
|
|
243
|
+
if (connectionId) {
|
|
244
|
+
TelegramExecutionContext.poisonedConnections.add(connectionId);
|
|
245
|
+
}
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
if (e.message === 'PEER_ID_INVALID') {
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
throw e;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
async replyVideo(video, options = {}) {
|
|
256
|
+
const params = {
|
|
257
|
+
...options,
|
|
258
|
+
chat_id: this.getChatId(),
|
|
259
|
+
message_thread_id: this.getThreadId(),
|
|
260
|
+
reply_to_message_id: this.getMessageId(),
|
|
261
|
+
video,
|
|
262
|
+
};
|
|
263
|
+
if (this.update_type === 'business_message') {
|
|
264
|
+
params['business_connection_id'] = this.update.business_message?.business_connection_id;
|
|
265
|
+
return await this.withBusinessFallback(params, (api, data) => this.api.sendVideo(api, data));
|
|
266
|
+
}
|
|
267
|
+
if (this.update_type === 'guest_message') {
|
|
268
|
+
return await this.answerGuestQueryVideo(video);
|
|
269
|
+
}
|
|
270
|
+
if (this.update_type === 'inline') {
|
|
271
|
+
return await this.api.answerInline(this.bot.api.toString(), {
|
|
272
|
+
...options,
|
|
273
|
+
inline_query_id: this.update.inline_query?.id.toString() ?? '',
|
|
274
|
+
results: [{ type: 'video', id: crypto.randomUUID(), video_url: video, mime_type: 'video/mp4', thumbnail_url: video, title: 'Video' }],
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
return await this.api.sendVideo(this.bot.api.toString(), params);
|
|
178
278
|
}
|
|
179
279
|
/**
|
|
180
280
|
* Get File from telegram file_id
|
|
@@ -192,37 +292,28 @@ export default class TelegramExecutionContext {
|
|
|
192
292
|
* @returns Promise with the API response
|
|
193
293
|
*/
|
|
194
294
|
async replyPhoto(photo, caption = '', options = {}) {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
...options,
|
|
210
|
-
chat_id: this.getChatId(),
|
|
211
|
-
message_thread_id: this.getThreadId(),
|
|
212
|
-
business_connection_id: this.update.business_message?.business_connection_id.toString() ?? '',
|
|
213
|
-
photo,
|
|
214
|
-
caption,
|
|
215
|
-
});
|
|
216
|
-
case 'guest_message':
|
|
217
|
-
return await this.answerGuestQueryPhoto(photo, caption);
|
|
218
|
-
case 'inline':
|
|
219
|
-
return await this.api.answerInline(this.bot.api.toString(), {
|
|
220
|
-
inline_query_id: this.update.inline_query?.id.toString() ?? '',
|
|
221
|
-
results: [new TelegramInlineQueryResultPhoto({ photo })],
|
|
222
|
-
});
|
|
223
|
-
default:
|
|
224
|
-
return null;
|
|
295
|
+
const params = {
|
|
296
|
+
...options,
|
|
297
|
+
chat_id: this.getChatId(),
|
|
298
|
+
message_thread_id: this.getThreadId(),
|
|
299
|
+
reply_to_message_id: this.getMessageId(),
|
|
300
|
+
photo,
|
|
301
|
+
caption,
|
|
302
|
+
};
|
|
303
|
+
if (this.update_type === 'business_message') {
|
|
304
|
+
params['business_connection_id'] = this.update.business_message?.business_connection_id;
|
|
305
|
+
return await this.withBusinessFallback(params, (api, data) => this.api.sendPhoto(api, data));
|
|
306
|
+
}
|
|
307
|
+
if (this.update_type === 'guest_message') {
|
|
308
|
+
return await this.answerGuestQueryPhoto(photo, caption);
|
|
225
309
|
}
|
|
310
|
+
if (this.update_type === 'inline') {
|
|
311
|
+
return await this.api.answerInline(this.bot.api.toString(), {
|
|
312
|
+
inline_query_id: this.update.inline_query?.id.toString() ?? '',
|
|
313
|
+
results: [{ type: 'photo', id: crypto.randomUUID(), photo_url: photo, thumbnail_url: photo }],
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
return await this.api.sendPhoto(this.bot.api.toString(), params);
|
|
226
317
|
}
|
|
227
318
|
/**
|
|
228
319
|
* Reply to the last message with a voice message
|
|
@@ -232,57 +323,38 @@ export default class TelegramExecutionContext {
|
|
|
232
323
|
* @returns Promise with the API response
|
|
233
324
|
*/
|
|
234
325
|
async replyVoice(voice, caption = '', options = {}) {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
chat_id: this.getChatId(),
|
|
250
|
-
message_thread_id: this.getThreadId(),
|
|
251
|
-
business_connection_id: this.update.business_message?.business_connection_id.toString() ?? '',
|
|
252
|
-
voice,
|
|
253
|
-
caption,
|
|
254
|
-
});
|
|
255
|
-
case 'guest_message':
|
|
256
|
-
return await this.answerGuestQueryVoice(voice, caption);
|
|
257
|
-
default:
|
|
258
|
-
return null;
|
|
326
|
+
const params = {
|
|
327
|
+
...options,
|
|
328
|
+
chat_id: this.getChatId(),
|
|
329
|
+
message_thread_id: this.getThreadId(),
|
|
330
|
+
reply_to_message_id: this.getMessageId(),
|
|
331
|
+
voice,
|
|
332
|
+
caption,
|
|
333
|
+
};
|
|
334
|
+
if (this.update_type === 'business_message') {
|
|
335
|
+
params['business_connection_id'] = this.update.business_message?.business_connection_id;
|
|
336
|
+
return await this.withBusinessFallback(params, (api, data) => this.api.sendVoice(api, data));
|
|
337
|
+
}
|
|
338
|
+
if (this.update_type === 'guest_message') {
|
|
339
|
+
return await this.answerGuestQueryVoice(voice, caption);
|
|
259
340
|
}
|
|
341
|
+
return await this.api.sendVoice(this.bot.api.toString(), params);
|
|
260
342
|
}
|
|
261
343
|
/**
|
|
262
344
|
* Send typing in a chat
|
|
263
345
|
* @returns Promise with the API response
|
|
264
346
|
*/
|
|
265
347
|
async sendTyping() {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
action: 'typing',
|
|
275
|
-
});
|
|
276
|
-
case 'business_message':
|
|
277
|
-
return await this.api.sendChatAction(this.bot.api.toString(), {
|
|
278
|
-
business_connection_id: this.update.business_message?.business_connection_id.toString() ?? '',
|
|
279
|
-
chat_id: this.getChatId(),
|
|
280
|
-
message_thread_id: this.getThreadId(),
|
|
281
|
-
action: 'typing',
|
|
282
|
-
});
|
|
283
|
-
default:
|
|
284
|
-
return null;
|
|
348
|
+
const params = {
|
|
349
|
+
chat_id: this.getChatId(),
|
|
350
|
+
message_thread_id: this.getThreadId(),
|
|
351
|
+
action: 'typing',
|
|
352
|
+
};
|
|
353
|
+
if (this.update_type === 'business_message') {
|
|
354
|
+
params['business_connection_id'] = this.update.business_message?.business_connection_id;
|
|
355
|
+
return await this.withBusinessFallback(params, (api, data) => this.api.sendChatAction(api, data));
|
|
285
356
|
}
|
|
357
|
+
return await this.api.sendChatAction(this.bot.api.toString(), params);
|
|
286
358
|
}
|
|
287
359
|
/**
|
|
288
360
|
* Reply to an inline message with a title and content
|
|
@@ -295,7 +367,7 @@ export default class TelegramExecutionContext {
|
|
|
295
367
|
if (this.update_type === 'inline') {
|
|
296
368
|
return await this.api.answerInline(this.bot.api.toString(), {
|
|
297
369
|
inline_query_id: this.update.inline_query?.id.toString() ?? '',
|
|
298
|
-
results: [
|
|
370
|
+
results: [{ type: 'article', id: crypto.randomUUID(), title: title ?? '', input_message_content: { message_text: message, parse_mode: parse_mode } }],
|
|
299
371
|
});
|
|
300
372
|
}
|
|
301
373
|
return null;
|
|
@@ -318,7 +390,7 @@ export default class TelegramExecutionContext {
|
|
|
318
390
|
* @returns Promise with the API response
|
|
319
391
|
*/
|
|
320
392
|
async answerGuestQueryText(message, parse_mode = '') {
|
|
321
|
-
return await this.answerGuestQuery(
|
|
393
|
+
return await this.answerGuestQuery({ type: 'article', id: crypto.randomUUID(), title: 'Response', input_message_content: { message_text: message, parse_mode: parse_mode } });
|
|
322
394
|
}
|
|
323
395
|
/**
|
|
324
396
|
* Answer a guest query with a photo
|
|
@@ -328,7 +400,7 @@ export default class TelegramExecutionContext {
|
|
|
328
400
|
* @returns Promise with the API response
|
|
329
401
|
*/
|
|
330
402
|
async answerGuestQueryPhoto(photo, caption = '', parse_mode = '') {
|
|
331
|
-
return await this.answerGuestQuery(
|
|
403
|
+
return await this.answerGuestQuery({ type: 'photo', id: crypto.randomUUID(), photo_url: photo, thumbnail_url: photo, caption, parse_mode: parse_mode });
|
|
332
404
|
}
|
|
333
405
|
/**
|
|
334
406
|
* Answer a guest query with a video
|
|
@@ -338,7 +410,7 @@ export default class TelegramExecutionContext {
|
|
|
338
410
|
* @returns Promise with the API response
|
|
339
411
|
*/
|
|
340
412
|
async answerGuestQueryVideo(video, caption = '', parse_mode = '') {
|
|
341
|
-
return await this.answerGuestQuery(
|
|
413
|
+
return await this.answerGuestQuery({ type: 'video', id: crypto.randomUUID(), video_url: video, mime_type: 'video/mp4', thumbnail_url: video, title: 'Video', caption, parse_mode: parse_mode });
|
|
342
414
|
}
|
|
343
415
|
/**
|
|
344
416
|
* Answer a guest query with a voice message
|
|
@@ -348,7 +420,7 @@ export default class TelegramExecutionContext {
|
|
|
348
420
|
* @returns Promise with the API response
|
|
349
421
|
*/
|
|
350
422
|
async answerGuestQueryVoice(voice, caption = '', parse_mode = '') {
|
|
351
|
-
return await this.answerGuestQuery(
|
|
423
|
+
return await this.answerGuestQuery({ type: 'voice', id: crypto.randomUUID(), voice_url: voice, title: 'Voice', caption, parse_mode: parse_mode });
|
|
352
424
|
}
|
|
353
425
|
/** Map of draft IDs to message IDs for streaming */
|
|
354
426
|
drafts = new Map();
|
|
@@ -360,104 +432,56 @@ export default class TelegramExecutionContext {
|
|
|
360
432
|
* @param options - any additional options to pass to sendMessage/editMessageText
|
|
361
433
|
* @returns Promise with the API response
|
|
362
434
|
*/
|
|
363
|
-
async streamReply(message, draft_id, parse_mode = '', options = {}) {
|
|
364
|
-
const message_id = this.drafts.get(draft_id);
|
|
365
|
-
const business_connection_id = this.update.business_message?.business_connection_id.toString();
|
|
366
|
-
if (message_id) {
|
|
367
|
-
return await this.api.editMessageText(this.bot.api.toString(), {
|
|
368
|
-
chat_id: this.getChatId(),
|
|
369
|
-
message_id,
|
|
370
|
-
text: message,
|
|
371
|
-
parse_mode,
|
|
372
|
-
business_connection_id,
|
|
373
|
-
...options,
|
|
374
|
-
});
|
|
375
|
-
}
|
|
435
|
+
async streamReply(message, draft_id, parse_mode = '', options = {}, finish = false) {
|
|
376
436
|
if (this.update_type === 'guest_message') {
|
|
377
|
-
if (
|
|
378
|
-
return
|
|
437
|
+
if (finish) {
|
|
438
|
+
return await this.answerGuestQueryText(message, parse_mode);
|
|
379
439
|
}
|
|
380
|
-
|
|
381
|
-
|
|
440
|
+
return null;
|
|
441
|
+
}
|
|
442
|
+
if (finish) {
|
|
443
|
+
return await this.reply(message, parse_mode, true, options);
|
|
382
444
|
}
|
|
383
|
-
const
|
|
445
|
+
const params = {
|
|
384
446
|
...options,
|
|
385
447
|
chat_id: this.getChatId(),
|
|
386
448
|
message_thread_id: this.getThreadId(),
|
|
387
449
|
text: message,
|
|
388
450
|
parse_mode,
|
|
389
|
-
|
|
390
|
-
}
|
|
391
|
-
if (
|
|
392
|
-
|
|
393
|
-
try {
|
|
394
|
-
const json = (await cloned.json());
|
|
395
|
-
if (json.ok && json.result?.message_id) {
|
|
396
|
-
this.drafts.set(draft_id, json.result.message_id);
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
catch {
|
|
400
|
-
// ignore
|
|
401
|
-
}
|
|
451
|
+
draft_id,
|
|
452
|
+
};
|
|
453
|
+
if (this.update_type === 'business_message') {
|
|
454
|
+
params.business_connection_id = this.update.business_message?.business_connection_id;
|
|
402
455
|
}
|
|
403
|
-
return
|
|
456
|
+
return await this.withBusinessFallback(params, (api, data) => this.api.sendMessageDraft(api, data));
|
|
404
457
|
}
|
|
405
|
-
/**
|
|
406
|
-
* Reply to the last message with text
|
|
407
|
-
* @param message - text to reply with
|
|
408
|
-
* @param parse_mode - one of HTML, MarkdownV2, Markdown, or an empty string for ascii
|
|
409
|
-
* @param options - any additional options to pass to sendMessage
|
|
410
|
-
* @returns Promise with the API response
|
|
411
|
-
*/
|
|
412
458
|
async reply(message, parse_mode = '', reply = true, options = {}) {
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
if (reply) {
|
|
419
|
-
return await this.api.sendMessage(this.bot.api.toString(), {
|
|
420
|
-
...options,
|
|
421
|
-
chat_id: this.getChatId(),
|
|
422
|
-
message_thread_id: this.getThreadId(),
|
|
423
|
-
reply_to_message_id: this.getMessageId(),
|
|
424
|
-
text: message,
|
|
425
|
-
parse_mode,
|
|
426
|
-
});
|
|
427
|
-
}
|
|
428
|
-
return await this.api.sendMessage(this.bot.api.toString(), {
|
|
429
|
-
...options,
|
|
430
|
-
chat_id: this.getChatId(),
|
|
431
|
-
message_thread_id: this.getThreadId(),
|
|
432
|
-
text: message,
|
|
433
|
-
parse_mode,
|
|
434
|
-
});
|
|
435
|
-
case 'guest_message':
|
|
436
|
-
return await this.answerGuestQueryText(message, parse_mode);
|
|
437
|
-
case 'business_message':
|
|
438
|
-
return await this.api.sendMessage(this.bot.api.toString(), {
|
|
439
|
-
chat_id: this.getChatId(),
|
|
440
|
-
message_thread_id: this.getThreadId(),
|
|
441
|
-
text: message,
|
|
442
|
-
business_connection_id: this.update.business_message?.business_connection_id.toString() ?? '',
|
|
443
|
-
parse_mode,
|
|
444
|
-
});
|
|
445
|
-
case 'callback':
|
|
446
|
-
if (this.update.callback_query?.message.chat.id) {
|
|
447
|
-
return await this.api.sendMessage(this.bot.api.toString(), {
|
|
448
|
-
...options,
|
|
449
|
-
chat_id: this.update.callback_query.message.chat.id.toString(),
|
|
450
|
-
message_thread_id: this.getThreadId(),
|
|
451
|
-
text: message,
|
|
452
|
-
parse_mode,
|
|
453
|
-
});
|
|
454
|
-
}
|
|
455
|
-
return null;
|
|
456
|
-
case 'inline':
|
|
457
|
-
return await this.replyInline('Response', message, parse_mode);
|
|
458
|
-
default:
|
|
459
|
-
return null;
|
|
459
|
+
if (this.update_type === 'guest_message') {
|
|
460
|
+
return await this.answerGuestQueryText(message, parse_mode);
|
|
461
|
+
}
|
|
462
|
+
if (this.update_type === 'inline') {
|
|
463
|
+
return await this.replyInline('Response', message, parse_mode);
|
|
460
464
|
}
|
|
465
|
+
const params = {
|
|
466
|
+
...options,
|
|
467
|
+
chat_id: this.getChatId(),
|
|
468
|
+
message_thread_id: this.getThreadId(),
|
|
469
|
+
text: message,
|
|
470
|
+
parse_mode,
|
|
471
|
+
};
|
|
472
|
+
if (reply) {
|
|
473
|
+
params.reply_to_message_id = this.getMessageId();
|
|
474
|
+
}
|
|
475
|
+
if (this.update_type === 'business_message') {
|
|
476
|
+
params['business_connection_id'] = this.update.business_message?.business_connection_id;
|
|
477
|
+
return await this.withBusinessFallback(params, (api, data) => this.api.sendMessage(api, data));
|
|
478
|
+
}
|
|
479
|
+
if (this.update_type === 'callback') {
|
|
480
|
+
if (this.update.callback_query?.message?.chat.id) {
|
|
481
|
+
params['chat_id'] = this.update.callback_query.message.chat.id.toString();
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
return await this.api.sendMessage(this.bot.api.toString(), params);
|
|
461
485
|
}
|
|
462
486
|
/**
|
|
463
487
|
* Send an invoice for Telegram Stars
|
|
@@ -468,17 +492,21 @@ export default class TelegramExecutionContext {
|
|
|
468
492
|
* @returns Promise with the API response
|
|
469
493
|
*/
|
|
470
494
|
async sendStarsInvoice(title, description, payload, amount) {
|
|
471
|
-
|
|
495
|
+
const params = {
|
|
472
496
|
chat_id: this.getChatId(),
|
|
473
497
|
message_thread_id: this.getThreadId(),
|
|
474
|
-
business_connection_id: this.update.business_message?.business_connection_id.toString(),
|
|
475
498
|
title,
|
|
476
499
|
description,
|
|
477
500
|
payload,
|
|
478
501
|
provider_token: '',
|
|
479
502
|
currency: 'XTR',
|
|
480
503
|
prices: [{ label: title, amount }],
|
|
481
|
-
}
|
|
504
|
+
};
|
|
505
|
+
if (this.update_type === 'business_message') {
|
|
506
|
+
params['business_connection_id'] = this.update.business_message?.business_connection_id;
|
|
507
|
+
return await this.withBusinessFallback(params, (api, data) => this.api.sendInvoice(api, data));
|
|
508
|
+
}
|
|
509
|
+
return await this.api.sendInvoice(this.bot.api.toString(), params);
|
|
482
510
|
}
|
|
483
511
|
/**
|
|
484
512
|
* Answer a pre-checkout query
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import TelegramBusinessMessage from '
|
|
2
|
-
import TelegramInlineQuery from '
|
|
3
|
-
import TelegramMessage from '
|
|
1
|
+
import { Message as TelegramBusinessMessage } from '@grammyjs/types';
|
|
2
|
+
import { InlineQuery as TelegramInlineQuery } from '@grammyjs/types';
|
|
3
|
+
import { Message as TelegramMessage } from '@grammyjs/types';
|
|
4
4
|
import TelegramGuestMessage from './TelegramGuestMessage.js';
|
|
5
|
-
import TelegramPreCheckoutQuery from '
|
|
6
|
-
import TelegramCallbackQuery from '
|
|
7
|
-
import TelegramBusinessConnection from '
|
|
5
|
+
import { PreCheckoutQuery as TelegramPreCheckoutQuery } from '@grammyjs/types';
|
|
6
|
+
import { CallbackQuery as TelegramCallbackQuery } from '@grammyjs/types';
|
|
7
|
+
import { BusinessConnection as TelegramBusinessConnection } from '@grammyjs/types';
|
|
8
8
|
interface PartialTelegramUpdate {
|
|
9
9
|
update_id?: number;
|
|
10
10
|
message?: TelegramMessage;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import TelegramBot from '../telegram_bot.js';
|
|
2
|
-
import TelegramUpdate from '
|
|
2
|
+
import { Update as TelegramUpdate } from '@grammyjs/types';
|
|
3
3
|
type TelegramCommand = (bot: TelegramBot, update: TelegramUpdate, args: string[]) => Promise<Response>;
|
|
4
4
|
export default TelegramCommand;
|
package/dist/types.d.ts
CHANGED
|
@@ -1,22 +1,10 @@
|
|
|
1
|
+
import { Chat as TelegramChat, User as TelegramUser, User as TelegramFrom, MessageEntity as TelegramMessageEntity, PhotoSize as TelegramPhotoSize, Message as TelegramMessage, InputMessageContent as TelegramInputMessageContent, InlineQuery as TelegramInlineQuery, Update as TelegramUpdate, InlineQueryResult as TelegramInlineQueryResult, InlineQueryResultPhoto as TelegramInlineQueryResultPhoto, InlineQueryResultArticle as TelegramInlineQueryResultArticle, ChatPermissions as ChatPermissions } from '@grammyjs/types';
|
|
1
2
|
import TelegramBot from './telegram_bot.js';
|
|
2
3
|
import TelegramExecutionContext from './telegram_execution_context.js';
|
|
3
4
|
import Webhook from './webhook.js';
|
|
4
5
|
import TelegramApi from './telegram_api.js';
|
|
5
6
|
import TelegramCommand from './types/TelegramCommand.js';
|
|
6
|
-
import TelegramFrom from './types/TelegramFrom.js';
|
|
7
|
-
import TelegramChat from './types/TelegramChat.js';
|
|
8
|
-
import TelegramUser from './types/TelegramUser.js';
|
|
9
|
-
import TelegramMessageEntity from './types/TelegramMessageEntity.js';
|
|
10
|
-
import TelegramPhotoSize from './types/TelegramPhotoSize.js';
|
|
11
|
-
import TelegramMessage from './types/TelegramMessage.js';
|
|
12
|
-
import TelegramInputMessageContent from './types/TelegramInputMessageContent.js';
|
|
13
|
-
import TelegramInlineQuery from './types/TelegramInlineQuery.js';
|
|
14
|
-
import TelegramUpdate from './types/TelegramUpdate.js';
|
|
15
7
|
import PartialTelegramUpdate from './types/PartialTelegramUpdate.js';
|
|
16
8
|
import TelegramInlineQueryType from './types/TelegramInlineQueryType.js';
|
|
17
|
-
import TelegramInlineQueryResult from './types/TelegramInlineQueryResult.js';
|
|
18
|
-
import TelegramInlineQueryResultPhoto from './types/TelegramInlineQueryResultPhoto.js';
|
|
19
|
-
import TelegramInlineQueryResultArticle from './types/TelegramInlineQueryResultArticle.js';
|
|
20
|
-
import ChatPermissions from './types/ChatPermissions.js';
|
|
21
9
|
export default TelegramBot;
|
|
22
10
|
export { TelegramBot, TelegramExecutionContext, Webhook, TelegramApi, TelegramCommand, TelegramFrom, TelegramChat, TelegramUser, TelegramMessageEntity, TelegramPhotoSize, TelegramMessage, TelegramInputMessageContent, TelegramInlineQuery, TelegramUpdate, PartialTelegramUpdate, TelegramInlineQueryType, TelegramInlineQueryResult, TelegramInlineQueryResultPhoto, TelegramInlineQueryResultArticle, ChatPermissions, };
|
package/dist/types.js
CHANGED
|
@@ -2,9 +2,5 @@ import TelegramBot from './telegram_bot.js';
|
|
|
2
2
|
import TelegramExecutionContext from './telegram_execution_context.js';
|
|
3
3
|
import Webhook from './webhook.js';
|
|
4
4
|
import TelegramApi from './telegram_api.js';
|
|
5
|
-
import TelegramUpdate from './types/TelegramUpdate.js';
|
|
6
|
-
import TelegramInlineQueryResult from './types/TelegramInlineQueryResult.js';
|
|
7
|
-
import TelegramInlineQueryResultPhoto from './types/TelegramInlineQueryResultPhoto.js';
|
|
8
|
-
import TelegramInlineQueryResultArticle from './types/TelegramInlineQueryResultArticle.js';
|
|
9
5
|
export default TelegramBot;
|
|
10
|
-
export { TelegramBot, TelegramExecutionContext, Webhook, TelegramApi,
|
|
6
|
+
export { TelegramBot, TelegramExecutionContext, Webhook, TelegramApi, };
|
package/dist/utils.js
CHANGED
|
@@ -27,16 +27,17 @@ export async function markdownToHtml(s) {
|
|
|
27
27
|
return result;
|
|
28
28
|
};
|
|
29
29
|
renderer.listitem = (item) => {
|
|
30
|
-
return renderer.parser.
|
|
30
|
+
return renderer.parser.parse(item.tokens).trim();
|
|
31
31
|
};
|
|
32
32
|
renderer.strong = ({ tokens }) => `<b>${renderer.parser.parseInline(tokens)}</b>`;
|
|
33
33
|
renderer.em = ({ tokens }) => `<i>${renderer.parser.parseInline(tokens)}</i>`;
|
|
34
34
|
renderer.codespan = ({ text }) => `<code>${text}</code>`;
|
|
35
35
|
renderer.code = ({ text, lang }) => {
|
|
36
|
+
const escapedText = text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
36
37
|
if (lang) {
|
|
37
|
-
return `<pre><code class="language-${lang}">${
|
|
38
|
+
return `<pre><code class="language-${lang}">${escapedText}</code></pre>\n`;
|
|
38
39
|
}
|
|
39
|
-
return `<pre><code>${
|
|
40
|
+
return `<pre><code>${escapedText}</code></pre>\n`;
|
|
40
41
|
};
|
|
41
42
|
renderer.del = ({ tokens }) => `<s>${renderer.parser.parseInline(tokens)}</s>`;
|
|
42
43
|
renderer.link = ({ href, tokens }) => `<a href="${href}">${renderer.parser.parseInline(tokens)}</a>`;
|