telegraf
Version:
Modern Telegram Bot Framework
888 lines (783 loc) • 24.7 kB
text/typescript
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 Telegram from './telegram'
type Tail<T> = T extends [unknown, ...infer U] ? U : never
type Shorthand<FName extends Exclude<keyof Telegram, keyof ApiClient>> = Tail<
Parameters<Telegram[FName]>
>
export class Context<U extends Deunionize<tg.Update> = tg.Update> {
readonly state: Record<string | symbol, any> = {}
constructor(
readonly update: U,
readonly tg: Telegram,
readonly botInfo: tg.UserFromGetMe
) {}
get updateType() {
const types = Object.keys(this.update).filter(
(k) => typeof this.update[k as keyof U] === 'object'
)
if (types.length !== 1) {
throw new Error(
`Cannot determine \`updateType\` of ${JSON.stringify(this.update)}`
)
}
return types[0] as UpdateTypes<U>
}
get me() {
return this.botInfo?.username
}
get telegram() {
return this.tg
}
get message() {
return this.update.message as PropOr<U, 'message'>
}
get editedMessage() {
return this.update.edited_message as PropOr<U, 'edited_message'>
}
get inlineQuery() {
return this.update.inline_query as PropOr<U, 'inline_query'>
}
get shippingQuery() {
return this.update.shipping_query as PropOr<U, 'shipping_query'>
}
get preCheckoutQuery() {
return this.update.pre_checkout_query as PropOr<U, 'pre_checkout_query'>
}
get chosenInlineResult() {
return this.update.chosen_inline_result as PropOr<U, 'chosen_inline_result'>
}
get channelPost() {
return this.update.channel_post as PropOr<U, 'channel_post'>
}
get editedChannelPost() {
return this.update.edited_channel_post as PropOr<U, 'edited_channel_post'>
}
get callbackQuery() {
return this.update.callback_query as PropOr<U, 'callback_query'>
}
get poll() {
return this.update.poll as PropOr<U, 'poll'>
}
get pollAnswer() {
return this.update.poll_answer as PropOr<U, 'poll_answer'>
}
get myChatMember() {
return this.update.my_chat_member as PropOr<U, 'my_chat_member'>
}
get chatMember() {
return this.update.chat_member as PropOr<U, 'chat_member'>
}
get chat(): Getter<U, 'chat'> {
return (
this.chatMember ??
this.myChatMember ??
getMessageFromAnySource(this)
)?.chat as Getter<U, 'chat'>
}
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 ??
getMessageFromAnySource(this)
)?.from as Getter<U, 'from'>
}
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
}
/**
* @deprecated use {@link Telegram.webhookReply}
*/
get webhookReply(): boolean {
return this.tg.webhookReply
}
set webhookReply(enable: boolean) {
this.tg.webhookReply = enable
}
private assert<T extends string | object>(
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
*/
reply(this: Context, ...args: Shorthand<'sendMessage'>) {
this.assert(this.chat, 'reply')
return this.telegram.sendMessage(this.chat.id, ...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
*/
kickChatMember(this: Context, ...args: Shorthand<'kickChatMember'>) {
this.assert(this.chat, 'kickChatMember')
return this.telegram.kickChatMember(this.chat.id, ...args)
}
/**
* @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#replywithphoto
*/
replyWithPhoto(this: Context, ...args: Shorthand<'sendPhoto'>) {
this.assert(this.chat, 'replyWithPhoto')
return this.telegram.sendPhoto(this.chat.id, ...args)
}
/**
* @see https://core.telegram.org/bots/api#replywithmediagroup
*/
replyWithMediaGroup(this: Context, ...args: Shorthand<'sendMediaGroup'>) {
this.assert(this.chat, 'replyWithMediaGroup')
return this.telegram.sendMediaGroup(this.chat.id, ...args)
}
/**
* @see https://core.telegram.org/bots/api#replywithaudio
*/
replyWithAudio(this: Context, ...args: Shorthand<'sendAudio'>) {
this.assert(this.chat, 'replyWithAudio')
return this.telegram.sendAudio(this.chat.id, ...args)
}
/**
* @see https://core.telegram.org/bots/api#replywithdice
*/
replyWithDice(this: Context, ...args: Shorthand<'sendDice'>) {
this.assert(this.chat, 'replyWithDice')
return this.telegram.sendDice(this.chat.id, ...args)
}
/**
* @see https://core.telegram.org/bots/api#replywithdocument
*/
replyWithDocument(this: Context, ...args: Shorthand<'sendDocument'>) {
this.assert(this.chat, 'replyWithDocument')
return this.telegram.sendDocument(this.chat.id, ...args)
}
/**
* @see https://core.telegram.org/bots/api#replywithsticker
*/
replyWithSticker(this: Context, ...args: Shorthand<'sendSticker'>) {
this.assert(this.chat, 'replyWithSticker')
return this.telegram.sendSticker(this.chat.id, ...args)
}
/**
* @see https://core.telegram.org/bots/api#replywithvideo
*/
replyWithVideo(this: Context, ...args: Shorthand<'sendVideo'>) {
this.assert(this.chat, 'replyWithVideo')
return this.telegram.sendVideo(this.chat.id, ...args)
}
/**
* @see https://core.telegram.org/bots/api#replywithanimation
*/
replyWithAnimation(this: Context, ...args: Shorthand<'sendAnimation'>) {
this.assert(this.chat, 'replyWithAnimation')
return this.telegram.sendAnimation(this.chat.id, ...args)
}
/**
* @see https://core.telegram.org/bots/api#replywithvideonote
*/
replyWithVideoNote(this: Context, ...args: Shorthand<'sendVideoNote'>) {
this.assert(this.chat, 'replyWithVideoNote')
return this.telegram.sendVideoNote(this.chat.id, ...args)
}
/**
* @see https://core.telegram.org/bots/api#replywithinvoice
*/
replyWithInvoice(this: Context, ...args: Shorthand<'sendInvoice'>) {
this.assert(this.chat, 'replyWithInvoice')
return this.telegram.sendInvoice(this.chat.id, ...args)
}
/**
* @see https://core.telegram.org/bots/api#replywithgame
*/
replyWithGame(this: Context, ...args: Shorthand<'sendGame'>) {
this.assert(this.chat, 'replyWithGame')
return this.telegram.sendGame(this.chat.id, ...args)
}
/**
* @see https://core.telegram.org/bots/api#replywithvoice
*/
replyWithVoice(this: Context, ...args: Shorthand<'sendVoice'>) {
this.assert(this.chat, 'replyWithVoice')
return this.telegram.sendVoice(this.chat.id, ...args)
}
/**
* @see https://core.telegram.org/bots/api#replywithpoll
*/
replyWithPoll(this: Context, ...args: Shorthand<'sendPoll'>) {
this.assert(this.chat, 'replyWithPoll')
return this.telegram.sendPoll(this.chat.id, ...args)
}
/**
* @see https://core.telegram.org/bots/api#replywithquiz
*/
replyWithQuiz(this: Context, ...args: Shorthand<'sendQuiz'>) {
this.assert(this.chat, 'replyWithQuiz')
return this.telegram.sendQuiz(this.chat.id, ...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#replywithchataction
*/
replyWithChatAction(this: Context, ...args: Shorthand<'sendChatAction'>) {
this.assert(this.chat, 'replyWithChatAction')
return this.telegram.sendChatAction(this.chat.id, ...args)
}
/**
* @see https://core.telegram.org/bots/api#replywithlocation
*/
replyWithLocation(this: Context, ...args: Shorthand<'sendLocation'>) {
this.assert(this.chat, 'replyWithLocation')
return this.telegram.sendLocation(this.chat.id, ...args)
}
/**
* @see https://core.telegram.org/bots/api#replywithvenue
*/
replyWithVenue(this: Context, ...args: Shorthand<'sendVenue'>) {
this.assert(this.chat, 'replyWithVenue')
return this.telegram.sendVenue(this.chat.id, ...args)
}
/**
* @see https://core.telegram.org/bots/api#replywithcontact
*/
replyWithContact(this: Context, ...args: Shorthand<'sendContact'>) {
this.assert(this.chat, 'replyWithContact')
return this.telegram.sendContact(this.chat.id, ...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<Telegram['setStickerSetThumb']>
) {
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)
}
/**
* @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
)
}
}
export default Context
type UpdateTypes<U extends Deunionize<tg.Update>> = Extract<
UnionKeys<U>,
tt.UpdateType
>
export type GetUpdateContent<
U extends tg.Update
> = U extends tg.Update.CallbackQueryUpdate
? U['callback_query']['message']
: U[UpdateTypes<U>]
type Getter<U extends Deunionize<tg.Update>, P extends string> = PropOr<
GetUpdateContent<U>,
P
>
function getMessageFromAnySource<U extends tg.Update>(ctx: Context<U>) {
return (
ctx.message ??
ctx.editedMessage ??
ctx.callbackQuery?.message ??
ctx.channelPost ??
ctx.editedChannelPost
)
}