Skip to content

Instantly share code, notes, and snippets.

@hypernova7
Last active September 11, 2023 05:16
Show Gist options
  • Save hypernova7/c8b017931008ffe00c4a8bcc39bfe1b2 to your computer and use it in GitHub Desktop.
Save hypernova7/c8b017931008ffe00c4a8bcc39bfe1b2 to your computer and use it in GitHub Desktop.
Telegraf pagination bot example
/*
Telegraf pagination bot example
by @hypernova7
Dependencies to install: npm i consola telegraf
*/
import consola from 'consola'
import { Telegraf, Markup, session } from 'telegraf'
const bot = new Telegraf('bot-token')
const logger = consola.withTag('pagination-bot')
// Create x amount of chunks with 10 items each
const results = chunk(Array.from({ length: 45 }).fill(0).map((_, i) => i+=1), 10)
// Create pagination buttons with choices
const makeButtons = (choiceButtons) => Markup.inlineKeyboard([
...choiceButtons,
[
Markup.button.callback('Prev', 'prev'),
Markup.button.callback('Next', 'next')
]
])
// Catch Telegraf errors
bot.catch(e => logger.error(e))
bot
.use(session())
.use((ctx, next) => {
ctx.session ??= {} // set session if no exists
return next()
})
bot.command('demo', async ctx => {
// Set page number
ctx.session.page = ctx.session.page || 0
// Show first page results
await ctx.replyWithMarkdownV2(results[ctx.session.page].map(i => `Item: *${i}*`).join('\n'), {
...makeButtons(chunk(results[ctx.session.page].map((_,i) => Markup.button.callback(i + 1, `prefix:${i + 1}`)), 5))
})
}).action(/(prev|next)/, async ctx => {
/* Handler to incremet or decrement page number, and change page */
// Prevent errors when ctx.session.page is undefined
if (typeof ctx.session.page === 'undefined') return ctx.answerCbQuery();
const [, action] = ctx.match
if (action === 'prev') {
// prevent decrement and show alert
if (ctx.session.page === 0) return ctx.answerCbQuery('You are on home page');
ctx.session.page = ctx.session.page - 1; // decrement
}
if (action === 'next') {
// prevent increment and show alert
if ((ctx.session.page + 1) === results.length) return ctx.answerCbQuery('You are on last page');
ctx.session.page = ctx.session.page + 1 // increment
}
await ctx.answerCbQuery()
// Change results
await ctx.editMessageText(results[ctx.session.page].map(i => `Item: *${i}*`).join('\n'), {
...makeButtons(chunk(results[ctx.session.page].map((_,i) => Markup.button.callback(i + 1, `prefix:${i + 1}`)), 5)),
parse_mode: 'MarkdownV2'
})
}).action(/prefix:(\d+)/, async ctx => {
/* Item choice handler */
const [, choice] = ctx.match
await ctx.answerCbQuery()
await ctx.replyWithMarkdownV2(`You chose the item: *${results[ctx.session.page][choice - 1]}*`)
})
function chunk (arr, size) {
return Array.from({ length: Math.ceil(arr.length / size) })
.fill(0)
.map(() => arr.splice(0, size));
}
bot.launch()
@bek-shoyatbek
Copy link

thanks .
I have a question : how can i impliment it in wizard scene?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment