Bug Fixes
This commit is contained in:
1 parent
82bc086e92
commit
b1af6e078c
131 files changed
+8597
-1930
No files matched your search
+23
-5
@@ -1,4 +1,4 @@
|
||||
const TelegrafContext = require('./core/context')
|
||||
const Context = require('./context')
|
||||
|
||||
class Composer {
|
||||
constructor (...fns) {
|
||||
@@ -100,9 +100,24 @@ class Composer {
|
||||
return (ctx) => ctx.reply(...args)
|
||||
}
|
||||
|
||||
static catchAll (...fns) {
|
||||
return Composer.catch((err) => {
|
||||
console.error()
|
||||
console.error((err.stack || err.toString()).replace(/^/gm, ' '))
|
||||
console.error()
|
||||
}, ...fns)
|
||||
}
|
||||
|
||||
static catch (errorHandler, ...fns) {
|
||||
const handler = Composer.compose(fns)
|
||||
return (ctx, next) => Promise.resolve(handler(ctx, next))
|
||||
.catch((err) => errorHandler(err, ctx))
|
||||
}
|
||||
|
||||
static fork (middleware) {
|
||||
const handler = Composer.unwrap(middleware)
|
||||
return (ctx, next) => {
|
||||
setImmediate(Composer.unwrap(middleware), ctx, Composer.safePassThru())
|
||||
setImmediate(handler, ctx, Composer.safePassThru())
|
||||
return next(ctx)
|
||||
}
|
||||
}
|
||||
@@ -317,7 +332,10 @@ class Composer {
|
||||
}
|
||||
|
||||
static unwrap (handler) {
|
||||
return handler && typeof handler.middleware === 'function'
|
||||
if (!handler) {
|
||||
throw new Error('Handler is undefined')
|
||||
}
|
||||
return typeof handler.middleware === 'function'
|
||||
? handler.middleware()
|
||||
: handler
|
||||
}
|
||||
@@ -336,14 +354,14 @@ class Composer {
|
||||
let index = -1
|
||||
return execute(0, ctx)
|
||||
function execute (i, context) {
|
||||
if (!(context instanceof TelegrafContext)) {
|
||||
if (!(context instanceof Context)) {
|
||||
return Promise.reject(new Error('next(ctx) called with invalid context'))
|
||||
}
|
||||
if (i <= index) {
|
||||
return Promise.reject(new Error('next() called multiple times'))
|
||||
}
|
||||
index = i
|
||||
const handler = Composer.unwrap(middlewares[i]) || next
|
||||
const handler = middlewares[i] ? Composer.unwrap(middlewares[i]) : next
|
||||
if (!handler) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
+568
@@ -0,0 +1,568 @@
|
||||
const UpdateTypes = [
|
||||
'callback_query',
|
||||
'channel_post',
|
||||
'chosen_inline_result',
|
||||
'edited_channel_post',
|
||||
'edited_message',
|
||||
'inline_query',
|
||||
'shipping_query',
|
||||
'pre_checkout_query',
|
||||
'message',
|
||||
'poll',
|
||||
'poll_answer'
|
||||
]
|
||||
|
||||
const MessageSubTypes = [
|
||||
'voice',
|
||||
'video_note',
|
||||
'video',
|
||||
'animation',
|
||||
'venue',
|
||||
'text',
|
||||
'supergroup_chat_created',
|
||||
'successful_payment',
|
||||
'sticker',
|
||||
'pinned_message',
|
||||
'photo',
|
||||
'new_chat_title',
|
||||
'new_chat_photo',
|
||||
'new_chat_members',
|
||||
'migrate_to_chat_id',
|
||||
'migrate_from_chat_id',
|
||||
'location',
|
||||
'left_chat_member',
|
||||
'invoice',
|
||||
'group_chat_created',
|
||||
'game',
|
||||
'document',
|
||||
'delete_chat_photo',
|
||||
'contact',
|
||||
'channel_chat_created',
|
||||
'audio',
|
||||
'connected_website',
|
||||
'passport_data',
|
||||
'poll',
|
||||
'forward_date'
|
||||
]
|
||||
|
||||
const MessageSubTypesMapping = {
|
||||
forward_date: 'forward'
|
||||
}
|
||||
|
||||
class TelegrafContext {
|
||||
constructor (update, telegram, options) {
|
||||
this.tg = telegram
|
||||
this.update = update
|
||||
this.options = options
|
||||
this.updateType = UpdateTypes.find((key) => key in this.update)
|
||||
if (this.updateType === 'message' || (this.options.channelMode && this.updateType === 'channel_post')) {
|
||||
this.updateSubTypes = MessageSubTypes
|
||||
.filter((key) => key in this.update[this.updateType])
|
||||
.map((type) => MessageSubTypesMapping[type] || type)
|
||||
} else {
|
||||
this.updateSubTypes = []
|
||||
}
|
||||
Object.getOwnPropertyNames(TelegrafContext.prototype)
|
||||
.filter((key) => key !== 'constructor' && typeof this[key] === 'function')
|
||||
.forEach((key) => (this[key] = this[key].bind(this)))
|
||||
}
|
||||
|
||||
get me () {
|
||||
return this.options && this.options.username
|
||||
}
|
||||
|
||||
get telegram () {
|
||||
return this.tg
|
||||
}
|
||||
|
||||
get message () {
|
||||
return this.update.message
|
||||
}
|
||||
|
||||
get editedMessage () {
|
||||
return this.update.edited_message
|
||||
}
|
||||
|
||||
get inlineQuery () {
|
||||
return this.update.inline_query
|
||||
}
|
||||
|
||||
get shippingQuery () {
|
||||
return this.update.shipping_query
|
||||
}
|
||||
|
||||
get preCheckoutQuery () {
|
||||
return this.update.pre_checkout_query
|
||||
}
|
||||
|
||||
get chosenInlineResult () {
|
||||
return this.update.chosen_inline_result
|
||||
}
|
||||
|
||||
get channelPost () {
|
||||
return this.update.channel_post
|
||||
}
|
||||
|
||||
get editedChannelPost () {
|
||||
return this.update.edited_channel_post
|
||||
}
|
||||
|
||||
get callbackQuery () {
|
||||
return this.update.callback_query
|
||||
}
|
||||
|
||||
get poll () {
|
||||
return this.update.poll
|
||||
}
|
||||
|
||||
get pollAnswer () {
|
||||
return this.update.poll_answer
|
||||
}
|
||||
|
||||
get chat () {
|
||||
return (this.message && this.message.chat) ||
|
||||
(this.editedMessage && this.editedMessage.chat) ||
|
||||
(this.callbackQuery && this.callbackQuery.message && this.callbackQuery.message.chat) ||
|
||||
(this.channelPost && this.channelPost.chat) ||
|
||||
(this.editedChannelPost && this.editedChannelPost.chat)
|
||||
}
|
||||
|
||||
get from () {
|
||||
return (this.message && this.message.from) ||
|
||||
(this.editedMessage && this.editedMessage.from) ||
|
||||
(this.callbackQuery && this.callbackQuery.from) ||
|
||||
(this.inlineQuery && this.inlineQuery.from) ||
|
||||
(this.channelPost && this.channelPost.from) ||
|
||||
(this.editedChannelPost && this.editedChannelPost.from) ||
|
||||
(this.shippingQuery && this.shippingQuery.from) ||
|
||||
(this.preCheckoutQuery && this.preCheckoutQuery.from) ||
|
||||
(this.chosenInlineResult && this.chosenInlineResult.from)
|
||||
}
|
||||
|
||||
get inlineMessageId () {
|
||||
return (this.callbackQuery && this.callbackQuery.inline_message_id) || (this.chosenInlineResult && this.chosenInlineResult.inline_message_id)
|
||||
}
|
||||
|
||||
get passportData () {
|
||||
return this.message && this.message.passport_data
|
||||
}
|
||||
|
||||
get state () {
|
||||
if (!this.contextState) {
|
||||
this.contextState = {}
|
||||
}
|
||||
return this.contextState
|
||||
}
|
||||
|
||||
set state (value) {
|
||||
this.contextState = { ...value }
|
||||
}
|
||||
|
||||
get webhookReply () {
|
||||
return this.tg.webhookReply
|
||||
}
|
||||
|
||||
set webhookReply (enable) {
|
||||
this.tg.webhookReply = enable
|
||||
}
|
||||
|
||||
assert (value, method) {
|
||||
if (!value) {
|
||||
throw new Error(`Telegraf: "${method}" isn't available for "${this.updateType}::${this.updateSubTypes}"`)
|
||||
}
|
||||
}
|
||||
|
||||
answerInlineQuery (...args) {
|
||||
this.assert(this.inlineQuery, 'answerInlineQuery')
|
||||
return this.telegram.answerInlineQuery(this.inlineQuery.id, ...args)
|
||||
}
|
||||
|
||||
answerCbQuery (...args) {
|
||||
this.assert(this.callbackQuery, 'answerCbQuery')
|
||||
return this.telegram.answerCbQuery(this.callbackQuery.id, ...args)
|
||||
}
|
||||
|
||||
answerGameQuery (...args) {
|
||||
this.assert(this.callbackQuery, 'answerGameQuery')
|
||||
return this.telegram.answerGameQuery(this.callbackQuery.id, ...args)
|
||||
}
|
||||
|
||||
answerShippingQuery (...args) {
|
||||
this.assert(this.shippingQuery, 'answerShippingQuery')
|
||||
return this.telegram.answerShippingQuery(this.shippingQuery.id, ...args)
|
||||
}
|
||||
|
||||
answerPreCheckoutQuery (...args) {
|
||||
this.assert(this.preCheckoutQuery, 'answerPreCheckoutQuery')
|
||||
return this.telegram.answerPreCheckoutQuery(this.preCheckoutQuery.id, ...args)
|
||||
}
|
||||
|
||||
editMessageText (text, extra) {
|
||||
this.assert(this.callbackQuery || this.inlineMessageId, 'editMessageText')
|
||||
return this.inlineMessageId
|
||||
? this.telegram.editMessageText(
|
||||
undefined,
|
||||
undefined,
|
||||
this.inlineMessageId,
|
||||
text,
|
||||
extra
|
||||
)
|
||||
: this.telegram.editMessageText(
|
||||
this.chat.id,
|
||||
this.callbackQuery.message.message_id,
|
||||
undefined,
|
||||
text,
|
||||
extra
|
||||
)
|
||||
}
|
||||
|
||||
editMessageCaption (caption, extra) {
|
||||
this.assert(this.callbackQuery || this.inlineMessageId, 'editMessageCaption')
|
||||
return this.inlineMessageId
|
||||
? this.telegram.editMessageCaption(
|
||||
undefined,
|
||||
undefined,
|
||||
this.inlineMessageId,
|
||||
caption,
|
||||
extra
|
||||
)
|
||||
: this.telegram.editMessageCaption(
|
||||
this.chat.id,
|
||||
this.callbackQuery.message.message_id,
|
||||
undefined,
|
||||
caption,
|
||||
extra
|
||||
)
|
||||
}
|
||||
|
||||
editMessageMedia (media, extra) {
|
||||
this.assert(this.callbackQuery || this.inlineMessageId, 'editMessageMedia')
|
||||
return this.inlineMessageId
|
||||
? this.telegram.editMessageMedia(
|
||||
undefined,
|
||||
undefined,
|
||||
this.inlineMessageId,
|
||||
media,
|
||||
extra
|
||||
)
|
||||
: this.telegram.editMessageMedia(
|
||||
this.chat.id,
|
||||
this.callbackQuery.message.message_id,
|
||||
undefined,
|
||||
media,
|
||||
extra
|
||||
)
|
||||
}
|
||||
|
||||
editMessageReplyMarkup (markup) {
|
||||
this.assert(this.callbackQuery || this.inlineMessageId, 'editMessageReplyMarkup')
|
||||
return this.inlineMessageId
|
||||
? this.telegram.editMessageReplyMarkup(
|
||||
undefined,
|
||||
undefined,
|
||||
this.inlineMessageId,
|
||||
markup
|
||||
)
|
||||
: this.telegram.editMessageReplyMarkup(
|
||||
this.chat.id,
|
||||
this.callbackQuery.message.message_id,
|
||||
undefined,
|
||||
markup
|
||||
)
|
||||
}
|
||||
|
||||
editMessageLiveLocation (latitude, longitude, markup) {
|
||||
this.assert(this.callbackQuery || this.inlineMessageId, 'editMessageLiveLocation')
|
||||
return this.inlineMessageId
|
||||
? this.telegram.editMessageLiveLocation(
|
||||
latitude,
|
||||
longitude,
|
||||
undefined,
|
||||
undefined,
|
||||
this.inlineMessageId,
|
||||
markup
|
||||
)
|
||||
: this.telegram.editMessageLiveLocation(
|
||||
latitude,
|
||||
longitude,
|
||||
this.chat.id,
|
||||
this.callbackQuery.message.message_id,
|
||||
undefined,
|
||||
markup
|
||||
)
|
||||
}
|
||||
|
||||
stopMessageLiveLocation (markup) {
|
||||
this.assert(this.callbackQuery || this.inlineMessageId, 'stopMessageLiveLocation')
|
||||
return this.inlineMessageId
|
||||
? this.telegram.stopMessageLiveLocation(
|
||||
undefined,
|
||||
undefined,
|
||||
this.inlineMessageId,
|
||||
markup
|
||||
)
|
||||
: this.telegram.stopMessageLiveLocation(
|
||||
this.chat.id,
|
||||
this.callbackQuery.message.message_id,
|
||||
undefined,
|
||||
markup
|
||||
)
|
||||
}
|
||||
|
||||
reply (...args) {
|
||||
this.assert(this.chat, 'reply')
|
||||
return this.telegram.sendMessage(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
getChat (...args) {
|
||||
this.assert(this.chat, 'getChat')
|
||||
return this.telegram.getChat(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
exportChatInviteLink (...args) {
|
||||
this.assert(this.chat, 'exportChatInviteLink')
|
||||
return this.telegram.exportChatInviteLink(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
kickChatMember (...args) {
|
||||
this.assert(this.chat, 'kickChatMember')
|
||||
return this.telegram.kickChatMember(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
restrictChatMember (...args) {
|
||||
this.assert(this.chat, 'restrictChatMember')
|
||||
return this.telegram.restrictChatMember(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
promoteChatMember (...args) {
|
||||
this.assert(this.chat, 'promoteChatMember')
|
||||
return this.telegram.promoteChatMember(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
setChatAdministratorCustomTitle (...args) {
|
||||
this.assert(this.chat, 'setChatAdministratorCustomTitle')
|
||||
return this.telegram.setChatAdministratorCustomTitle(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
setChatPhoto (...args) {
|
||||
this.assert(this.chat, 'setChatPhoto')
|
||||
return this.telegram.setChatPhoto(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
deleteChatPhoto (...args) {
|
||||
this.assert(this.chat, 'deleteChatPhoto')
|
||||
return this.telegram.deleteChatPhoto(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
setChatTitle (...args) {
|
||||
this.assert(this.chat, 'setChatTitle')
|
||||
return this.telegram.setChatTitle(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
setChatDescription (...args) {
|
||||
this.assert(this.chat, 'setChatDescription')
|
||||
return this.telegram.setChatDescription(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
pinChatMessage (...args) {
|
||||
this.assert(this.chat, 'pinChatMessage')
|
||||
return this.telegram.pinChatMessage(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
unpinChatMessage (...args) {
|
||||
this.assert(this.chat, 'unpinChatMessage')
|
||||
return this.telegram.unpinChatMessage(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
leaveChat (...args) {
|
||||
this.assert(this.chat, 'leaveChat')
|
||||
return this.telegram.leaveChat(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
setChatPermissions (...args) {
|
||||
this.assert(this.chat, 'setChatPermissions')
|
||||
return this.telegram.setChatPermissions(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
getChatAdministrators (...args) {
|
||||
this.assert(this.chat, 'getChatAdministrators')
|
||||
return this.telegram.getChatAdministrators(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
getChatMember (...args) {
|
||||
this.assert(this.chat, 'getChatMember')
|
||||
return this.telegram.getChatMember(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
getChatMembersCount (...args) {
|
||||
this.assert(this.chat, 'getChatMembersCount')
|
||||
return this.telegram.getChatMembersCount(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
setPassportDataErrors (errors) {
|
||||
this.assert(this.chat, 'setPassportDataErrors')
|
||||
return this.telegram.setPassportDataErrors(this.from.id, errors)
|
||||
}
|
||||
|
||||
replyWithPhoto (...args) {
|
||||
this.assert(this.chat, 'replyWithPhoto')
|
||||
return this.telegram.sendPhoto(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
replyWithMediaGroup (...args) {
|
||||
this.assert(this.chat, 'replyWithMediaGroup')
|
||||
return this.telegram.sendMediaGroup(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
replyWithAudio (...args) {
|
||||
this.assert(this.chat, 'replyWithAudio')
|
||||
return this.telegram.sendAudio(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
replyWithDocument (...args) {
|
||||
this.assert(this.chat, 'replyWithDocument')
|
||||
return this.telegram.sendDocument(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
replyWithSticker (...args) {
|
||||
this.assert(this.chat, 'replyWithSticker')
|
||||
return this.telegram.sendSticker(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
replyWithVideo (...args) {
|
||||
this.assert(this.chat, 'replyWithVideo')
|
||||
return this.telegram.sendVideo(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
replyWithAnimation (...args) {
|
||||
this.assert(this.chat, 'replyWithAnimation')
|
||||
return this.telegram.sendAnimation(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
replyWithVideoNote (...args) {
|
||||
this.assert(this.chat, 'replyWithVideoNote')
|
||||
return this.telegram.sendVideoNote(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
replyWithInvoice (...args) {
|
||||
this.assert(this.chat, 'replyWithInvoice')
|
||||
return this.telegram.sendInvoice(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
replyWithGame (...args) {
|
||||
this.assert(this.chat, 'replyWithGame')
|
||||
return this.telegram.sendGame(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
replyWithVoice (...args) {
|
||||
this.assert(this.chat, 'replyWithVoice')
|
||||
return this.telegram.sendVoice(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
replyWithPoll (...args) {
|
||||
this.assert(this.chat, 'replyWithPoll')
|
||||
return this.telegram.sendPoll(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
replyWithQuiz (...args) {
|
||||
this.assert(this.chat, 'replyWithQuiz')
|
||||
return this.telegram.sendQuiz(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
stopPoll (...args) {
|
||||
this.assert(this.chat, 'stopPoll')
|
||||
return this.telegram.stopPoll(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
replyWithChatAction (...args) {
|
||||
this.assert(this.chat, 'replyWithChatAction')
|
||||
return this.telegram.sendChatAction(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
replyWithLocation (...args) {
|
||||
this.assert(this.chat, 'replyWithLocation')
|
||||
return this.telegram.sendLocation(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
replyWithVenue (...args) {
|
||||
this.assert(this.chat, 'replyWithVenue')
|
||||
return this.telegram.sendVenue(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
replyWithContact (...args) {
|
||||
this.assert(this.from, 'replyWithContact')
|
||||
return this.telegram.sendContact(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
getStickerSet (setName) {
|
||||
return this.telegram.getStickerSet(setName)
|
||||
}
|
||||
|
||||
setChatStickerSet (setName) {
|
||||
this.assert(this.chat, 'setChatStickerSet')
|
||||
return this.telegram.setChatStickerSet(this.chat.id, setName)
|
||||
}
|
||||
|
||||
deleteChatStickerSet () {
|
||||
this.assert(this.chat, 'deleteChatStickerSet')
|
||||
return this.telegram.deleteChatStickerSet(this.chat.id)
|
||||
}
|
||||
|
||||
setStickerPositionInSet (sticker, position) {
|
||||
return this.telegram.setStickerPositionInSet(sticker, position)
|
||||
}
|
||||
|
||||
deleteStickerFromSet (sticker) {
|
||||
return this.telegram.deleteStickerFromSet(sticker)
|
||||
}
|
||||
|
||||
uploadStickerFile (...args) {
|
||||
this.assert(this.from, 'uploadStickerFile')
|
||||
return this.telegram.uploadStickerFile(this.from.id, ...args)
|
||||
}
|
||||
|
||||
createNewStickerSet (...args) {
|
||||
this.assert(this.from, 'createNewStickerSet')
|
||||
return this.telegram.createNewStickerSet(this.from.id, ...args)
|
||||
}
|
||||
|
||||
addStickerToSet (...args) {
|
||||
this.assert(this.from, 'addStickerToSet')
|
||||
return this.telegram.addStickerToSet(this.from.id, ...args)
|
||||
}
|
||||
|
||||
replyWithMarkdown (markdown, extra) {
|
||||
return this.reply(markdown, { parse_mode: 'Markdown', ...extra })
|
||||
}
|
||||
|
||||
replyWithHTML (html, extra) {
|
||||
return this.reply(html, { parse_mode: 'HTML', ...extra })
|
||||
}
|
||||
|
||||
deleteMessage (messageId) {
|
||||
this.assert(this.chat, 'deleteMessage')
|
||||
if (typeof messageId !== 'undefined') {
|
||||
return this.telegram.deleteMessage(this.chat.id, messageId)
|
||||
}
|
||||
const message = this.message ||
|
||||
this.editedMessage ||
|
||||
this.channelPost ||
|
||||
this.editedChannelPost ||
|
||||
(this.callbackQuery && this.callbackQuery.message)
|
||||
this.assert(message, 'deleteMessage')
|
||||
return this.telegram.deleteMessage(this.chat.id, message.message_id)
|
||||
}
|
||||
|
||||
forwardMessage (chatId, extra) {
|
||||
this.assert(this.chat, 'forwardMessage')
|
||||
const message = this.message ||
|
||||
this.editedMessage ||
|
||||
this.channelPost ||
|
||||
this.editedChannelPost ||
|
||||
(this.callbackQuery && this.callbackQuery.message)
|
||||
this.assert(message, 'forwardMessage')
|
||||
return this.telegram.forwardMessage(chatId, this.chat.id, message.message_id, extra)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = TelegrafContext
|
||||
+50
-32
@@ -8,7 +8,7 @@ const TelegramError = require('./error')
|
||||
const MultipartStream = require('./multipart-stream')
|
||||
const { isStream } = MultipartStream
|
||||
|
||||
const WebhookBlacklist = [
|
||||
const WEBHOOK_BLACKLIST = [
|
||||
'getChat',
|
||||
'getChatAdministrators',
|
||||
'getChatMember',
|
||||
@@ -22,7 +22,7 @@ const WebhookBlacklist = [
|
||||
'exportChatInviteLink'
|
||||
]
|
||||
|
||||
const DefaultExtensions = {
|
||||
const DEFAULT_EXTENSIONS = {
|
||||
audio: 'mp3',
|
||||
photo: 'jpg',
|
||||
sticker: 'webp',
|
||||
@@ -32,7 +32,7 @@ const DefaultExtensions = {
|
||||
voice: 'ogg'
|
||||
}
|
||||
|
||||
const DefaultOptions = {
|
||||
const DEFAULT_OPTIONS = {
|
||||
apiRoot: 'https://api.telegram.org',
|
||||
webhookReply: true,
|
||||
agent: new https.Agent({
|
||||
@@ -41,7 +41,7 @@ const DefaultOptions = {
|
||||
})
|
||||
}
|
||||
|
||||
const WebhookReplyStub = {
|
||||
const WEBHOOK_REPLY_STUB = {
|
||||
webhook: true,
|
||||
details: 'https://core.telegram.org/bots/api#making-requests-when-getting-updates'
|
||||
}
|
||||
@@ -79,13 +79,23 @@ function buildJSONConfig (payload) {
|
||||
})
|
||||
}
|
||||
|
||||
function buildFormDataConfig (payload) {
|
||||
if (payload.reply_markup && typeof payload.reply_markup !== 'string') {
|
||||
payload.reply_markup = JSON.stringify(payload.reply_markup)
|
||||
const FORM_DATA_JSON_FIELDS = [
|
||||
'results',
|
||||
'reply_markup',
|
||||
'mask_position',
|
||||
'shipping_options',
|
||||
'errors'
|
||||
]
|
||||
|
||||
function buildFormDataConfig (payload, agent) {
|
||||
for (const field of FORM_DATA_JSON_FIELDS) {
|
||||
if (field in payload && typeof payload[field] !== 'string') {
|
||||
payload[field] = JSON.stringify(payload[field])
|
||||
}
|
||||
}
|
||||
const boundary = crypto.randomBytes(32).toString('hex')
|
||||
const formData = new MultipartStream(boundary)
|
||||
const tasks = Object.keys(payload).map((key) => attachFormValue(formData, key, payload[key]))
|
||||
const tasks = Object.keys(payload).map((key) => attachFormValue(formData, key, payload[key], agent))
|
||||
return Promise.all(tasks).then(() => {
|
||||
return {
|
||||
method: 'POST',
|
||||
@@ -96,7 +106,7 @@ function buildFormDataConfig (payload) {
|
||||
})
|
||||
}
|
||||
|
||||
function attachFormValue (form, id, value) {
|
||||
function attachFormValue (form, id, value, agent) {
|
||||
if (!value) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
@@ -110,7 +120,7 @@ function attachFormValue (form, id, value) {
|
||||
}
|
||||
if (id === 'thumb') {
|
||||
const attachmentId = crypto.randomBytes(16).toString('hex')
|
||||
return attachFormMedia(form, value, attachmentId)
|
||||
return attachFormMedia(form, value, attachmentId, agent)
|
||||
.then(() => form.addPart({
|
||||
headers: { 'content-disposition': `form-data; name="${id}"` },
|
||||
body: `attach://${attachmentId}`
|
||||
@@ -123,8 +133,8 @@ function attachFormValue (form, id, value) {
|
||||
return Promise.resolve(item)
|
||||
}
|
||||
const attachmentId = crypto.randomBytes(16).toString('hex')
|
||||
return attachFormMedia(form, item.media, attachmentId)
|
||||
.then(() => Object.assign({}, item, { media: `attach://${attachmentId}` }))
|
||||
return attachFormMedia(form, item.media, attachmentId, agent)
|
||||
.then(() => ({ ...item, media: `attach://${attachmentId}` }))
|
||||
})
|
||||
).then((items) => form.addPart({
|
||||
headers: { 'content-disposition': `form-data; name="${id}"` },
|
||||
@@ -133,21 +143,22 @@ function attachFormValue (form, id, value) {
|
||||
}
|
||||
if (typeof value.media !== 'undefined' && typeof value.type !== 'undefined') {
|
||||
const attachmentId = crypto.randomBytes(16).toString('hex')
|
||||
return attachFormMedia(form, value.media, attachmentId)
|
||||
return attachFormMedia(form, value.media, attachmentId, agent)
|
||||
.then(() => form.addPart({
|
||||
headers: { 'content-disposition': `form-data; name="${id}"` },
|
||||
body: JSON.stringify(Object.assign(value, {
|
||||
body: JSON.stringify({
|
||||
...value,
|
||||
media: `attach://${attachmentId}`
|
||||
}))
|
||||
})
|
||||
}))
|
||||
}
|
||||
return attachFormMedia(form, value, id)
|
||||
return attachFormMedia(form, value, id, agent)
|
||||
}
|
||||
|
||||
function attachFormMedia (form, media, id) {
|
||||
let fileName = media.filename || `${id}.${DefaultExtensions[id] || 'dat'}`
|
||||
function attachFormMedia (form, media, id, agent) {
|
||||
let fileName = media.filename || `${id}.${DEFAULT_EXTENSIONS[id] || 'dat'}`
|
||||
if (media.url) {
|
||||
return fetch(media.url).then((res) =>
|
||||
return fetch(media.url, { agent }).then((res) =>
|
||||
form.addPart({
|
||||
headers: { 'content-disposition': `form-data; name="${id}"; filename="${fileName}"` },
|
||||
body: res.body
|
||||
@@ -173,32 +184,36 @@ function isKoaResponse (response) {
|
||||
return typeof response.set === 'function' && typeof response.header === 'object'
|
||||
}
|
||||
|
||||
function answerToWebhook (response, payload = {}) {
|
||||
function answerToWebhook (response, payload = {}, options) {
|
||||
if (!includesMedia(payload)) {
|
||||
if (isKoaResponse(response)) {
|
||||
response.body = payload
|
||||
return Promise.resolve(WebhookReplyStub)
|
||||
return Promise.resolve(WEBHOOK_REPLY_STUB)
|
||||
}
|
||||
if (!response.headersSent) {
|
||||
response.setHeader('content-type', 'application/json')
|
||||
}
|
||||
return new Promise((resolve) =>
|
||||
response.end(JSON.stringify(payload), 'utf-8', () => resolve(WebhookReplyStub))
|
||||
)
|
||||
return new Promise((resolve) => {
|
||||
if (response.end.length === 2) {
|
||||
response.end(JSON.stringify(payload), 'utf-8')
|
||||
return resolve(WEBHOOK_REPLY_STUB)
|
||||
}
|
||||
response.end(JSON.stringify(payload), 'utf-8', () => resolve(WEBHOOK_REPLY_STUB))
|
||||
})
|
||||
}
|
||||
|
||||
return buildFormDataConfig(payload)
|
||||
return buildFormDataConfig(payload, options.agent)
|
||||
.then(({ headers, body }) => {
|
||||
if (isKoaResponse(response)) {
|
||||
Object.keys(headers).forEach(key => response.set(key, headers[key]))
|
||||
response.body = body
|
||||
return Promise.resolve(WebhookReplyStub)
|
||||
return Promise.resolve(WEBHOOK_REPLY_STUB)
|
||||
}
|
||||
if (!response.headersSent) {
|
||||
Object.keys(headers).forEach(key => response.setHeader(key, headers[key]))
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
response.on('finish', () => resolve(WebhookReplyStub))
|
||||
response.on('finish', () => resolve(WEBHOOK_REPLY_STUB))
|
||||
body.pipe(response)
|
||||
})
|
||||
})
|
||||
@@ -207,7 +222,10 @@ function answerToWebhook (response, payload = {}) {
|
||||
class ApiClient {
|
||||
constructor (token, options, webhookResponse) {
|
||||
this.token = token
|
||||
this.options = Object.assign({}, DefaultOptions, options)
|
||||
this.options = {
|
||||
...DEFAULT_OPTIONS,
|
||||
...options
|
||||
}
|
||||
if (this.options.apiRoot.startsWith('http://')) {
|
||||
this.options.agent = null
|
||||
}
|
||||
@@ -227,12 +245,12 @@ class ApiClient {
|
||||
|
||||
const payload = Object.keys(data)
|
||||
.filter((key) => typeof data[key] !== 'undefined' && data[key] !== null)
|
||||
.reduce((acc, key) => Object.assign(acc, { [key]: data[key] }), {})
|
||||
.reduce((acc, key) => ({ ...acc, [key]: data[key] }), {})
|
||||
|
||||
if (options.webhookReply && response && !responseEnd && !WebhookBlacklist.includes(method)) {
|
||||
if (options.webhookReply && response && !responseEnd && !WEBHOOK_BLACKLIST.includes(method)) {
|
||||
debug('Call via webhook', method, payload)
|
||||
this.responseEnd = true
|
||||
return answerToWebhook(response, Object.assign({ method }, payload))
|
||||
return answerToWebhook(response, { method, ...payload }, options)
|
||||
}
|
||||
|
||||
if (!token) {
|
||||
@@ -241,7 +259,7 @@ class ApiClient {
|
||||
|
||||
debug('HTTP call', method, payload)
|
||||
const buildConfig = includesMedia(payload)
|
||||
? buildFormDataConfig(Object.assign({ method }, payload))
|
||||
? buildFormDataConfig({ method, ...payload }, options.agent)
|
||||
: buildJSONConfig(payload)
|
||||
return buildConfig
|
||||
.then((config) => {
|
||||
|
||||
+31
-30
@@ -1,26 +1,4 @@
|
||||
function wrapEntity (content, entity) {
|
||||
switch (entity.type) {
|
||||
case 'bold':
|
||||
return `<b>${content}</b>`
|
||||
case 'italic':
|
||||
return `<i>${content}</i>`
|
||||
case 'code':
|
||||
return `<code>${content}</code>`
|
||||
case 'pre':
|
||||
return `<pre>${content}</pre>`
|
||||
case 'text_link':
|
||||
return `<a href="${entity.url}">${content}</a>`
|
||||
default:
|
||||
return content
|
||||
}
|
||||
}
|
||||
|
||||
function applyEntity (text, entity) {
|
||||
const head = text.substring(0, entity.offset)
|
||||
const tail = text.substring(entity.offset + entity.length)
|
||||
const content = wrapEntity(text.substring(entity.offset, entity.offset + entity.length), entity)
|
||||
return `${head}${content}${tail}`
|
||||
}
|
||||
const { formatHTML } = require('../markup')
|
||||
|
||||
module.exports = {
|
||||
copyMethods: {
|
||||
@@ -35,17 +13,20 @@ module.exports = {
|
||||
video: 'sendVideo',
|
||||
video_note: 'sendVideoNote',
|
||||
animation: 'sendAnimation',
|
||||
voice: 'sendVoice'
|
||||
voice: 'sendVoice',
|
||||
poll: 'sendPoll'
|
||||
},
|
||||
text: (message) => {
|
||||
const entities = message.entities || []
|
||||
return {
|
||||
reply_markup: message.reply_markup,
|
||||
parse_mode: entities.length > 0 ? 'HTML' : '',
|
||||
text: entities.reduceRight(applyEntity, message.text)
|
||||
text: formatHTML(message.text, entities)
|
||||
}
|
||||
},
|
||||
contact: (message) => {
|
||||
return {
|
||||
reply_markup: message.reply_markup,
|
||||
phone_number: message.contact.phone_number,
|
||||
first_name: message.contact.first_name,
|
||||
last_name: message.contact.last_name
|
||||
@@ -53,12 +34,14 @@ module.exports = {
|
||||
},
|
||||
location: (message) => {
|
||||
return {
|
||||
reply_markup: message.reply_markup,
|
||||
latitude: message.location.latitude,
|
||||
longitude: message.location.longitude
|
||||
}
|
||||
},
|
||||
venue: (message) => {
|
||||
return {
|
||||
reply_markup: message.reply_markup,
|
||||
latitude: message.venue.location.latitude,
|
||||
longitude: message.venue.location.longitude,
|
||||
title: message.venue.title,
|
||||
@@ -69,30 +52,33 @@ module.exports = {
|
||||
voice: (message) => {
|
||||
const entities = message.caption_entities || []
|
||||
return {
|
||||
reply_markup: message.reply_markup,
|
||||
voice: message.voice.file_id,
|
||||
duration: message.voice.duration,
|
||||
caption: entities.reduceRight(applyEntity, message.caption),
|
||||
caption: formatHTML(message.caption, entities),
|
||||
parse_mode: entities.length > 0 ? 'HTML' : ''
|
||||
}
|
||||
},
|
||||
audio: (message) => {
|
||||
const entities = message.caption_entities || []
|
||||
return {
|
||||
reply_markup: message.reply_markup,
|
||||
audio: message.audio.file_id,
|
||||
thumb: message.audio.thumb,
|
||||
duration: message.audio.duration,
|
||||
performer: message.audio.performer,
|
||||
title: message.audio.title,
|
||||
caption: entities.reduceRight(applyEntity, message.caption),
|
||||
caption: formatHTML(message.caption, entities),
|
||||
parse_mode: entities.length > 0 ? 'HTML' : ''
|
||||
}
|
||||
},
|
||||
video: (message) => {
|
||||
const entities = message.caption_entities || []
|
||||
return {
|
||||
reply_markup: message.reply_markup,
|
||||
video: message.video.file_id,
|
||||
thumb: message.video.thumb,
|
||||
caption: entities.reduceRight(applyEntity, message.caption),
|
||||
caption: formatHTML(message.caption, entities),
|
||||
parse_mode: entities.length > 0 ? 'HTML' : '',
|
||||
duration: message.video.duration,
|
||||
width: message.video.width,
|
||||
@@ -103,26 +89,30 @@ module.exports = {
|
||||
document: (message) => {
|
||||
const entities = message.caption_entities || []
|
||||
return {
|
||||
reply_markup: message.reply_markup,
|
||||
document: message.document.file_id,
|
||||
caption: entities.reduceRight(applyEntity, message.caption),
|
||||
caption: formatHTML(message.caption, entities),
|
||||
parse_mode: entities.length > 0 ? 'HTML' : ''
|
||||
}
|
||||
},
|
||||
sticker: (message) => {
|
||||
return {
|
||||
reply_markup: message.reply_markup,
|
||||
sticker: message.sticker.file_id
|
||||
}
|
||||
},
|
||||
photo: (message) => {
|
||||
const entities = message.caption_entities || []
|
||||
return {
|
||||
reply_markup: message.reply_markup,
|
||||
photo: message.photo[message.photo.length - 1].file_id,
|
||||
parse_mode: entities.length > 0 ? 'HTML' : '',
|
||||
caption: entities.reduceRight(applyEntity, message.caption)
|
||||
caption: formatHTML(message.caption, entities)
|
||||
}
|
||||
},
|
||||
video_note: (message) => {
|
||||
return {
|
||||
reply_markup: message.reply_markup,
|
||||
video_note: message.video_note.file_id,
|
||||
thumb: message.video_note.thumb,
|
||||
length: message.video_note.length,
|
||||
@@ -131,9 +121,20 @@ module.exports = {
|
||||
},
|
||||
animation: (message) => {
|
||||
return {
|
||||
reply_markup: message.reply_markup,
|
||||
animation: message.animation.file_id,
|
||||
thumb: message.animation.thumb,
|
||||
duration: message.animation.duration
|
||||
}
|
||||
},
|
||||
poll: (message) => {
|
||||
return {
|
||||
question: message.poll.question,
|
||||
type: message.poll.type,
|
||||
is_anonymous: message.poll.is_anonymous,
|
||||
allows_multiple_answers: message.poll.allows_multiple_answers,
|
||||
correct_option_id: message.poll.correct_option_id,
|
||||
options: message.poll.options.map(({ text }) => text)
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -5,8 +5,8 @@ class Extra {
|
||||
this.load(opts)
|
||||
}
|
||||
|
||||
load (opts) {
|
||||
return Object.assign(this, opts || {})
|
||||
load (opts = {}) {
|
||||
return Object.assign(this, opts)
|
||||
}
|
||||
|
||||
inReplyTo (messageId) {
|
||||
@@ -28,7 +28,7 @@ class Extra {
|
||||
if (typeof markup === 'function') {
|
||||
markup = markup(new Markup())
|
||||
}
|
||||
this.reply_markup = Object.assign({}, markup)
|
||||
this.reply_markup = { ...markup }
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
+87
-6
@@ -15,13 +15,14 @@ class Markup {
|
||||
}
|
||||
|
||||
extra (options) {
|
||||
return Object.assign({
|
||||
reply_markup: Object.assign({}, this)
|
||||
}, options)
|
||||
return {
|
||||
reply_markup: { ...this },
|
||||
...options
|
||||
}
|
||||
}
|
||||
|
||||
keyboard (buttons, options) {
|
||||
const keyboard = buildKeyboard(buttons, Object.assign({ columns: 1 }, options))
|
||||
const keyboard = buildKeyboard(buttons, { columns: 1, ...options })
|
||||
if (keyboard && keyboard.length > 0) {
|
||||
this.keyboard = keyboard
|
||||
}
|
||||
@@ -39,7 +40,7 @@ class Markup {
|
||||
}
|
||||
|
||||
inlineKeyboard (buttons, options) {
|
||||
const keyboard = buildKeyboard(buttons, Object.assign({ columns: buttons.length }, options))
|
||||
const keyboard = buildKeyboard(buttons, { columns: buttons.length, ...options })
|
||||
if (keyboard && keyboard.length > 0) {
|
||||
this.inline_keyboard = keyboard
|
||||
}
|
||||
@@ -126,6 +127,10 @@ class Markup {
|
||||
return { text: text, request_location: true, hide: hide }
|
||||
}
|
||||
|
||||
static pollRequestButton (text, type, hide = false) {
|
||||
return { text: text, request_poll: { type }, hide: hide }
|
||||
}
|
||||
|
||||
static urlButton (text, url, hide = false) {
|
||||
return { text: text, url: url, hide: hide }
|
||||
}
|
||||
@@ -153,10 +158,86 @@ class Markup {
|
||||
static loginButton (text, url, opts = {}, hide = false) {
|
||||
return {
|
||||
text: text,
|
||||
login_url: Object.assign({}, opts, { url: url }),
|
||||
login_url: { ...opts, url: url },
|
||||
hide: hide
|
||||
}
|
||||
}
|
||||
|
||||
static formatHTML (text, entities) {
|
||||
const chars = [...text]
|
||||
const available = [...entities]
|
||||
const opened = []
|
||||
const result = []
|
||||
for (let offset = 0; offset < chars.length; offset++) {
|
||||
while (true) {
|
||||
const index = available.findIndex((entity) => entity.offset === offset)
|
||||
if (index === -1) {
|
||||
break
|
||||
}
|
||||
const entity = available[index]
|
||||
switch (entity.type) {
|
||||
case 'bold':
|
||||
result.push('<b>')
|
||||
break
|
||||
case 'italic':
|
||||
result.push('<i>')
|
||||
break
|
||||
case 'code':
|
||||
result.push('<code>')
|
||||
break
|
||||
case 'pre':
|
||||
result.push('<pre>')
|
||||
break
|
||||
case 'strikethrough':
|
||||
result.push('<s>')
|
||||
break
|
||||
case 'underline':
|
||||
result.push('<u>')
|
||||
break
|
||||
case 'text_link':
|
||||
result.push(`<a href="${entity.url}">`)
|
||||
break
|
||||
}
|
||||
opened.unshift(entity)
|
||||
available.splice(index, 1)
|
||||
}
|
||||
|
||||
result.push(chars[offset])
|
||||
|
||||
while (true) {
|
||||
const index = opened.findIndex((entity) => entity.offset + entity.length - 1 === offset)
|
||||
if (index === -1) {
|
||||
break
|
||||
}
|
||||
const entity = opened[index]
|
||||
switch (entity.type) {
|
||||
case 'bold':
|
||||
result.push('</b>')
|
||||
break
|
||||
case 'italic':
|
||||
result.push('</i>')
|
||||
break
|
||||
case 'code':
|
||||
result.push('</code>')
|
||||
break
|
||||
case 'pre':
|
||||
result.push('</pre>')
|
||||
break
|
||||
case 'strikethrough':
|
||||
result.push('</s>')
|
||||
break
|
||||
case 'underline':
|
||||
result.push('</u>')
|
||||
break
|
||||
case 'text_link':
|
||||
result.push('</a>')
|
||||
break
|
||||
}
|
||||
opened.splice(index, 1)
|
||||
}
|
||||
}
|
||||
return result.join('')
|
||||
}
|
||||
}
|
||||
|
||||
function buildKeyboard (buttons, options) {
|
||||
|
||||
+26
-19
@@ -1,61 +1,67 @@
|
||||
{
|
||||
"_from": "telegraf",
|
||||
"_id": "telegraf@3.32.0",
|
||||
"_from": "telegraf@3.36.0",
|
||||
"_id": "telegraf@3.36.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-5ZHiovyuG1rVLygJjaqf57wDt8e1nijAinKXCxN1tyUZ4BcrkZW/z5rVTEXA+KegpFbWxKKv3KnJwUJrKDqD0Q==",
|
||||
"_integrity": "sha512-9o6AJKRiTm5vMWYI6WpTfBHzu4FMpWBNKxvnMxRds/cbMY9RnsVVjdi8i4bFFlfd+xbi73EbrnI3dybayryICA==",
|
||||
"_location": "/telegraf",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "tag",
|
||||
"type": "version",
|
||||
"registry": true,
|
||||
"raw": "telegraf",
|
||||
"raw": "telegraf@3.36.0",
|
||||
"name": "telegraf",
|
||||
"escapedName": "telegraf",
|
||||
"rawSpec": "",
|
||||
"rawSpec": "3.36.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "latest"
|
||||
"fetchSpec": "3.36.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"#USER",
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/telegraf/-/telegraf-3.32.0.tgz",
|
||||
"_shasum": "70ec304b9c8645f8988924ebe90e5c00ee46ddbb",
|
||||
"_spec": "telegraf",
|
||||
"_resolved": "https://registry.npmjs.org/telegraf/-/telegraf-3.36.0.tgz",
|
||||
"_shasum": "eab1160159df6033d3cb92ac990902523277822a",
|
||||
"_spec": "telegraf@3.36.0",
|
||||
"_where": "C:\\Users\\Luis\\source\\repos\\AAMasters\\TaskServer",
|
||||
"author": {
|
||||
"name": "Vitaly Domnikov",
|
||||
"email": "oss@vitaly.codes"
|
||||
},
|
||||
"bin": {
|
||||
"telegraf": "./bin/telegraf"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/telegraf/telegraf/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"@types/node": "^12.0.4",
|
||||
"@types/node": "^13.1.0",
|
||||
"debug": "^4.0.1",
|
||||
"minimist": "^1.2.0",
|
||||
"module-alias": "^2.2.2",
|
||||
"node-fetch": "^2.2.0",
|
||||
"sandwich-stream": "^2.0.1",
|
||||
"telegram-typings": "^3.6.0"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "📡 Modern Telegram Bot Framework",
|
||||
"description": "Modern Telegram Bot Framework",
|
||||
"devDependencies": {
|
||||
"ava": "^2.2.0",
|
||||
"eslint": "^6.1.0",
|
||||
"eslint-config-standard": "^13.0.1",
|
||||
"eslint-plugin-ava": "^7.1.0",
|
||||
"ava": "^3.0.0",
|
||||
"eslint": "^6.2.2",
|
||||
"eslint-config-standard": "^14.1.0",
|
||||
"eslint-plugin-ava": "^10.0.0",
|
||||
"eslint-plugin-import": "^2.2.0",
|
||||
"eslint-plugin-node": "^9.1.0",
|
||||
"eslint-plugin-node": "^11.0.0",
|
||||
"eslint-plugin-promise": "^4.0.0",
|
||||
"eslint-plugin-standard": "^4.0.0",
|
||||
"husky": "^3.0.2",
|
||||
"husky": "^4.2.0",
|
||||
"typescript": "^3.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"files": [
|
||||
"bin/*",
|
||||
"core/**/*.js",
|
||||
"scenes/**/*.js",
|
||||
"typings/*.d.ts",
|
||||
@@ -83,6 +89,7 @@
|
||||
"test": "ava test/*",
|
||||
"typecheck": "tsc"
|
||||
},
|
||||
"type": "commonjs",
|
||||
"types": "./typings/index.d.ts",
|
||||
"version": "3.32.0"
|
||||
"version": "3.36.0"
|
||||
}
|
||||
+4
-3
@@ -3,11 +3,12 @@ const { compose } = Composer
|
||||
|
||||
class BaseScene extends Composer {
|
||||
constructor (id, options) {
|
||||
const opts = Object.assign({
|
||||
const opts = {
|
||||
handlers: [],
|
||||
enterHandlers: [],
|
||||
leaveHandlers: []
|
||||
}, options)
|
||||
leaveHandlers: [],
|
||||
...options
|
||||
}
|
||||
super(...opts.handlers)
|
||||
this.id = id
|
||||
this.options = opts
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ class SceneContext {
|
||||
}
|
||||
|
||||
set state (value) {
|
||||
this.session.state = Object.assign({}, value)
|
||||
this.session.state = { ...value }
|
||||
}
|
||||
|
||||
get current () {
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ class WizardScene extends Composer {
|
||||
this.id = id
|
||||
this.options = typeof options === 'function'
|
||||
? { steps: [options, ...steps], leaveHandlers: [] }
|
||||
: Object.assign({ steps: steps, leaveHandlers: [] }, options)
|
||||
: { steps: steps, leaveHandlers: [], ...options }
|
||||
this.leaveHandler = compose(this.options.leaveHandlers)
|
||||
}
|
||||
|
||||
|
||||
+5
-4
@@ -1,9 +1,10 @@
|
||||
module.exports = function (opts) {
|
||||
const options = Object.assign({
|
||||
const options = {
|
||||
property: 'session',
|
||||
store: new Map(),
|
||||
getSessionKey: (ctx) => ctx.from && ctx.chat && `${ctx.from.id}:${ctx.chat.id}`
|
||||
}, opts)
|
||||
getSessionKey: (ctx) => ctx.from && ctx.chat && `${ctx.from.id}:${ctx.chat.id}`,
|
||||
...opts
|
||||
}
|
||||
|
||||
const ttlMs = options.ttl && options.ttl * 1000
|
||||
|
||||
@@ -21,7 +22,7 @@ module.exports = function (opts) {
|
||||
}
|
||||
Object.defineProperty(ctx, options.property, {
|
||||
get: function () { return session },
|
||||
set: function (newValue) { session = Object.assign({}, newValue) }
|
||||
set: function (newValue) { session = { ...newValue } }
|
||||
})
|
||||
return next(ctx).then(() => options.store.set(key, {
|
||||
session,
|
||||
|
||||
+4
-3
@@ -5,9 +5,10 @@ const { compose, optional, lazy, safePassThru } = Composer
|
||||
class Stage extends Composer {
|
||||
constructor (scenes = [], options) {
|
||||
super()
|
||||
this.options = Object.assign({
|
||||
sessionName: 'session'
|
||||
}, options)
|
||||
this.options = {
|
||||
sessionName: 'session',
|
||||
...options
|
||||
}
|
||||
this.scenes = new Map()
|
||||
scenes.forEach((scene) => this.register(scene))
|
||||
}
|
||||
|
||||
+42
-18
@@ -5,14 +5,17 @@ const Composer = require('./composer')
|
||||
const Markup = require('./markup')
|
||||
const session = require('./session')
|
||||
const Router = require('./router')
|
||||
const Context = require('./core/context')
|
||||
const Stage = require('./stage')
|
||||
const BaseScene = require('./scenes/base')
|
||||
const Context = require('./context')
|
||||
const generateCallback = require('./core/network/webhook')
|
||||
const crypto = require('crypto')
|
||||
const { URL } = require('url')
|
||||
|
||||
const DefaultOptions = {
|
||||
const DEFAULT_OPTIONS = {
|
||||
retryAfter: 1,
|
||||
handlerTimeout: 0
|
||||
handlerTimeout: 0,
|
||||
contextType: Context
|
||||
}
|
||||
|
||||
const noop = () => { }
|
||||
@@ -20,7 +23,10 @@ const noop = () => { }
|
||||
class Telegraf extends Composer {
|
||||
constructor (token, options) {
|
||||
super()
|
||||
this.options = Object.assign({}, DefaultOptions, options)
|
||||
this.options = {
|
||||
...DEFAULT_OPTIONS,
|
||||
...options
|
||||
}
|
||||
this.token = token
|
||||
this.handleError = (err) => {
|
||||
console.error()
|
||||
@@ -92,6 +98,7 @@ class Telegraf extends Composer {
|
||||
}
|
||||
|
||||
launch (config = {}) {
|
||||
debug('Connecting to Telegram')
|
||||
return this.telegram.getMe()
|
||||
.then((botInfo) => {
|
||||
debug(`Launching @${botInfo.username}`)
|
||||
@@ -101,7 +108,7 @@ class Telegraf extends Composer {
|
||||
const { timeout, limit, allowedUpdates, stopCallback } = config.polling || {}
|
||||
return this.telegram.deleteWebhook()
|
||||
.then(() => this.startPolling(timeout, limit, allowedUpdates, stopCallback))
|
||||
.then(() => debug(`Bot started with long-polling`))
|
||||
.then(() => debug('Bot started with long-polling'))
|
||||
}
|
||||
if (typeof config.webhook.domain !== 'string' && typeof config.webhook.hookPath !== 'string') {
|
||||
throw new Error('Webhook domain or webhook path is required')
|
||||
@@ -114,23 +121,31 @@ class Telegraf extends Composer {
|
||||
const { port, host, tlsOptions, cb } = config.webhook
|
||||
this.startWebhook(hookPath, tlsOptions, port, host, cb)
|
||||
if (!domain) {
|
||||
debug(`Bot started with webhook`)
|
||||
debug('Bot started with webhook')
|
||||
return
|
||||
}
|
||||
return this.telegram
|
||||
.setWebhook(`https://${domain}${hookPath}`)
|
||||
.then(() => debug(`Bot started with webhook @ https://${domain}`))
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('Launch failed')
|
||||
console.error(err.stack || err.toString())
|
||||
})
|
||||
}
|
||||
|
||||
stop (cb = noop) {
|
||||
this.polling.started = false
|
||||
if (this.webhookServer) {
|
||||
this.webhookServer.close(cb)
|
||||
} else {
|
||||
cb()
|
||||
}
|
||||
return this
|
||||
debug('Stopping bot...')
|
||||
return new Promise((resolve) => {
|
||||
const done = () => resolve() & cb()
|
||||
if (this.webhookServer) {
|
||||
return this.webhookServer.close(done)
|
||||
} else if (!this.polling.started) {
|
||||
return done()
|
||||
}
|
||||
this.polling.stopCallback = done
|
||||
this.polling.started = false
|
||||
})
|
||||
}
|
||||
|
||||
handleUpdates (updates) {
|
||||
@@ -150,16 +165,18 @@ class Telegraf extends Composer {
|
||||
handleUpdate (update, webhookResponse) {
|
||||
debug('Processing update', update.update_id)
|
||||
const tg = new Telegram(this.token, this.telegram.options, webhookResponse)
|
||||
const ctx = new Context(update, tg, this.options)
|
||||
const TelegrafContext = this.options.contextType
|
||||
const ctx = new TelegrafContext(update, tg, this.options)
|
||||
Object.assign(ctx, this.context)
|
||||
return this.middleware()(ctx).catch(this.handleError)
|
||||
return this.middleware()(ctx).catch((err) => this.handleError(err, ctx))
|
||||
}
|
||||
|
||||
fetchUpdates () {
|
||||
const { timeout, limit, offset, started, allowedUpdates } = this.polling
|
||||
if (!started) {
|
||||
if (!this.polling.started) {
|
||||
this.polling.stopCallback && this.polling.stopCallback()
|
||||
return
|
||||
}
|
||||
const { timeout, limit, offset, allowedUpdates } = this.polling
|
||||
this.telegram.getUpdates(timeout, limit, offset, allowedUpdates)
|
||||
.catch((err) => {
|
||||
if (err.code === 401 || err.code === 409) {
|
||||
@@ -169,7 +186,10 @@ class Telegraf extends Composer {
|
||||
console.error(`Failed to fetch updates. Waiting: ${wait}s`, err.message)
|
||||
return new Promise((resolve) => setTimeout(resolve, wait * 1000, []))
|
||||
})
|
||||
.then((updates) => this.handleUpdates(updates).then(() => updates))
|
||||
.then((updates) => this.polling.started
|
||||
? this.handleUpdates(updates).then(() => updates)
|
||||
: []
|
||||
)
|
||||
.catch((err) => {
|
||||
console.error('Failed to process updates.', err)
|
||||
this.polling.started = false
|
||||
@@ -187,6 +207,7 @@ class Telegraf extends Composer {
|
||||
}
|
||||
|
||||
module.exports = Object.assign(Telegraf, {
|
||||
Context,
|
||||
Composer,
|
||||
Extra,
|
||||
Markup,
|
||||
@@ -196,10 +217,13 @@ module.exports = Object.assign(Telegraf, {
|
||||
})
|
||||
|
||||
module.exports.default = Object.assign(Telegraf, {
|
||||
Context,
|
||||
Composer,
|
||||
Extra,
|
||||
Markup,
|
||||
Router,
|
||||
Telegram,
|
||||
Stage,
|
||||
BaseScene,
|
||||
session
|
||||
})
|
||||
+96
-84
@@ -1,4 +1,3 @@
|
||||
const util = require('util')
|
||||
const replicators = require('./core/replicators')
|
||||
const ApiClient = require('./core/network/client')
|
||||
|
||||
@@ -31,11 +30,11 @@ class Telegram extends ApiClient {
|
||||
}
|
||||
|
||||
getWebhookInfo () {
|
||||
return this.callApi(`getWebhookInfo`)
|
||||
return this.callApi('getWebhookInfo')
|
||||
}
|
||||
|
||||
getGameHighScores (userId, inlineMessageId, chatId, messageId) {
|
||||
return this.callApi(`getGameHighScores`, {
|
||||
return this.callApi('getGameHighScores', {
|
||||
user_id: userId,
|
||||
inline_message_id: inlineMessageId,
|
||||
chat_id: chatId,
|
||||
@@ -44,21 +43,21 @@ class Telegram extends ApiClient {
|
||||
}
|
||||
|
||||
setGameScore (userId, score, inlineMessageId, chatId, messageId, editMessage = true, force) {
|
||||
return this.callApi(`setGameScore`, {
|
||||
return this.callApi('setGameScore', {
|
||||
force,
|
||||
score,
|
||||
user_id: userId,
|
||||
score: score,
|
||||
inline_message_id: inlineMessageId,
|
||||
chat_id: chatId,
|
||||
message_id: messageId,
|
||||
disable_edit_message: !editMessage,
|
||||
force: force
|
||||
disable_edit_message: !editMessage
|
||||
})
|
||||
}
|
||||
|
||||
setWebhook (url, cert, maxConnections, allowedUpdates) {
|
||||
setWebhook (url, certificate, maxConnections, allowedUpdates) {
|
||||
return this.callApi('setWebhook', {
|
||||
url: url,
|
||||
certificate: cert,
|
||||
url,
|
||||
certificate,
|
||||
max_connections: maxConnections,
|
||||
allowed_updates: allowedUpdates
|
||||
})
|
||||
@@ -69,93 +68,99 @@ class Telegram extends ApiClient {
|
||||
}
|
||||
|
||||
sendMessage (chatId, text, extra) {
|
||||
return this.callApi('sendMessage', Object.assign({ chat_id: chatId, text: text }, extra))
|
||||
return this.callApi('sendMessage', { chat_id: chatId, text, ...extra })
|
||||
}
|
||||
|
||||
forwardMessage (chatId, fromChatId, messageId, extra) {
|
||||
return this.callApi('forwardMessage', Object.assign({
|
||||
return this.callApi('forwardMessage', {
|
||||
chat_id: chatId,
|
||||
from_chat_id: fromChatId,
|
||||
message_id: messageId
|
||||
}, extra))
|
||||
message_id: messageId,
|
||||
...extra
|
||||
})
|
||||
}
|
||||
|
||||
sendChatAction (chatId, action) {
|
||||
return this.callApi('sendChatAction', { chat_id: chatId, action: action })
|
||||
return this.callApi('sendChatAction', { chat_id: chatId, action })
|
||||
}
|
||||
|
||||
getUserProfilePhotos (userId, offset, limit) {
|
||||
return this.callApi('getUserProfilePhotos', { user_id: userId, offset: offset, limit: limit })
|
||||
return this.callApi('getUserProfilePhotos', { user_id: userId, offset, limit })
|
||||
}
|
||||
|
||||
sendLocation (chatId, latitude, longitude, extra) {
|
||||
return this.callApi('sendLocation', Object.assign({ chat_id: chatId, latitude: latitude, longitude: longitude }, extra))
|
||||
return this.callApi('sendLocation', { chat_id: chatId, latitude, longitude, ...extra })
|
||||
}
|
||||
|
||||
sendVenue (chatId, latitude, longitude, title, address, extra) {
|
||||
return this.callApi('sendVenue', Object.assign({
|
||||
return this.callApi('sendVenue', {
|
||||
latitude,
|
||||
longitude,
|
||||
title,
|
||||
address,
|
||||
chat_id: chatId,
|
||||
latitude: latitude,
|
||||
longitude: longitude,
|
||||
title: title,
|
||||
address: address
|
||||
}, extra))
|
||||
...extra
|
||||
})
|
||||
}
|
||||
|
||||
sendInvoice (chatId, invoice, extra) {
|
||||
return this.callApi('sendInvoice', Object.assign({ chat_id: chatId }, invoice, extra))
|
||||
return this.callApi('sendInvoice', { chat_id: chatId, ...invoice, ...extra })
|
||||
}
|
||||
|
||||
sendContact (chatId, phoneNumber, firstName, extra) {
|
||||
return this.callApi('sendContact', Object.assign({ chat_id: chatId, phone_number: phoneNumber, first_name: firstName }, extra))
|
||||
return this.callApi('sendContact', { chat_id: chatId, phone_number: phoneNumber, first_name: firstName, ...extra })
|
||||
}
|
||||
|
||||
sendPhoto (chatId, photo, extra) {
|
||||
return this.callApi('sendPhoto', Object.assign({ chat_id: chatId, photo: photo }, extra))
|
||||
return this.callApi('sendPhoto', { chat_id: chatId, photo, ...extra })
|
||||
}
|
||||
|
||||
sendDocument (chatId, doc, extra) {
|
||||
return this.callApi('sendDocument', Object.assign({ chat_id: chatId, document: doc }, extra))
|
||||
sendDocument (chatId, document, extra) {
|
||||
return this.callApi('sendDocument', { chat_id: chatId, document, ...extra })
|
||||
}
|
||||
|
||||
sendAudio (chatId, audio, extra) {
|
||||
return this.callApi('sendAudio', Object.assign({ chat_id: chatId, audio: audio }, extra))
|
||||
return this.callApi('sendAudio', { chat_id: chatId, audio, ...extra })
|
||||
}
|
||||
|
||||
sendSticker (chatId, sticker, extra) {
|
||||
return this.callApi('sendSticker', Object.assign({ chat_id: chatId, sticker: sticker }, extra))
|
||||
return this.callApi('sendSticker', { chat_id: chatId, sticker, ...extra })
|
||||
}
|
||||
|
||||
sendVideo (chatId, video, extra) {
|
||||
return this.callApi('sendVideo', Object.assign({ chat_id: chatId, video: video }, extra))
|
||||
return this.callApi('sendVideo', { chat_id: chatId, video, ...extra })
|
||||
}
|
||||
|
||||
sendAnimation (chatId, animation, extra) {
|
||||
return this.callApi('sendAnimation', Object.assign({ chat_id: chatId, animation: animation }, extra))
|
||||
return this.callApi('sendAnimation', { chat_id: chatId, animation, ...extra })
|
||||
}
|
||||
|
||||
sendVideoNote (chatId, videoNote, extra) {
|
||||
return this.callApi('sendVideoNote', Object.assign({ chat_id: chatId, video_note: videoNote }, extra))
|
||||
return this.callApi('sendVideoNote', { chat_id: chatId, video_note: videoNote, ...extra })
|
||||
}
|
||||
|
||||
sendVoice (chatId, voice, extra) {
|
||||
return this.callApi('sendVoice', Object.assign({ chat_id: chatId, voice: voice }, extra))
|
||||
return this.callApi('sendVoice', { chat_id: chatId, voice, ...extra })
|
||||
}
|
||||
|
||||
sendGame (chatId, gameName, extra) {
|
||||
return this.callApi('sendGame', Object.assign({ chat_id: chatId, game_short_name: gameName }, extra))
|
||||
return this.callApi('sendGame', { chat_id: chatId, game_short_name: gameName, ...extra })
|
||||
}
|
||||
|
||||
sendMediaGroup (chatId, media, extra) {
|
||||
return this.callApi('sendMediaGroup', Object.assign({ chat_id: chatId, media }, extra))
|
||||
return this.callApi('sendMediaGroup', { chat_id: chatId, media, ...extra })
|
||||
}
|
||||
|
||||
sendPoll (chatId, question, options, extra) {
|
||||
return this.callApi('sendPoll', Object.assign({ chat_id: chatId, question, options }, extra))
|
||||
return this.callApi('sendPoll', { chat_id: chatId, type: 'regular', question, options, ...extra })
|
||||
}
|
||||
|
||||
sendQuiz (chatId, question, options, extra) {
|
||||
return this.callApi('sendPoll', { chat_id: chatId, type: 'quiz', question, options, ...extra })
|
||||
}
|
||||
|
||||
stopPoll (chatId, messageId, extra) {
|
||||
return this.callApi('stopPoll', Object.assign({ chat_id: chatId, message_id: messageId }, extra))
|
||||
return this.callApi('stopPoll', { chat_id: chatId, message_id: messageId, ...extra })
|
||||
}
|
||||
|
||||
getChat (chatId) {
|
||||
@@ -175,7 +180,7 @@ class Telegram extends ApiClient {
|
||||
}
|
||||
|
||||
answerInlineQuery (inlineQueryId, results, extra) {
|
||||
return this.callApi('answerInlineQuery', Object.assign({ inline_query_id: inlineQueryId, results: JSON.stringify(results) }, extra))
|
||||
return this.callApi('answerInlineQuery', { inline_query_id: inlineQueryId, results, ...extra })
|
||||
}
|
||||
|
||||
setChatPermissions (chatId, permissions) {
|
||||
@@ -187,11 +192,15 @@ class Telegram extends ApiClient {
|
||||
}
|
||||
|
||||
promoteChatMember (chatId, userId, extra) {
|
||||
return this.callApi('promoteChatMember', Object.assign({ chat_id: chatId, user_id: userId }, extra))
|
||||
return this.callApi('promoteChatMember', { chat_id: chatId, user_id: userId, ...extra })
|
||||
}
|
||||
|
||||
restrictChatMember (chatId, userId, extra) {
|
||||
return this.callApi('restrictChatMember', Object.assign({ chat_id: chatId, user_id: userId }, extra))
|
||||
return this.callApi('restrictChatMember', { chat_id: chatId, user_id: userId, ...extra })
|
||||
}
|
||||
|
||||
setChatAdministratorCustomTitle (chatId, userId, title) {
|
||||
return this.callApi('setChatAdministratorCustomTitle', { chat_id: chatId, user_id: userId, custom_title: title })
|
||||
}
|
||||
|
||||
exportChatInviteLink (chatId) {
|
||||
@@ -199,7 +208,7 @@ class Telegram extends ApiClient {
|
||||
}
|
||||
|
||||
setChatPhoto (chatId, photo) {
|
||||
return this.callApi('setChatPhoto', { chat_id: chatId, photo: photo })
|
||||
return this.callApi('setChatPhoto', { chat_id: chatId, photo })
|
||||
}
|
||||
|
||||
deleteChatPhoto (chatId) {
|
||||
@@ -207,15 +216,15 @@ class Telegram extends ApiClient {
|
||||
}
|
||||
|
||||
setChatTitle (chatId, title) {
|
||||
return this.callApi('setChatTitle', { chat_id: chatId, title: title })
|
||||
return this.callApi('setChatTitle', { chat_id: chatId, title })
|
||||
}
|
||||
|
||||
setChatDescription (chatId, description) {
|
||||
return this.callApi('setChatDescription', { chat_id: chatId, description: description })
|
||||
return this.callApi('setChatDescription', { chat_id: chatId, description })
|
||||
}
|
||||
|
||||
pinChatMessage (chatId, messageId, extra) {
|
||||
return this.callApi('pinChatMessage', Object.assign({ chat_id: chatId, message_id: messageId }, extra))
|
||||
return this.callApi('pinChatMessage', { chat_id: chatId, message_id: messageId, ...extra })
|
||||
}
|
||||
|
||||
unpinChatMessage (chatId) {
|
||||
@@ -230,35 +239,26 @@ class Telegram extends ApiClient {
|
||||
return this.callApi('unbanChatMember', { chat_id: chatId, user_id: userId })
|
||||
}
|
||||
|
||||
answerCallbackQuery (callbackQueryId, text, url, showAlert, cacheTime) {
|
||||
return this.callApi('answerCallbackQuery', {
|
||||
callback_query_id: callbackQueryId,
|
||||
text: text,
|
||||
url: url,
|
||||
show_alert: showAlert,
|
||||
cache_time: cacheTime
|
||||
})
|
||||
}
|
||||
|
||||
answerCbQuery (callbackQueryId, text, showAlert, extra) {
|
||||
return this.callApi('answerCallbackQuery', Object.assign({
|
||||
return this.callApi('answerCallbackQuery', {
|
||||
text,
|
||||
show_alert: showAlert,
|
||||
callback_query_id: callbackQueryId,
|
||||
text: text,
|
||||
show_alert: showAlert
|
||||
}, extra))
|
||||
...extra
|
||||
})
|
||||
}
|
||||
|
||||
answerGameQuery (callbackQueryId, url) {
|
||||
return this.callApi('answerCallbackQuery', {
|
||||
callback_query_id: callbackQueryId,
|
||||
url: url
|
||||
url,
|
||||
callback_query_id: callbackQueryId
|
||||
})
|
||||
}
|
||||
|
||||
answerShippingQuery (shippingQueryId, ok, shippingOptions, errorMessage) {
|
||||
return this.callApi('answerShippingQuery', {
|
||||
ok,
|
||||
shipping_query_id: shippingQueryId,
|
||||
ok: ok,
|
||||
shipping_options: shippingOptions,
|
||||
error_message: errorMessage
|
||||
})
|
||||
@@ -266,27 +266,28 @@ class Telegram extends ApiClient {
|
||||
|
||||
answerPreCheckoutQuery (preCheckoutQueryId, ok, errorMessage) {
|
||||
return this.callApi('answerPreCheckoutQuery', {
|
||||
ok,
|
||||
pre_checkout_query_id: preCheckoutQueryId,
|
||||
ok: ok,
|
||||
error_message: errorMessage
|
||||
})
|
||||
}
|
||||
|
||||
editMessageText (chatId, messageId, inlineMessageId, text, extra) {
|
||||
return this.callApi('editMessageText', Object.assign({
|
||||
return this.callApi('editMessageText', {
|
||||
text,
|
||||
chat_id: chatId,
|
||||
message_id: messageId,
|
||||
inline_message_id: inlineMessageId,
|
||||
text: text
|
||||
}, extra))
|
||||
...extra
|
||||
})
|
||||
}
|
||||
|
||||
editMessageCaption (chatId, messageId, inlineMessageId, caption, extra = {}) {
|
||||
return this.callApi('editMessageCaption', {
|
||||
caption,
|
||||
chat_id: chatId,
|
||||
message_id: messageId,
|
||||
inline_message_id: inlineMessageId,
|
||||
caption: caption,
|
||||
parse_mode: extra.parse_mode,
|
||||
reply_markup: extra.parse_mode || extra.reply_markup ? extra.reply_markup : extra
|
||||
})
|
||||
@@ -297,7 +298,7 @@ class Telegram extends ApiClient {
|
||||
chat_id: chatId,
|
||||
message_id: messageId,
|
||||
inline_message_id: inlineMessageId,
|
||||
media: Object.assign(media, { parse_mode: extra.parse_mode }),
|
||||
media: { ...media, parse_mode: extra.parse_mode },
|
||||
reply_markup: extra.reply_markup ? extra.reply_markup : extra
|
||||
})
|
||||
}
|
||||
@@ -349,8 +350,8 @@ class Telegram extends ApiClient {
|
||||
return this.callApi('deleteChatStickerSet', { chat_id: chatId })
|
||||
}
|
||||
|
||||
getStickerSet (setName) {
|
||||
return this.callApi('getStickerSet', { name: setName })
|
||||
getStickerSet (name) {
|
||||
return this.callApi('getStickerSet', { name })
|
||||
}
|
||||
|
||||
uploadStickerFile (ownerId, stickerFile) {
|
||||
@@ -361,30 +362,39 @@ class Telegram extends ApiClient {
|
||||
}
|
||||
|
||||
createNewStickerSet (ownerId, name, title, stickerData) {
|
||||
return this.callApi('createNewStickerSet', Object.assign({
|
||||
return this.callApi('createNewStickerSet', {
|
||||
name,
|
||||
title,
|
||||
user_id: ownerId,
|
||||
name: name,
|
||||
title: title
|
||||
}, stickerData))
|
||||
...stickerData
|
||||
})
|
||||
}
|
||||
|
||||
addStickerToSet (ownerId, name, stickerData, isMasks) {
|
||||
return this.callApi('addStickerToSet', Object.assign({
|
||||
return this.callApi('addStickerToSet', {
|
||||
name,
|
||||
user_id: ownerId,
|
||||
name: name,
|
||||
is_masks: isMasks
|
||||
}, stickerData))
|
||||
is_masks: isMasks,
|
||||
...stickerData
|
||||
})
|
||||
}
|
||||
|
||||
setStickerPositionInSet (sticker, position) {
|
||||
return this.callApi('setStickerPositionInSet', {
|
||||
sticker: sticker,
|
||||
position: position
|
||||
sticker,
|
||||
position
|
||||
})
|
||||
}
|
||||
|
||||
deleteStickerFromSet (sticker) {
|
||||
return this.callApi('deleteStickerFromSet', { sticker: sticker })
|
||||
return this.callApi('deleteStickerFromSet', { sticker })
|
||||
}
|
||||
|
||||
setPassportDataErrors (userId, errors) {
|
||||
return this.callApi('setPassportDataErrors', {
|
||||
user_id: userId,
|
||||
errors: errors
|
||||
})
|
||||
}
|
||||
|
||||
sendCopy (chatId, message, extra) {
|
||||
@@ -395,11 +405,13 @@ class Telegram extends ApiClient {
|
||||
if (!type) {
|
||||
throw new Error('Unsupported message type')
|
||||
}
|
||||
const opts = Object.assign({ chat_id: chatId }, replicators[type](message), extra)
|
||||
const opts = {
|
||||
chat_id: chatId,
|
||||
...replicators[type](message),
|
||||
...extra
|
||||
}
|
||||
return this.callApi(replicators.copyMethods[type], opts)
|
||||
}
|
||||
}
|
||||
|
||||
Telegram.prototype.answerCallbackQuery = util.deprecate(Telegram.prototype.answerCallbackQuery, '️⚠️ Telegraf: answerCallbackQuery() is deprecated, use answerCbQuery() instead')
|
||||
|
||||
module.exports = Telegram
|
||||
Reference in new issue
Block a user