import * as tg from './core/types/typegram' import * as tt from './telegram-types' import { Deunionize, PropOr, UnionKeys } from './deunionize' import ApiClient from './core/network/client' import { deprecate } from './util' import Telegram from './telegram' type Tail = T extends [unknown, ...infer U] ? U : never type Shorthand> = Tail< Parameters > export class Context = tg.Update> { // eslint-disable-next-line @typescript-eslint/no-explicit-any readonly state: Record = {} constructor( readonly update: U, readonly telegram: Telegram, readonly botInfo: tg.UserFromGetMe ) {} get updateType() { for (const key in this.update) { if (typeof this.update[key] === 'object') return key as UpdateTypes } throw new Error( `Cannot determine \`updateType\` of ${JSON.stringify(this.update)}` ) } get me() { return this.botInfo?.username } /** * @deprecated Use ctx.telegram instead */ get tg() { return this.telegram } get message() { return this.update.message as PropOr } get editedMessage() { return this.update.edited_message as PropOr } get inlineQuery() { return this.update.inline_query as PropOr } get shippingQuery() { return this.update.shipping_query as PropOr } get preCheckoutQuery() { return this.update.pre_checkout_query as PropOr } get chosenInlineResult() { return this.update.chosen_inline_result as PropOr } get channelPost() { return this.update.channel_post as PropOr } get editedChannelPost() { return this.update.edited_channel_post as PropOr } get callbackQuery() { return this.update.callback_query as PropOr } get poll() { return this.update.poll as PropOr } get pollAnswer() { return this.update.poll_answer as PropOr } get myChatMember() { return this.update.my_chat_member as PropOr } get chatMember() { return this.update.chat_member as PropOr } get chatJoinRequest() { return this.update.chat_join_request } get chat(): Getter { return ( this.chatMember ?? this.myChatMember ?? this.chatJoinRequest ?? getMessageFromAnySource(this) )?.chat as Getter } get senderChat() { return getMessageFromAnySource(this)?.sender_chat as Getter< U, 'sender_chat' > } get from() { return ( this.callbackQuery ?? this.inlineQuery ?? this.shippingQuery ?? this.preCheckoutQuery ?? this.chosenInlineResult ?? this.chatMember ?? this.myChatMember ?? this.chatJoinRequest ?? getMessageFromAnySource(this) )?.from as Getter } get inlineMessageId() { return (this.callbackQuery ?? this.chosenInlineResult)?.inline_message_id } get passportData() { if (this.message == null) return undefined if (!('passport_data' in this.message)) return undefined return this.message?.passport_data } get webAppData() { if ( !( 'message' in this.update && this.update.message && 'web_app_data' in this.update.message ) ) return undefined const { data, button_text } = this.update.message.web_app_data return { data: { json() { return JSON.parse(data) as T }, text() { return data }, }, button_text, } } /** * @deprecated use {@link Telegram.webhookReply} */ get webhookReply(): boolean { return this.telegram.webhookReply } set webhookReply(enable: boolean) { this.telegram.webhookReply = enable } /** * @internal */ assert( value: T | undefined, method: string ): asserts value is T { if (value === undefined) { throw new TypeError( `Telegraf: "${method}" isn't available for "${this.updateType}"` ) } } /** * @see https://core.telegram.org/bots/api#answerinlinequery */ answerInlineQuery(this: Context, ...args: Shorthand<'answerInlineQuery'>) { this.assert(this.inlineQuery, 'answerInlineQuery') return this.telegram.answerInlineQuery(this.inlineQuery.id, ...args) } /** * @see https://core.telegram.org/bots/api#answercallbackquery */ answerCbQuery(this: Context, ...args: Shorthand<'answerCbQuery'>) { this.assert(this.callbackQuery, 'answerCbQuery') return this.telegram.answerCbQuery(this.callbackQuery.id, ...args) } /** * @see https://core.telegram.org/bots/api#answercallbackquery */ answerGameQuery(this: Context, ...args: Shorthand<'answerGameQuery'>) { this.assert(this.callbackQuery, 'answerGameQuery') return this.telegram.answerGameQuery(this.callbackQuery.id, ...args) } /** * @see https://core.telegram.org/bots/api#answershippingquery */ answerShippingQuery( this: Context, ...args: Shorthand<'answerShippingQuery'> ) { this.assert(this.shippingQuery, 'answerShippingQuery') return this.telegram.answerShippingQuery(this.shippingQuery.id, ...args) } /** * @see https://core.telegram.org/bots/api#answerprecheckoutquery */ answerPreCheckoutQuery( this: Context, ...args: Shorthand<'answerPreCheckoutQuery'> ) { this.assert(this.preCheckoutQuery, 'answerPreCheckoutQuery') return this.telegram.answerPreCheckoutQuery( this.preCheckoutQuery.id, ...args ) } /** * @see https://core.telegram.org/bots/api#editmessagetext */ editMessageText( this: Context, text: string, extra?: tt.ExtraEditMessageText ) { this.assert(this.callbackQuery ?? this.inlineMessageId, 'editMessageText') return this.telegram.editMessageText( this.chat?.id, this.callbackQuery?.message?.message_id, this.inlineMessageId, text, extra ) } /** * @see https://core.telegram.org/bots/api#editmessagecaption */ editMessageCaption( this: Context, caption: string | undefined, extra?: tt.ExtraEditMessageCaption ) { this.assert( this.callbackQuery ?? this.inlineMessageId, 'editMessageCaption' ) return this.telegram.editMessageCaption( this.chat?.id, this.callbackQuery?.message?.message_id, this.inlineMessageId, caption, extra ) } /** * @see https://core.telegram.org/bots/api#editmessagemedia */ editMessageMedia( this: Context, media: tg.InputMedia, extra?: tt.ExtraEditMessageMedia ) { this.assert(this.callbackQuery ?? this.inlineMessageId, 'editMessageMedia') return this.telegram.editMessageMedia( this.chat?.id, this.callbackQuery?.message?.message_id, this.inlineMessageId, media, extra ) } /** * @see https://core.telegram.org/bots/api#editmessagereplymarkup */ editMessageReplyMarkup( this: Context, markup: tg.InlineKeyboardMarkup | undefined ) { this.assert( this.callbackQuery ?? this.inlineMessageId, 'editMessageReplyMarkup' ) return this.telegram.editMessageReplyMarkup( this.chat?.id, this.callbackQuery?.message?.message_id, this.inlineMessageId, markup ) } /** * @see https://core.telegram.org/bots/api#editmessagelivelocation */ editMessageLiveLocation( this: Context, latitude: number, longitude: number, extra?: tt.ExtraEditMessageLiveLocation ) { this.assert( this.callbackQuery ?? this.inlineMessageId, 'editMessageLiveLocation' ) return this.telegram.editMessageLiveLocation( this.chat?.id, this.callbackQuery?.message?.message_id, this.inlineMessageId, latitude, longitude, extra ) } /** * @see https://core.telegram.org/bots/api#stopmessagelivelocation */ stopMessageLiveLocation(this: Context, markup?: tg.InlineKeyboardMarkup) { this.assert( this.callbackQuery ?? this.inlineMessageId, 'stopMessageLiveLocation' ) return this.telegram.stopMessageLiveLocation( this.chat?.id, this.callbackQuery?.message?.message_id, this.inlineMessageId, markup ) } /** * @see https://core.telegram.org/bots/api#sendmessage */ sendMessage(this: Context, ...args: Shorthand<'sendMessage'>) { this.assert(this.chat, 'sendMessage') return this.telegram.sendMessage(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#sendmessage */ reply(this: Context, ...args: Shorthand<'sendMessage'>) { deprecate( 'ctx.reply', 'reply', 'sendMessage', 'https://telegraf.js.org/experimental#new-reply' ) return this.sendMessage(...args) } /** * @see https://core.telegram.org/bots/api#getchat */ getChat(this: Context, ...args: Shorthand<'getChat'>) { this.assert(this.chat, 'getChat') return this.telegram.getChat(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#exportchatinvitelink */ exportChatInviteLink( this: Context, ...args: Shorthand<'exportChatInviteLink'> ) { this.assert(this.chat, 'exportChatInviteLink') return this.telegram.exportChatInviteLink(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#createchatinvitelink */ createChatInviteLink( this: Context, ...args: Shorthand<'createChatInviteLink'> ) { this.assert(this.chat, 'createChatInviteLink') return this.telegram.createChatInviteLink(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#editchatinvitelink */ editChatInviteLink(this: Context, ...args: Shorthand<'editChatInviteLink'>) { this.assert(this.chat, 'editChatInviteLink') return this.telegram.editChatInviteLink(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#revokechatinvitelink */ revokeChatInviteLink( this: Context, ...args: Shorthand<'revokeChatInviteLink'> ) { this.assert(this.chat, 'revokeChatInviteLink') return this.telegram.revokeChatInviteLink(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#banchatmember */ banChatMember(this: Context, ...args: Shorthand<'banChatMember'>) { this.assert(this.chat, 'banChatMember') return this.telegram.banChatMember(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#banchatmember * @deprecated since API 5.3. Use {@link Context.banChatMember} */ get kickChatMember() { return this.banChatMember } /** * @see https://core.telegram.org/bots/api#unbanchatmember */ unbanChatMember(this: Context, ...args: Shorthand<'unbanChatMember'>) { this.assert(this.chat, 'unbanChatMember') return this.telegram.unbanChatMember(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#restrictchatmember */ restrictChatMember(this: Context, ...args: Shorthand<'restrictChatMember'>) { this.assert(this.chat, 'restrictChatMember') return this.telegram.restrictChatMember(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#promotechatmember */ promoteChatMember(this: Context, ...args: Shorthand<'promoteChatMember'>) { this.assert(this.chat, 'promoteChatMember') return this.telegram.promoteChatMember(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#setchatadministratorcustomtitle */ setChatAdministratorCustomTitle( this: Context, ...args: Shorthand<'setChatAdministratorCustomTitle'> ) { this.assert(this.chat, 'setChatAdministratorCustomTitle') return this.telegram.setChatAdministratorCustomTitle(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#setchatphoto */ setChatPhoto(this: Context, ...args: Shorthand<'setChatPhoto'>) { this.assert(this.chat, 'setChatPhoto') return this.telegram.setChatPhoto(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#deletechatphoto */ deleteChatPhoto(this: Context, ...args: Shorthand<'deleteChatPhoto'>) { this.assert(this.chat, 'deleteChatPhoto') return this.telegram.deleteChatPhoto(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#setchattitle */ setChatTitle(this: Context, ...args: Shorthand<'setChatTitle'>) { this.assert(this.chat, 'setChatTitle') return this.telegram.setChatTitle(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#setchatdescription */ setChatDescription(this: Context, ...args: Shorthand<'setChatDescription'>) { this.assert(this.chat, 'setChatDescription') return this.telegram.setChatDescription(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#pinchatmessage */ pinChatMessage(this: Context, ...args: Shorthand<'pinChatMessage'>) { this.assert(this.chat, 'pinChatMessage') return this.telegram.pinChatMessage(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#unpinchatmessage */ unpinChatMessage(this: Context, ...args: Shorthand<'unpinChatMessage'>) { this.assert(this.chat, 'unpinChatMessage') return this.telegram.unpinChatMessage(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#unpinallchatmessages */ unpinAllChatMessages( this: Context, ...args: Shorthand<'unpinAllChatMessages'> ) { this.assert(this.chat, 'unpinAllChatMessages') return this.telegram.unpinAllChatMessages(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#leavechat */ leaveChat(this: Context, ...args: Shorthand<'leaveChat'>) { this.assert(this.chat, 'leaveChat') return this.telegram.leaveChat(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#setchatpermissions */ setChatPermissions(this: Context, ...args: Shorthand<'setChatPermissions'>) { this.assert(this.chat, 'setChatPermissions') return this.telegram.setChatPermissions(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#getchatadministrators */ getChatAdministrators( this: Context, ...args: Shorthand<'getChatAdministrators'> ) { this.assert(this.chat, 'getChatAdministrators') return this.telegram.getChatAdministrators(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#getchatmember */ getChatMember(this: Context, ...args: Shorthand<'getChatMember'>) { this.assert(this.chat, 'getChatMember') return this.telegram.getChatMember(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#getchatmembercount */ getChatMembersCount( this: Context, ...args: Shorthand<'getChatMembersCount'> ) { this.assert(this.chat, 'getChatMembersCount') return this.telegram.getChatMembersCount(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#setpassportdataerrors */ setPassportDataErrors( this: Context, errors: readonly tg.PassportElementError[] ) { this.assert(this.from, 'setPassportDataErrors') return this.telegram.setPassportDataErrors(this.from.id, errors) } /** * @see https://core.telegram.org/bots/api#sendphoto */ sendPhoto(this: Context, ...args: Shorthand<'sendPhoto'>) { this.assert(this.chat, 'sendPhoto') return this.telegram.sendPhoto(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#sendphoto */ replyWithPhoto(this: Context, ...args: Shorthand<'sendPhoto'>) { deprecate( 'ctx.replyWithPhoto', 'reply', 'sendPhoto', 'https://telegraf.js.org/experimental#new-reply' ) return this.sendPhoto(...args) } /** * @see https://core.telegram.org/bots/api#sendmediagroup */ sendMediaGroup(this: Context, ...args: Shorthand<'sendMediaGroup'>) { this.assert(this.chat, 'sendMediaGroup') return this.telegram.sendMediaGroup(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#sendmediagroup */ replyWithMediaGroup(this: Context, ...args: Shorthand<'sendMediaGroup'>) { deprecate( 'ctx.replyWithMediaGroup', 'reply', 'sendMediaGroup', 'https://telegraf.js.org/experimental#new-reply' ) return this.sendMediaGroup(...args) } /** * @see https://core.telegram.org/bots/api#sendaudio */ sendAudio(this: Context, ...args: Shorthand<'sendAudio'>) { this.assert(this.chat, 'sendAudio') return this.telegram.sendAudio(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#sendaudio */ replyWithAudio(this: Context, ...args: Shorthand<'sendAudio'>) { deprecate( 'ctx.replyWithAudio', 'reply', 'sendAudio', 'https://telegraf.js.org/experimental#new-reply' ) return this.sendAudio(...args) } /** * @see https://core.telegram.org/bots/api#senddice */ sendDice(this: Context, ...args: Shorthand<'sendDice'>) { this.assert(this.chat, 'sendDice') return this.telegram.sendDice(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#senddice */ replyWithDice(this: Context, ...args: Shorthand<'sendDice'>) { deprecate( 'ctx.replyWithDice', 'reply', 'sendDice', 'https://telegraf.js.org/experimental#new-reply' ) return this.sendDice(...args) } /** * @see https://core.telegram.org/bots/api#senddocument */ sendDocument(this: Context, ...args: Shorthand<'sendDocument'>) { this.assert(this.chat, 'sendDocument') return this.telegram.sendDocument(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#senddocument */ replyWithDocument(this: Context, ...args: Shorthand<'sendDocument'>) { deprecate( 'ctx.replyWithDocument', 'reply', 'sendDocument', 'https://telegraf.js.org/experimental#new-reply' ) return this.sendDocument(...args) } /** * @see https://core.telegram.org/bots/api#sendsticker */ sendSticker(this: Context, ...args: Shorthand<'sendSticker'>) { this.assert(this.chat, 'sendSticker') return this.telegram.sendSticker(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#sendsticker */ replyWithSticker(this: Context, ...args: Shorthand<'sendSticker'>) { deprecate( 'ctx.replyWithSticker', 'reply', 'sendSticker', 'https://telegraf.js.org/experimental#new-reply' ) return this.sendSticker(...args) } /** * @see https://core.telegram.org/bots/api#sendvideo */ sendVideo(this: Context, ...args: Shorthand<'sendVideo'>) { this.assert(this.chat, 'sendVideo') return this.telegram.sendVideo(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#sendvideo */ replyWithVideo(this: Context, ...args: Shorthand<'sendVideo'>) { deprecate( 'ctx.replyWithVideo', 'reply', 'sendVideo', 'https://telegraf.js.org/experimental#new-reply' ) return this.sendVideo(...args) } /** * @see https://core.telegram.org/bots/api#sendanimation */ sendAnimation(this: Context, ...args: Shorthand<'sendAnimation'>) { this.assert(this.chat, 'sendAnimation') return this.telegram.sendAnimation(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#sendanimation */ replyWithAnimation(this: Context, ...args: Shorthand<'sendAnimation'>) { deprecate( 'ctx.replyWithAnimation', 'reply', 'sendAnimation', 'https://telegraf.js.org/experimental#new-reply' ) return this.sendAnimation(...args) } /** * @see https://core.telegram.org/bots/api#sendvideonote */ sendVideoNote(this: Context, ...args: Shorthand<'sendVideoNote'>) { this.assert(this.chat, 'sendVideoNote') return this.telegram.sendVideoNote(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#sendvideonote */ replyWithVideoNote(this: Context, ...args: Shorthand<'sendVideoNote'>) { deprecate( 'ctx.replyWithVideoNote', 'reply', 'sendVideoNote', 'https://telegraf.js.org/experimental#new-reply' ) return this.sendVideoNote(...args) } /** * @see https://core.telegram.org/bots/api#sendinvoice */ sendInvoice(this: Context, ...args: Shorthand<'sendInvoice'>) { this.assert(this.chat, 'sendInvoice') return this.telegram.sendInvoice(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#sendinvoice */ replyWithInvoice(this: Context, ...args: Shorthand<'sendInvoice'>) { deprecate( 'ctx.replyWithInvoice', 'reply', 'sendInvoice', 'https://telegraf.js.org/experimental#new-reply' ) return this.sendInvoice(...args) } /** * @see https://core.telegram.org/bots/api#sendgame */ sendGame(this: Context, ...args: Shorthand<'sendGame'>) { this.assert(this.chat, 'sendGame') return this.telegram.sendGame(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#sendgame */ replyWithGame(this: Context, ...args: Shorthand<'sendGame'>) { deprecate( 'ctx.replyWithGame', 'reply', 'sendGame', 'https://telegraf.js.org/experimental#new-reply' ) return this.sendGame(...args) } /** * @see https://core.telegram.org/bots/api#sendvoice */ sendVoice(this: Context, ...args: Shorthand<'sendVoice'>) { this.assert(this.chat, 'sendVoice') return this.telegram.sendVoice(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#sendvoice */ replyWithVoice(this: Context, ...args: Shorthand<'sendVoice'>) { deprecate( 'ctx.replyWithVoice', 'reply', 'sendVoice', 'https://telegraf.js.org/experimental#new-reply' ) return this.sendVoice(...args) } /** * @see https://core.telegram.org/bots/api#sendpoll */ sendPoll(this: Context, ...args: Shorthand<'sendPoll'>) { this.assert(this.chat, 'sendPoll') return this.telegram.sendPoll(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#sendpoll */ replyWithPoll(this: Context, ...args: Shorthand<'sendPoll'>) { deprecate( 'ctx.replyWithPoll', 'reply', 'sendPoll', 'https://telegraf.js.org/experimental#new-reply' ) return this.sendPoll(...args) } /** * @see https://core.telegram.org/bots/api#sendquiz */ sendQuiz(this: Context, ...args: Shorthand<'sendQuiz'>) { this.assert(this.chat, 'sendQuiz') return this.telegram.sendQuiz(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#sendquiz */ replyWithQuiz(this: Context, ...args: Shorthand<'sendQuiz'>) { deprecate( 'ctx.replyWithQuiz', 'reply', 'sendQuiz', 'https://telegraf.js.org/experimental#new-reply' ) return this.sendQuiz(...args) } /** * @see https://core.telegram.org/bots/api#stoppoll */ stopPoll(this: Context, ...args: Shorthand<'stopPoll'>) { this.assert(this.chat, 'stopPoll') return this.telegram.stopPoll(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#sendchataction */ sendChatAction(this: Context, ...args: Shorthand<'sendChatAction'>) { this.assert(this.chat, 'sendChatAction') return this.telegram.sendChatAction(this.chat.id, ...args) } /** * @deprecated use {@link Context.sendChatAction} instead * @see https://core.telegram.org/bots/api#sendchataction */ replyWithChatAction(this: Context, ...args: Shorthand<'sendChatAction'>) { deprecate('ctx.replyWithChatAction', 'reply', 'sendChatAction') return this.sendChatAction(...args) } /** * @see https://core.telegram.org/bots/api#sendlocation */ sendLocation(this: Context, ...args: Shorthand<'sendLocation'>) { this.assert(this.chat, 'sendLocation') return this.telegram.sendLocation(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#sendlocation */ replyWithLocation(this: Context, ...args: Shorthand<'sendLocation'>) { deprecate( 'ctx.replyWithLocation', 'reply', 'sendLocation', 'https://telegraf.js.org/experimental#new-reply' ) return this.sendLocation(...args) } /** * @see https://core.telegram.org/bots/api#sendvenue */ sendVenue(this: Context, ...args: Shorthand<'sendVenue'>) { this.assert(this.chat, 'sendVenue') return this.telegram.sendVenue(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#sendvenue */ replyWithVenue(this: Context, ...args: Shorthand<'sendVenue'>) { deprecate( 'ctx.replyWithVenue', 'reply', 'sendVenue', 'https://telegraf.js.org/experimental#new-reply' ) return this.sendVenue(...args) } /** * @see https://core.telegram.org/bots/api#sendcontact */ sendContact(this: Context, ...args: Shorthand<'sendContact'>) { this.assert(this.chat, 'sendContact') return this.telegram.sendContact(this.chat.id, ...args) } /** * @see https://core.telegram.org/bots/api#sendcontact */ replyWithContact(this: Context, ...args: Shorthand<'sendContact'>) { deprecate( 'ctx.replyWithContact', 'reply', 'sendContact', 'https://telegraf.js.org/experimental#new-reply' ) return this.sendContact(...args) } /** * @deprecated use {@link Telegram.getStickerSet} * @see https://core.telegram.org/bots/api#getstickerset */ getStickerSet(this: Context, setName: string) { return this.telegram.getStickerSet(setName) } /** * @see https://core.telegram.org/bots/api#setchatstickerset */ setChatStickerSet(this: Context, setName: string) { this.assert(this.chat, 'setChatStickerSet') return this.telegram.setChatStickerSet(this.chat.id, setName) } /** * @see https://core.telegram.org/bots/api#deletechatstickerset */ deleteChatStickerSet(this: Context) { this.assert(this.chat, 'deleteChatStickerSet') return this.telegram.deleteChatStickerSet(this.chat.id) } /** * @deprecated use {@link Telegram.setStickerPositionInSet} * @see https://core.telegram.org/bots/api#setstickerpositioninset */ setStickerPositionInSet(this: Context, sticker: string, position: number) { return this.telegram.setStickerPositionInSet(sticker, position) } /** * @deprecated use {@link Telegram.setStickerSetThumb} * @see https://core.telegram.org/bots/api#setstickersetthumb */ setStickerSetThumb( this: Context, ...args: Parameters ) { return this.telegram.setStickerSetThumb(...args) } /** * @deprecated use {@link Telegram.deleteStickerFromSet} * @see https://core.telegram.org/bots/api#deletestickerfromset */ deleteStickerFromSet(this: Context, sticker: string) { return this.telegram.deleteStickerFromSet(sticker) } /** * @see https://core.telegram.org/bots/api#uploadstickerfile */ uploadStickerFile(this: Context, ...args: Shorthand<'uploadStickerFile'>) { this.assert(this.from, 'uploadStickerFile') return this.telegram.uploadStickerFile(this.from.id, ...args) } /** * @see https://core.telegram.org/bots/api#createnewstickerset */ createNewStickerSet( this: Context, ...args: Shorthand<'createNewStickerSet'> ) { this.assert(this.from, 'createNewStickerSet') return this.telegram.createNewStickerSet(this.from.id, ...args) } /** * @see https://core.telegram.org/bots/api#addstickertoset */ addStickerToSet(this: Context, ...args: Shorthand<'addStickerToSet'>) { this.assert(this.from, 'addStickerToSet') return this.telegram.addStickerToSet(this.from.id, ...args) } /** * @deprecated use {@link Telegram.getMyCommands} * @see https://core.telegram.org/bots/api#getmycommands */ getMyCommands(this: Context) { return this.telegram.getMyCommands() } /** * @deprecated use {@link Telegram.setMyCommands} * @see https://core.telegram.org/bots/api#setmycommands */ setMyCommands(this: Context, commands: readonly tg.BotCommand[]) { return this.telegram.setMyCommands(commands) } /** * @deprecated use {@link Context.replyWithMarkdownV2} * @see https://core.telegram.org/bots/api#sendmessage */ replyWithMarkdown( this: Context, markdown: string, extra?: tt.ExtraReplyMessage ) { return this.reply(markdown, { parse_mode: 'Markdown', ...extra }) } /** * @see https://core.telegram.org/bots/api#sendmessage */ replyWithMarkdownV2( this: Context, markdown: string, extra?: tt.ExtraReplyMessage ) { return this.reply(markdown, { parse_mode: 'MarkdownV2', ...extra }) } /** * @see https://core.telegram.org/bots/api#sendmessage */ replyWithHTML(this: Context, html: string, extra?: tt.ExtraReplyMessage) { return this.reply(html, { parse_mode: 'HTML', ...extra }) } /** * @see https://core.telegram.org/bots/api#deletemessage */ deleteMessage(this: Context, messageId?: number) { this.assert(this.chat, 'deleteMessage') if (typeof messageId !== 'undefined') { return this.telegram.deleteMessage(this.chat.id, messageId) } const message = getMessageFromAnySource(this) this.assert(message, 'deleteMessage') return this.telegram.deleteMessage(this.chat.id, message.message_id) } /** * @see https://core.telegram.org/bots/api#forwardmessage */ forwardMessage( this: Context, chatId: string | number, extra?: { disable_notification?: boolean } ) { const message = getMessageFromAnySource(this) this.assert(message, 'forwardMessage') return this.telegram.forwardMessage( chatId, message.chat.id, message.message_id, extra ) } /** * @see https://core.telegram.org/bots/api#copymessage */ copyMessage( this: Context, chatId: string | number, extra?: tt.ExtraCopyMessage ) { const message = getMessageFromAnySource(this) this.assert(message, 'copyMessage') return this.telegram.copyMessage( chatId, message.chat.id, message.message_id, extra ) } /** * @see https://core.telegram.org/bots/api#approvechatjoinrequest */ approveChatJoinRequest(this: Context, userId: number) { this.assert(this.chat, 'approveChatJoinRequest') return this.telegram.approveChatJoinRequest(this.chat.id, userId) } /** * @see https://core.telegram.org/bots/api#declinechatjoinrequest */ declineChatJoinRequest(this: Context, userId: number) { this.assert(this.chat, 'declineChatJoinRequest') return this.telegram.declineChatJoinRequest(this.chat.id, userId) } /** * @see https://core.telegram.org/bots/api#banchatsenderchat */ banChatSenderChat(this: Context, senderChatId: number) { this.assert(this.chat, 'banChatSenderChat') return this.telegram.banChatSenderChat(this.chat.id, senderChatId) } /** * @see https://core.telegram.org/bots/api#unbanchatsenderchat */ unbanChatSenderChat(this: Context, senderChatId: number) { this.assert(this.chat, 'unbanChatSenderChat') return this.telegram.unbanChatSenderChat(this.chat.id, senderChatId) } /** * Use this method to change the bot's menu button in the current private chat. Returns true on success. * @see https://core.telegram.org/bots/api#setchatmenubutton */ setChatMenuButton(this: Context, menuButton?: tg.MenuButton) { this.assert(this.chat, 'setChatMenuButton') return this.telegram.setChatMenuButton({ chatId: this.chat.id, menuButton }) } /** * Use this method to get the current value of the bot's menu button in the current private chat. Returns MenuButton on success. * @see https://core.telegram.org/bots/api#getchatmenubutton */ getChatMenuButton() { this.assert(this.chat, 'getChatMenuButton') return this.telegram.getChatMenuButton({ chatId: this.chat.id }) } /** * @see https://core.telegram.org/bots/api#setmydefaultadministratorrights */ setMyDefaultAdministratorRights( extra?: Parameters[0] ) { return this.telegram.setMyDefaultAdministratorRights(extra) } /** * @see https://core.telegram.org/bots/api#getmydefaultadministratorrights */ getMyDefaultAdministratorRights( extra?: Parameters[0] ) { return this.telegram.getMyDefaultAdministratorRights(extra) } } export default Context type UpdateTypes> = Extract< UnionKeys, tt.UpdateType > export type GetUpdateContent = U extends tg.Update.CallbackQueryUpdate ? U['callback_query']['message'] : U[UpdateTypes] type Getter, P extends string> = PropOr< GetUpdateContent, P > function getMessageFromAnySource(ctx: Context) { return ( ctx.message ?? ctx.editedMessage ?? ctx.callbackQuery?.message ?? ctx.channelPost ?? ctx.editedChannelPost ) }