UNPKG

24.7 kBPlain TextView Raw
1import * as tg from './core/types/typegram'
2import * as tt from './telegram-types'
3import { Deunionize, PropOr, UnionKeys } from './deunionize'
4import ApiClient from './core/network/client'
5import Telegram from './telegram'
6
7type Tail<T> = T extends [unknown, ...infer U] ? U : never
8
9type Shorthand<FName extends Exclude<keyof Telegram, keyof ApiClient>> = Tail<
10 Parameters<Telegram[FName]>
11>
12
13export class Context<U extends Deunionize<tg.Update> = tg.Update> {
14 readonly state: Record<string | symbol, any> = {}
15
16 constructor(
17 readonly update: U,
18 readonly tg: Telegram,
19 readonly botInfo: tg.UserFromGetMe
20 ) {}
21
22 get updateType() {
23 const types = Object.keys(this.update).filter(
24 (k) => typeof this.update[k as keyof U] === 'object'
25 )
26 if (types.length !== 1) {
27 throw new Error(
28 `Cannot determine \`updateType\` of ${JSON.stringify(this.update)}`
29 )
30 }
31 return types[0] as UpdateTypes<U>
32 }
33
34 get me() {
35 return this.botInfo?.username
36 }
37
38 get telegram() {
39 return this.tg
40 }
41
42 get message() {
43 return this.update.message as PropOr<U, 'message'>
44 }
45
46 get editedMessage() {
47 return this.update.edited_message as PropOr<U, 'edited_message'>
48 }
49
50 get inlineQuery() {
51 return this.update.inline_query as PropOr<U, 'inline_query'>
52 }
53
54 get shippingQuery() {
55 return this.update.shipping_query as PropOr<U, 'shipping_query'>
56 }
57
58 get preCheckoutQuery() {
59 return this.update.pre_checkout_query as PropOr<U, 'pre_checkout_query'>
60 }
61
62 get chosenInlineResult() {
63 return this.update.chosen_inline_result as PropOr<U, 'chosen_inline_result'>
64 }
65
66 get channelPost() {
67 return this.update.channel_post as PropOr<U, 'channel_post'>
68 }
69
70 get editedChannelPost() {
71 return this.update.edited_channel_post as PropOr<U, 'edited_channel_post'>
72 }
73
74 get callbackQuery() {
75 return this.update.callback_query as PropOr<U, 'callback_query'>
76 }
77
78 get poll() {
79 return this.update.poll as PropOr<U, 'poll'>
80 }
81
82 get pollAnswer() {
83 return this.update.poll_answer as PropOr<U, 'poll_answer'>
84 }
85
86 get myChatMember() {
87 return this.update.my_chat_member as PropOr<U, 'my_chat_member'>
88 }
89
90 get chatMember() {
91 return this.update.chat_member as PropOr<U, 'chat_member'>
92 }
93
94 get chat(): Getter<U, 'chat'> {
95 return (
96 this.chatMember ??
97 this.myChatMember ??
98 getMessageFromAnySource(this)
99 )?.chat as Getter<U, 'chat'>
100 }
101
102 get senderChat() {
103 return getMessageFromAnySource(this)?.sender_chat as Getter<
104 U,
105 'sender_chat'
106 >
107 }
108
109 get from() {
110 return (
111 this.callbackQuery ??
112 this.inlineQuery ??
113 this.shippingQuery ??
114 this.preCheckoutQuery ??
115 this.chosenInlineResult ??
116 this.chatMember ??
117 this.myChatMember ??
118 getMessageFromAnySource(this)
119 )?.from as Getter<U, 'from'>
120 }
121
122 get inlineMessageId() {
123 return (this.callbackQuery ?? this.chosenInlineResult)?.inline_message_id
124 }
125
126 get passportData() {
127 if (this.message == null) return undefined
128 if (!('passport_data' in this.message)) return undefined
129 return this.message?.passport_data
130 }
131
132 /**
133 * @deprecated use {@link Telegram.webhookReply}
134 */
135 get webhookReply(): boolean {
136 return this.tg.webhookReply
137 }
138
139 set webhookReply(enable: boolean) {
140 this.tg.webhookReply = enable
141 }
142
143 private assert<T extends string | object>(
144 value: T | undefined,
145 method: string
146 ): asserts value is T {
147 if (value === undefined) {
148 throw new TypeError(
149 `Telegraf: "${method}" isn't available for "${this.updateType}"`
150 )
151 }
152 }
153
154 /**
155 * @see https://core.telegram.org/bots/api#answerinlinequery
156 */
157 answerInlineQuery(this: Context, ...args: Shorthand<'answerInlineQuery'>) {
158 this.assert(this.inlineQuery, 'answerInlineQuery')
159 return this.telegram.answerInlineQuery(this.inlineQuery.id, ...args)
160 }
161
162 /**
163 * @see https://core.telegram.org/bots/api#answercallbackquery
164 */
165 answerCbQuery(this: Context, ...args: Shorthand<'answerCbQuery'>) {
166 this.assert(this.callbackQuery, 'answerCbQuery')
167 return this.telegram.answerCbQuery(this.callbackQuery.id, ...args)
168 }
169
170 /**
171 * @see https://core.telegram.org/bots/api#answercallbackquery
172 */
173 answerGameQuery(this: Context, ...args: Shorthand<'answerGameQuery'>) {
174 this.assert(this.callbackQuery, 'answerGameQuery')
175 return this.telegram.answerGameQuery(this.callbackQuery.id, ...args)
176 }
177
178 /**
179 * @see https://core.telegram.org/bots/api#answershippingquery
180 */
181 answerShippingQuery(
182 this: Context,
183 ...args: Shorthand<'answerShippingQuery'>
184 ) {
185 this.assert(this.shippingQuery, 'answerShippingQuery')
186 return this.telegram.answerShippingQuery(this.shippingQuery.id, ...args)
187 }
188
189 /**
190 * @see https://core.telegram.org/bots/api#answerprecheckoutquery
191 */
192 answerPreCheckoutQuery(
193 this: Context,
194 ...args: Shorthand<'answerPreCheckoutQuery'>
195 ) {
196 this.assert(this.preCheckoutQuery, 'answerPreCheckoutQuery')
197 return this.telegram.answerPreCheckoutQuery(
198 this.preCheckoutQuery.id,
199 ...args
200 )
201 }
202
203 /**
204 * @see https://core.telegram.org/bots/api#editmessagetext
205 */
206 editMessageText(
207 this: Context,
208 text: string,
209 extra?: tt.ExtraEditMessageText
210 ) {
211 this.assert(this.callbackQuery ?? this.inlineMessageId, 'editMessageText')
212 return this.telegram.editMessageText(
213 this.chat?.id,
214 this.callbackQuery?.message?.message_id,
215 this.inlineMessageId,
216 text,
217 extra
218 )
219 }
220
221 /**
222 * @see https://core.telegram.org/bots/api#editmessagecaption
223 */
224 editMessageCaption(
225 this: Context,
226 caption: string | undefined,
227 extra?: tt.ExtraEditMessageCaption
228 ) {
229 this.assert(
230 this.callbackQuery ?? this.inlineMessageId,
231 'editMessageCaption'
232 )
233 return this.telegram.editMessageCaption(
234 this.chat?.id,
235 this.callbackQuery?.message?.message_id,
236 this.inlineMessageId,
237 caption,
238 extra
239 )
240 }
241
242 /**
243 * @see https://core.telegram.org/bots/api#editmessagemedia
244 */
245 editMessageMedia(
246 this: Context,
247 media: tg.InputMedia,
248 extra?: tt.ExtraEditMessageMedia
249 ) {
250 this.assert(this.callbackQuery ?? this.inlineMessageId, 'editMessageMedia')
251 return this.telegram.editMessageMedia(
252 this.chat?.id,
253 this.callbackQuery?.message?.message_id,
254 this.inlineMessageId,
255 media,
256 extra
257 )
258 }
259
260 /**
261 * @see https://core.telegram.org/bots/api#editmessagereplymarkup
262 */
263 editMessageReplyMarkup(
264 this: Context,
265 markup: tg.InlineKeyboardMarkup | undefined
266 ) {
267 this.assert(
268 this.callbackQuery ?? this.inlineMessageId,
269 'editMessageReplyMarkup'
270 )
271 return this.telegram.editMessageReplyMarkup(
272 this.chat?.id,
273 this.callbackQuery?.message?.message_id,
274 this.inlineMessageId,
275 markup
276 )
277 }
278
279 /**
280 * @see https://core.telegram.org/bots/api#editmessagelivelocation
281 */
282 editMessageLiveLocation(
283 this: Context,
284 latitude: number,
285 longitude: number,
286 extra?: tt.ExtraEditMessageLiveLocation
287 ) {
288 this.assert(
289 this.callbackQuery ?? this.inlineMessageId,
290 'editMessageLiveLocation'
291 )
292 return this.telegram.editMessageLiveLocation(
293 this.chat?.id,
294 this.callbackQuery?.message?.message_id,
295 this.inlineMessageId,
296 latitude,
297 longitude,
298 extra
299 )
300 }
301
302 /**
303 * @see https://core.telegram.org/bots/api#stopmessagelivelocation
304 */
305 stopMessageLiveLocation(this: Context, markup?: tg.InlineKeyboardMarkup) {
306 this.assert(
307 this.callbackQuery ?? this.inlineMessageId,
308 'stopMessageLiveLocation'
309 )
310 return this.telegram.stopMessageLiveLocation(
311 this.chat?.id,
312 this.callbackQuery?.message?.message_id,
313 this.inlineMessageId,
314 markup
315 )
316 }
317
318 /**
319 * @see https://core.telegram.org/bots/api#sendmessage
320 */
321 reply(this: Context, ...args: Shorthand<'sendMessage'>) {
322 this.assert(this.chat, 'reply')
323 return this.telegram.sendMessage(this.chat.id, ...args)
324 }
325
326 /**
327 * @see https://core.telegram.org/bots/api#getchat
328 */
329 getChat(this: Context, ...args: Shorthand<'getChat'>) {
330 this.assert(this.chat, 'getChat')
331 return this.telegram.getChat(this.chat.id, ...args)
332 }
333
334 /**
335 * @see https://core.telegram.org/bots/api#exportchatinvitelink
336 */
337 exportChatInviteLink(
338 this: Context,
339 ...args: Shorthand<'exportChatInviteLink'>
340 ) {
341 this.assert(this.chat, 'exportChatInviteLink')
342 return this.telegram.exportChatInviteLink(this.chat.id, ...args)
343 }
344
345 /**
346 * @see https://core.telegram.org/bots/api#createchatinvitelink
347 */
348 createChatInviteLink(
349 this: Context,
350 ...args: Shorthand<'createChatInviteLink'>
351 ) {
352 this.assert(this.chat, 'createChatInviteLink')
353 return this.telegram.createChatInviteLink(this.chat.id, ...args)
354 }
355
356 /**
357 * @see https://core.telegram.org/bots/api#editchatinvitelink
358 */
359 editChatInviteLink(this: Context, ...args: Shorthand<'editChatInviteLink'>) {
360 this.assert(this.chat, 'editChatInviteLink')
361 return this.telegram.editChatInviteLink(this.chat.id, ...args)
362 }
363
364 /**
365 * @see https://core.telegram.org/bots/api#revokechatinvitelink
366 */
367 revokeChatInviteLink(
368 this: Context,
369 ...args: Shorthand<'revokeChatInviteLink'>
370 ) {
371 this.assert(this.chat, 'revokeChatInviteLink')
372 return this.telegram.revokeChatInviteLink(this.chat.id, ...args)
373 }
374
375 /**
376 * @see https://core.telegram.org/bots/api#banchatmember
377 */
378 kickChatMember(this: Context, ...args: Shorthand<'kickChatMember'>) {
379 this.assert(this.chat, 'kickChatMember')
380 return this.telegram.kickChatMember(this.chat.id, ...args)
381 }
382
383 /**
384 * @see https://core.telegram.org/bots/api#unbanchatmember
385 */
386 unbanChatMember(this: Context, ...args: Shorthand<'unbanChatMember'>) {
387 this.assert(this.chat, 'unbanChatMember')
388 return this.telegram.unbanChatMember(this.chat.id, ...args)
389 }
390
391 /**
392 * @see https://core.telegram.org/bots/api#restrictchatmember
393 */
394 restrictChatMember(this: Context, ...args: Shorthand<'restrictChatMember'>) {
395 this.assert(this.chat, 'restrictChatMember')
396 return this.telegram.restrictChatMember(this.chat.id, ...args)
397 }
398
399 /**
400 * @see https://core.telegram.org/bots/api#promotechatmember
401 */
402 promoteChatMember(this: Context, ...args: Shorthand<'promoteChatMember'>) {
403 this.assert(this.chat, 'promoteChatMember')
404 return this.telegram.promoteChatMember(this.chat.id, ...args)
405 }
406
407 /**
408 * @see https://core.telegram.org/bots/api#setchatadministratorcustomtitle
409 */
410 setChatAdministratorCustomTitle(
411 this: Context,
412 ...args: Shorthand<'setChatAdministratorCustomTitle'>
413 ) {
414 this.assert(this.chat, 'setChatAdministratorCustomTitle')
415 return this.telegram.setChatAdministratorCustomTitle(this.chat.id, ...args)
416 }
417
418 /**
419 * @see https://core.telegram.org/bots/api#setchatphoto
420 */
421 setChatPhoto(this: Context, ...args: Shorthand<'setChatPhoto'>) {
422 this.assert(this.chat, 'setChatPhoto')
423 return this.telegram.setChatPhoto(this.chat.id, ...args)
424 }
425
426 /**
427 * @see https://core.telegram.org/bots/api#deletechatphoto
428 */
429 deleteChatPhoto(this: Context, ...args: Shorthand<'deleteChatPhoto'>) {
430 this.assert(this.chat, 'deleteChatPhoto')
431 return this.telegram.deleteChatPhoto(this.chat.id, ...args)
432 }
433
434 /**
435 * @see https://core.telegram.org/bots/api#setchattitle
436 */
437 setChatTitle(this: Context, ...args: Shorthand<'setChatTitle'>) {
438 this.assert(this.chat, 'setChatTitle')
439 return this.telegram.setChatTitle(this.chat.id, ...args)
440 }
441
442 /**
443 * @see https://core.telegram.org/bots/api#setchatdescription
444 */
445 setChatDescription(this: Context, ...args: Shorthand<'setChatDescription'>) {
446 this.assert(this.chat, 'setChatDescription')
447 return this.telegram.setChatDescription(this.chat.id, ...args)
448 }
449
450 /**
451 * @see https://core.telegram.org/bots/api#pinchatmessage
452 */
453 pinChatMessage(this: Context, ...args: Shorthand<'pinChatMessage'>) {
454 this.assert(this.chat, 'pinChatMessage')
455 return this.telegram.pinChatMessage(this.chat.id, ...args)
456 }
457
458 /**
459 * @see https://core.telegram.org/bots/api#unpinchatmessage
460 */
461 unpinChatMessage(this: Context, ...args: Shorthand<'unpinChatMessage'>) {
462 this.assert(this.chat, 'unpinChatMessage')
463 return this.telegram.unpinChatMessage(this.chat.id, ...args)
464 }
465
466 /**
467 * @see https://core.telegram.org/bots/api#unpinallchatmessages
468 */
469 unpinAllChatMessages(
470 this: Context,
471 ...args: Shorthand<'unpinAllChatMessages'>
472 ) {
473 this.assert(this.chat, 'unpinAllChatMessages')
474 return this.telegram.unpinAllChatMessages(this.chat.id, ...args)
475 }
476
477 /**
478 * @see https://core.telegram.org/bots/api#leavechat
479 */
480 leaveChat(this: Context, ...args: Shorthand<'leaveChat'>) {
481 this.assert(this.chat, 'leaveChat')
482 return this.telegram.leaveChat(this.chat.id, ...args)
483 }
484
485 /**
486 * @see https://core.telegram.org/bots/api#setchatpermissions
487 */
488 setChatPermissions(this: Context, ...args: Shorthand<'setChatPermissions'>) {
489 this.assert(this.chat, 'setChatPermissions')
490 return this.telegram.setChatPermissions(this.chat.id, ...args)
491 }
492
493 /**
494 * @see https://core.telegram.org/bots/api#getchatadministrators
495 */
496 getChatAdministrators(
497 this: Context,
498 ...args: Shorthand<'getChatAdministrators'>
499 ) {
500 this.assert(this.chat, 'getChatAdministrators')
501 return this.telegram.getChatAdministrators(this.chat.id, ...args)
502 }
503
504 /**
505 * @see https://core.telegram.org/bots/api#getchatmember
506 */
507 getChatMember(this: Context, ...args: Shorthand<'getChatMember'>) {
508 this.assert(this.chat, 'getChatMember')
509 return this.telegram.getChatMember(this.chat.id, ...args)
510 }
511
512 /**
513 * @see https://core.telegram.org/bots/api#getchatmembercount
514 */
515 getChatMembersCount(
516 this: Context,
517 ...args: Shorthand<'getChatMembersCount'>
518 ) {
519 this.assert(this.chat, 'getChatMembersCount')
520 return this.telegram.getChatMembersCount(this.chat.id, ...args)
521 }
522
523 /**
524 * @see https://core.telegram.org/bots/api#setpassportdataerrors
525 */
526 setPassportDataErrors(
527 this: Context,
528 errors: readonly tg.PassportElementError[]
529 ) {
530 this.assert(this.from, 'setPassportDataErrors')
531 return this.telegram.setPassportDataErrors(this.from.id, errors)
532 }
533
534 /**
535 * @see https://core.telegram.org/bots/api#replywithphoto
536 */
537 replyWithPhoto(this: Context, ...args: Shorthand<'sendPhoto'>) {
538 this.assert(this.chat, 'replyWithPhoto')
539 return this.telegram.sendPhoto(this.chat.id, ...args)
540 }
541
542 /**
543 * @see https://core.telegram.org/bots/api#replywithmediagroup
544 */
545 replyWithMediaGroup(this: Context, ...args: Shorthand<'sendMediaGroup'>) {
546 this.assert(this.chat, 'replyWithMediaGroup')
547 return this.telegram.sendMediaGroup(this.chat.id, ...args)
548 }
549
550 /**
551 * @see https://core.telegram.org/bots/api#replywithaudio
552 */
553 replyWithAudio(this: Context, ...args: Shorthand<'sendAudio'>) {
554 this.assert(this.chat, 'replyWithAudio')
555 return this.telegram.sendAudio(this.chat.id, ...args)
556 }
557
558 /**
559 * @see https://core.telegram.org/bots/api#replywithdice
560 */
561 replyWithDice(this: Context, ...args: Shorthand<'sendDice'>) {
562 this.assert(this.chat, 'replyWithDice')
563 return this.telegram.sendDice(this.chat.id, ...args)
564 }
565
566 /**
567 * @see https://core.telegram.org/bots/api#replywithdocument
568 */
569 replyWithDocument(this: Context, ...args: Shorthand<'sendDocument'>) {
570 this.assert(this.chat, 'replyWithDocument')
571 return this.telegram.sendDocument(this.chat.id, ...args)
572 }
573
574 /**
575 * @see https://core.telegram.org/bots/api#replywithsticker
576 */
577 replyWithSticker(this: Context, ...args: Shorthand<'sendSticker'>) {
578 this.assert(this.chat, 'replyWithSticker')
579 return this.telegram.sendSticker(this.chat.id, ...args)
580 }
581
582 /**
583 * @see https://core.telegram.org/bots/api#replywithvideo
584 */
585 replyWithVideo(this: Context, ...args: Shorthand<'sendVideo'>) {
586 this.assert(this.chat, 'replyWithVideo')
587 return this.telegram.sendVideo(this.chat.id, ...args)
588 }
589
590 /**
591 * @see https://core.telegram.org/bots/api#replywithanimation
592 */
593 replyWithAnimation(this: Context, ...args: Shorthand<'sendAnimation'>) {
594 this.assert(this.chat, 'replyWithAnimation')
595 return this.telegram.sendAnimation(this.chat.id, ...args)
596 }
597
598 /**
599 * @see https://core.telegram.org/bots/api#replywithvideonote
600 */
601 replyWithVideoNote(this: Context, ...args: Shorthand<'sendVideoNote'>) {
602 this.assert(this.chat, 'replyWithVideoNote')
603 return this.telegram.sendVideoNote(this.chat.id, ...args)
604 }
605
606 /**
607 * @see https://core.telegram.org/bots/api#replywithinvoice
608 */
609 replyWithInvoice(this: Context, ...args: Shorthand<'sendInvoice'>) {
610 this.assert(this.chat, 'replyWithInvoice')
611 return this.telegram.sendInvoice(this.chat.id, ...args)
612 }
613
614 /**
615 * @see https://core.telegram.org/bots/api#replywithgame
616 */
617 replyWithGame(this: Context, ...args: Shorthand<'sendGame'>) {
618 this.assert(this.chat, 'replyWithGame')
619 return this.telegram.sendGame(this.chat.id, ...args)
620 }
621
622 /**
623 * @see https://core.telegram.org/bots/api#replywithvoice
624 */
625 replyWithVoice(this: Context, ...args: Shorthand<'sendVoice'>) {
626 this.assert(this.chat, 'replyWithVoice')
627 return this.telegram.sendVoice(this.chat.id, ...args)
628 }
629
630 /**
631 * @see https://core.telegram.org/bots/api#replywithpoll
632 */
633 replyWithPoll(this: Context, ...args: Shorthand<'sendPoll'>) {
634 this.assert(this.chat, 'replyWithPoll')
635 return this.telegram.sendPoll(this.chat.id, ...args)
636 }
637
638 /**
639 * @see https://core.telegram.org/bots/api#replywithquiz
640 */
641 replyWithQuiz(this: Context, ...args: Shorthand<'sendQuiz'>) {
642 this.assert(this.chat, 'replyWithQuiz')
643 return this.telegram.sendQuiz(this.chat.id, ...args)
644 }
645
646 /**
647 * @see https://core.telegram.org/bots/api#stoppoll
648 */
649 stopPoll(this: Context, ...args: Shorthand<'stopPoll'>) {
650 this.assert(this.chat, 'stopPoll')
651 return this.telegram.stopPoll(this.chat.id, ...args)
652 }
653
654 /**
655 * @see https://core.telegram.org/bots/api#replywithchataction
656 */
657 replyWithChatAction(this: Context, ...args: Shorthand<'sendChatAction'>) {
658 this.assert(this.chat, 'replyWithChatAction')
659 return this.telegram.sendChatAction(this.chat.id, ...args)
660 }
661
662 /**
663 * @see https://core.telegram.org/bots/api#replywithlocation
664 */
665 replyWithLocation(this: Context, ...args: Shorthand<'sendLocation'>) {
666 this.assert(this.chat, 'replyWithLocation')
667 return this.telegram.sendLocation(this.chat.id, ...args)
668 }
669
670 /**
671 * @see https://core.telegram.org/bots/api#replywithvenue
672 */
673 replyWithVenue(this: Context, ...args: Shorthand<'sendVenue'>) {
674 this.assert(this.chat, 'replyWithVenue')
675 return this.telegram.sendVenue(this.chat.id, ...args)
676 }
677
678 /**
679 * @see https://core.telegram.org/bots/api#replywithcontact
680 */
681 replyWithContact(this: Context, ...args: Shorthand<'sendContact'>) {
682 this.assert(this.chat, 'replyWithContact')
683 return this.telegram.sendContact(this.chat.id, ...args)
684 }
685
686 /**
687 * @deprecated use {@link Telegram.getStickerSet}
688 * @see https://core.telegram.org/bots/api#getstickerset
689 */
690 getStickerSet(this: Context, setName: string) {
691 return this.telegram.getStickerSet(setName)
692 }
693
694 /**
695 * @see https://core.telegram.org/bots/api#setchatstickerset
696 */
697 setChatStickerSet(this: Context, setName: string) {
698 this.assert(this.chat, 'setChatStickerSet')
699 return this.telegram.setChatStickerSet(this.chat.id, setName)
700 }
701
702 /**
703 * @see https://core.telegram.org/bots/api#deletechatstickerset
704 */
705 deleteChatStickerSet(this: Context) {
706 this.assert(this.chat, 'deleteChatStickerSet')
707 return this.telegram.deleteChatStickerSet(this.chat.id)
708 }
709
710 /**
711 * @deprecated use {@link Telegram.setStickerPositionInSet}
712 * @see https://core.telegram.org/bots/api#setstickerpositioninset
713 */
714 setStickerPositionInSet(this: Context, sticker: string, position: number) {
715 return this.telegram.setStickerPositionInSet(sticker, position)
716 }
717
718 /**
719 * @deprecated use {@link Telegram.setStickerSetThumb}
720 * @see https://core.telegram.org/bots/api#setstickersetthumb
721 */
722 setStickerSetThumb(
723 this: Context,
724 ...args: Parameters<Telegram['setStickerSetThumb']>
725 ) {
726 return this.telegram.setStickerSetThumb(...args)
727 }
728
729 /**
730 * @deprecated use {@link Telegram.deleteStickerFromSet}
731 * @see https://core.telegram.org/bots/api#deletestickerfromset
732 */
733 deleteStickerFromSet(this: Context, sticker: string) {
734 return this.telegram.deleteStickerFromSet(sticker)
735 }
736
737 /**
738 * @see https://core.telegram.org/bots/api#uploadstickerfile
739 */
740 uploadStickerFile(this: Context, ...args: Shorthand<'uploadStickerFile'>) {
741 this.assert(this.from, 'uploadStickerFile')
742 return this.telegram.uploadStickerFile(this.from.id, ...args)
743 }
744
745 /**
746 * @see https://core.telegram.org/bots/api#createnewstickerset
747 */
748 createNewStickerSet(
749 this: Context,
750 ...args: Shorthand<'createNewStickerSet'>
751 ) {
752 this.assert(this.from, 'createNewStickerSet')
753 return this.telegram.createNewStickerSet(this.from.id, ...args)
754 }
755
756 /**
757 * @see https://core.telegram.org/bots/api#addstickertoset
758 */
759 addStickerToSet(this: Context, ...args: Shorthand<'addStickerToSet'>) {
760 this.assert(this.from, 'addStickerToSet')
761 return this.telegram.addStickerToSet(this.from.id, ...args)
762 }
763
764 /**
765 * @deprecated use {@link Telegram.getMyCommands}
766 * @see https://core.telegram.org/bots/api#getmycommands
767 */
768 getMyCommands(this: Context) {
769 return this.telegram.getMyCommands()
770 }
771
772 /**
773 * @deprecated use {@link Telegram.setMyCommands}
774 * @see https://core.telegram.org/bots/api#setmycommands
775 */
776 setMyCommands(this: Context, commands: readonly tg.BotCommand[]) {
777 return this.telegram.setMyCommands(commands)
778 }
779
780 /**
781 * @see https://core.telegram.org/bots/api#sendmessage
782 */
783 replyWithMarkdown(
784 this: Context,
785 markdown: string,
786 extra?: tt.ExtraReplyMessage
787 ) {
788 return this.reply(markdown, { parse_mode: 'Markdown', ...extra })
789 }
790
791 /**
792 * @see https://core.telegram.org/bots/api#sendmessage
793 */
794 replyWithMarkdownV2(
795 this: Context,
796 markdown: string,
797 extra?: tt.ExtraReplyMessage
798 ) {
799 return this.reply(markdown, { parse_mode: 'MarkdownV2', ...extra })
800 }
801
802 /**
803 * @see https://core.telegram.org/bots/api#sendmessage
804 */
805 replyWithHTML(this: Context, html: string, extra?: tt.ExtraReplyMessage) {
806 return this.reply(html, { parse_mode: 'HTML', ...extra })
807 }
808
809 /**
810 * @see https://core.telegram.org/bots/api#deletemessage
811 */
812 deleteMessage(this: Context, messageId?: number) {
813 this.assert(this.chat, 'deleteMessage')
814 if (typeof messageId !== 'undefined') {
815 return this.telegram.deleteMessage(this.chat.id, messageId)
816 }
817 const message = getMessageFromAnySource(this)
818 this.assert(message, 'deleteMessage')
819 return this.telegram.deleteMessage(this.chat.id, message.message_id)
820 }
821
822 /**
823 * @see https://core.telegram.org/bots/api#forwardmessage
824 */
825 forwardMessage(
826 this: Context,
827 chatId: string | number,
828 extra?: {
829 disable_notification?: boolean
830 }
831 ) {
832 const message = getMessageFromAnySource(this)
833 this.assert(message, 'forwardMessage')
834 return this.telegram.forwardMessage(
835 chatId,
836 message.chat.id,
837 message.message_id,
838 extra
839 )
840 }
841
842 /**
843 * @see https://core.telegram.org/bots/api#copymessage
844 */
845 copyMessage(
846 this: Context,
847 chatId: string | number,
848 extra?: tt.ExtraCopyMessage
849 ) {
850 const message = getMessageFromAnySource(this)
851 this.assert(message, 'copyMessage')
852 return this.telegram.copyMessage(
853 chatId,
854 message.chat.id,
855 message.message_id,
856 extra
857 )
858 }
859}
860
861export default Context
862
863type UpdateTypes<U extends Deunionize<tg.Update>> = Extract<
864 UnionKeys<U>,
865 tt.UpdateType
866>
867
868export type GetUpdateContent<
869 U extends tg.Update
870> = U extends tg.Update.CallbackQueryUpdate
871 ? U['callback_query']['message']
872 : U[UpdateTypes<U>]
873
874type Getter<U extends Deunionize<tg.Update>, P extends string> = PropOr<
875 GetUpdateContent<U>,
876 P
877>
878
879function getMessageFromAnySource<U extends tg.Update>(ctx: Context<U>) {
880 return (
881 ctx.message ??
882 ctx.editedMessage ??
883 ctx.callbackQuery?.message ??
884 ctx.channelPost ??
885 ctx.editedChannelPost
886 )
887}