Telegraf.js pass data from button to a function that handle a WizardScene

2.2k Views Asked by At

I need to pass some data retrieved from a Database.

When i click into a button i send a private message to the user who have cliecked. I need to pass some datas from that button, to the message sent. Because, into that message i have an other button that starts a WizardScene. SO how can i do to pass data? Thank you.

Here is my code.

This is into a function that post a photo with a description and with a callbackup button.

my function() {
...
let productId = //obtain from a db;
await bot.telegram.sendPhoto(
      channel_id,
      { source: filepath },
      {
        caption: description.join("\n"),
        parse_mode: 'MarkdownV2',
        reply_markup: productButtons.reply_markup
      }
    )
  return productId;
...}

and the button is:

const productButtons = Extra.markup((m) =>
  m.inlineKeyboard([
    [m.callbackButton('TEST', 'test_btn')],
  ])
)

when someone clicsk on it, it sends a message on a private user with this:

bot.action('testa_btn', (ctx) => {
    console.log('testa')
    let text = `My text about ${productId}`

    ctx.telegram.sendMessage(ctx.from.id, o_functions.escapeReplace(text), {
      parse_mode: 'MarkdownV2',
      reply_markup: startBtn.reply_markup
    })
    
  });

this sends a text where i need to write my productid, and an other button where i start my wizard scene:

const startBtn = Extra.markup((m) =>
  m.inlineKeyboard([
    [m.callbackButton('START', 'start_btn_wizard')],
  ])
);

bot.action('start_btn_wizard', (ctx) => {
    return ctx.scene.enter('super-wizard');
  })

So how can i pass my productId variable, first to the button TEST, then to the wizard scene? I need to use it on the Wizard on the user dialogue.

THank you

1

There are 1 best solutions below

2
On

You need to do a couple of things to pass data from a callback button to a handler and then towards a wizard scene.

  1. Add the desired data to the button. Notice how I attached the product Id to the callback data.

    const startBtn = Extra.markup((m) =>
      m.inlineKeyboard([
        [m.callbackButton('START', `start_btn_wizard_${product_id}`)],
      ])
    );
    
  2. Receive the button callback using a regex rather than using a literal string and extract the product ID from the callback data.

    bot.action(/start_btn_wizard_+/, (ctx) => {
        let product_id = ctx.match.input.substring(17);
    
        // add all necessary validations for the product_id here
        return ctx.scene.enter('super-wizard');
    });
    
  3. Pass the acquired id to the wizard scene and extract it again from inside the scene using ctx.scene.state.

    bot.action(/start_btn_wizard_+/, (ctx) => {
        let product_id = ctx.match.input.substring(17);
    
        // add all necessary validations for the product_id here
        return ctx.scene.enter('super-wizard', {product_id: product_id});
    });
    

From inside the wizard, you can access the product_id using ctx.scene.state.product_id.

Hope this helps someone even though it's probably too late for the OP