telegraf
Version:
Modern Telegram Bot Framework
214 lines (209 loc) • 7.01 kB
text/typescript
import { ReplyParameters } from '@telegraf/types'
import Context from './context'
import { Middleware } from './middleware'
type ReplyContext = { [key in keyof Context & `reply${string}`]: Context[key] }
function makeReply<
C extends Context,
E extends { reply_parameters?: ReplyParameters },
>(ctx: C, extra?: E) {
if (ctx.msgId)
return {
// overrides in this order so user can override all properties
reply_parameters: {
message_id: ctx.msgId,
...extra?.reply_parameters,
},
...extra,
}
else return extra
}
const replyContext: ReplyContext = {
replyWithChatAction: function () {
throw new TypeError(
'ctx.replyWithChatAction has been removed, use ctx.sendChatAction instead'
)
},
reply(this: Context, text, extra) {
this.assert(this.chat, 'reply')
return this.telegram.sendMessage(this.chat.id, text, makeReply(this, extra))
},
replyWithAnimation(this: Context, animation, extra) {
this.assert(this.chat, 'replyWithAnimation')
return this.telegram.sendAnimation(
this.chat.id,
animation,
makeReply(this, extra)
)
},
replyWithAudio(this: Context, audio, extra) {
this.assert(this.chat, 'replyWithAudio')
return this.telegram.sendAudio(this.chat.id, audio, makeReply(this, extra))
},
replyWithContact(this: Context, phoneNumber, firstName, extra) {
this.assert(this.chat, 'replyWithContact')
return this.telegram.sendContact(
this.chat.id,
phoneNumber,
firstName,
makeReply(this, extra)
)
},
replyWithDice(this: Context, extra) {
this.assert(this.chat, 'replyWithDice')
return this.telegram.sendDice(this.chat.id, makeReply(this, extra))
},
replyWithDocument(this: Context, document, extra) {
this.assert(this.chat, 'replyWithDocument')
return this.telegram.sendDocument(
this.chat.id,
document,
makeReply(this, extra)
)
},
replyWithGame(this: Context, gameName, extra) {
this.assert(this.chat, 'replyWithGame')
return this.telegram.sendGame(
this.chat.id,
gameName,
makeReply(this, extra)
)
},
replyWithHTML(this: Context, html, extra) {
this.assert(this.chat, 'replyWithHTML')
return this.telegram.sendMessage(this.chat.id, html, {
parse_mode: 'HTML',
...makeReply(this, extra),
})
},
replyWithInvoice(this: Context, invoice, extra) {
this.assert(this.chat, 'replyWithInvoice')
return this.telegram.sendInvoice(
this.chat.id,
invoice,
makeReply(this, extra)
)
},
replyWithLocation(this: Context, latitude, longitude, extra) {
this.assert(this.chat, 'replyWithLocation')
return this.telegram.sendLocation(
this.chat.id,
latitude,
longitude,
makeReply(this, extra)
)
},
replyWithMarkdown(this: Context, markdown, extra) {
this.assert(this.chat, 'replyWithMarkdown')
return this.telegram.sendMessage(this.chat.id, markdown, {
parse_mode: 'Markdown',
...makeReply(this, extra),
})
},
replyWithMarkdownV2(this: Context, markdown, extra) {
this.assert(this.chat, 'replyWithMarkdownV2')
return this.telegram.sendMessage(this.chat.id, markdown, {
parse_mode: 'MarkdownV2',
...makeReply(this, extra),
})
},
replyWithMediaGroup(this: Context, media, extra) {
this.assert(this.chat, 'replyWithMediaGroup')
return this.telegram.sendMediaGroup(
this.chat.id,
media,
makeReply(this, extra)
)
},
replyWithPhoto(this: Context, photo, extra) {
this.assert(this.chat, 'replyWithPhoto')
return this.telegram.sendPhoto(this.chat.id, photo, makeReply(this, extra))
},
replyWithPoll(this: Context, question, options, extra) {
this.assert(this.chat, 'replyWithPoll')
return this.telegram.sendPoll(
this.chat.id,
question,
options,
makeReply(this, extra)
)
},
replyWithQuiz(this: Context, question, options, extra) {
this.assert(this.chat, 'replyWithQuiz')
return this.telegram.sendQuiz(
this.chat.id,
question,
options,
makeReply(this, extra)
)
},
replyWithSticker(this: Context, sticker, extra) {
this.assert(this.chat, 'replyWithSticker')
return this.telegram.sendSticker(
this.chat.id,
sticker,
makeReply(this, extra)
)
},
replyWithVenue(this: Context, latitude, longitude, title, address, extra) {
this.assert(this.chat, 'replyWithVenue')
return this.telegram.sendVenue(
this.chat.id,
latitude,
longitude,
title,
address,
makeReply(this, extra)
)
},
replyWithVideo(this: Context, video, extra) {
this.assert(this.chat, 'replyWithVideo')
return this.telegram.sendVideo(this.chat.id, video, makeReply(this, extra))
},
replyWithVideoNote(this: Context, videoNote, extra) {
this.assert(this.chat, 'replyWithVideoNote')
return this.telegram.sendVideoNote(
this.chat.id,
videoNote,
makeReply(this, extra)
)
},
replyWithVoice(this: Context, voice, extra) {
this.assert(this.chat, 'replyWithVoice')
return this.telegram.sendVoice(this.chat.id, voice, makeReply(this, extra))
},
}
/**
* Sets up Context to use the new reply methods.
* This middleware makes `ctx.reply()` and `ctx.replyWith*()` methods will actually reply to the message they are replying to.
* Use `ctx.sendMessage()` to send a message in chat without replying to it.
*
* If the message to reply is deleted, `reply()` will send a normal message.
* If the update is not a message and we are unable to reply, `reply()` will send a normal message.
*/
export function useNewReplies<C extends Context>(): Middleware<C> {
return (ctx, next) => {
ctx.reply = replyContext.reply
ctx.replyWithPhoto = replyContext.replyWithPhoto
ctx.replyWithMediaGroup = replyContext.replyWithMediaGroup
ctx.replyWithAudio = replyContext.replyWithAudio
ctx.replyWithDice = replyContext.replyWithDice
ctx.replyWithDocument = replyContext.replyWithDocument
ctx.replyWithSticker = replyContext.replyWithSticker
ctx.replyWithVideo = replyContext.replyWithVideo
ctx.replyWithAnimation = replyContext.replyWithAnimation
ctx.replyWithVideoNote = replyContext.replyWithVideoNote
ctx.replyWithInvoice = replyContext.replyWithInvoice
ctx.replyWithGame = replyContext.replyWithGame
ctx.replyWithVoice = replyContext.replyWithVoice
ctx.replyWithPoll = replyContext.replyWithPoll
ctx.replyWithQuiz = replyContext.replyWithQuiz
ctx.replyWithChatAction = replyContext.replyWithChatAction
ctx.replyWithLocation = replyContext.replyWithLocation
ctx.replyWithVenue = replyContext.replyWithVenue
ctx.replyWithContact = replyContext.replyWithContact
ctx.replyWithMarkdown = replyContext.replyWithMarkdown
ctx.replyWithMarkdownV2 = replyContext.replyWithMarkdownV2
ctx.replyWithHTML = replyContext.replyWithHTML
return next()
}
}