Creating multiple inline buttons for a Telegram bot

I’m trying to make a Telegram bot that shows a list of drinks with their prices. I want to display this as buttons in a single message. Here’s what I’ve got so far:

const drinks = {
  'soda': '1.50',
  'juice': '2.00',
  'water': '1.00'
}

let buttons = []
for (let drink in drinks) {
  buttons.push([{ text: `${drink}: $${drinks[drink]}`, callback_data: drink }])
}

bot.sendMessage(chatId, 'Drink Menu:', {
  reply_markup: {
    inline_keyboard: buttons
  }
})

This code creates buttons, but it’s not quite right. How can I improve it to show all drinks in one message with their prices? Also, is there a better way to structure this data? Any help would be great!

I’ve worked on a similar project before, and I can share some insights. Your approach is on the right track, but you can optimize it further.

Instead of pushing each button as a separate array, you can create a single array of buttons. This will display them inline:

let buttons = Object.entries(drinks).map(([drink, price]) => ({
  text: `${drink}: $${price}`,
  callback_data: drink
}));

bot.sendMessage(chatId, 'Drink Menu:', {
  reply_markup: {
    inline_keyboard: [buttons]
  }
});

This creates a single row of buttons. If you want multiple rows, you can chunk the buttons array.

As for data structure, consider using an array of objects instead:

const drinks = [
  { name: 'soda', price: '1.50' },
  { name: 'juice', price: '2.00' },
  { name: 'water', price: '1.00' }
];

This format is more flexible and easier to work with, especially if you need to add more properties later.

Your approach is sound, but there’s room for improvement. Consider using the map() function for cleaner code:

const buttons = Object.entries(drinks).map(([drink, price]) => ({
  text: `${drink}: $${price}`,
  callback_data: drink
}));

bot.sendMessage(chatId, 'Drink Menu:', {
  reply_markup: { inline_keyboard: [buttons] }
});

This creates a single row of buttons. For multiple rows, you could split the array into chunks of the desired size. Regarding data structure, your current object format works well for this use case. If you need more complex data later, you might consider an array of objects, but for now, keep it simple.

hey there! i’ve done something similar before. you could try this:

const buttons = Object.entries(drinks).map(([d, p]) => ({ text: `${d}: $${p}`, callback_data: d }));

bot.sendMessage(chatId, 'Drink Menu:', { reply_markup: { inline_keyboard: [buttons] } });

this’ll give you a single row of buttons. if you want multiple rows, you can split the buttons array into chunks. hope this helps!