0

Context: Building a simple telegram bot to allow me to check on model and year of cars available on a garage. It should show a ReplyKeyboard with available Brands. Upon tapping on a Brand, it should update to a new ReplyKeyboard, now with all available models of such Brand.

I've already built a single table database, a connection.js, a driver.js, a .env and the index.js files, all working fine.

This is my bot structure.

Table: GARAGE

|     Brand   |     Model    |   Year   |
| ----------- | ------------ | -------- |
|   Ferrari   |     Roma     |   2021   |
|   Pagani    |     Zonda    |   2018   |
| Lamborghini |   Aventador  |   2020   |
|  Maserati   | Quattroporte |   2015   |

.env

TELEGRAM_BOT_TOKEN="my-bot-token"
MYSQL_DATABASE="cargarage"
MYSQL_USER="root"
MYSQL_PASSWORD="pswrd"
MYSQL_HOST="localhost"

connection.js

const mysql = require("mysql");
    
module.exports = mysql.createPool({
host: process.env.MYSQL_HOST,
user: process.env.MYSQL_USER,
password: process.env.MYSQL_PASSWORD,
database: process.env.MYSQL_DATABASE,
});

driver.js

brands() {
        return new Promise((resolve, reject) => {
            connection.query(`select distinct Brand from GARAGE`,
            (err, result) => {
                if (err) reject(err);
                else resolve(result);
            });
    });
},

models(SBrand) {
    return new Promise((resolve, reject) => {
        connection.query(`select distinct Model from GARAGE where Brand = ?`,
        [SBrand],
        (err, result) => {
            if (err) reject(err);
            else resolve(result);
        });
});
},

(I'm stuck in here because i don't know how to bring brands and models I'm selecting on driver.js, into the keyboard buttons)

index.js

require("dotenv").config();
const TelegramBot = require('node-telegram-bot-api');
const driver = require('./driver');
const token = process.env.TELEGRAM_BOT_TOKEN;
const bot = new TelegramBot(token, { polling: true });

bot.onText(new RegExp('\/start'), async (msg) => {
    const chatId = msg.chat.id;
    const UserName = msg.from.first_name;
    bot.sendMessage(chatId, "Hi, " + UserName + "." + "\n\nPlease, choose a brand.\n\n"
); 

If i'd manually create the static keyboard, it'd look like this, but i need it to auto update as the database grows over time:

{"reply_markup": {
    "one_time_keyboard": true,
    "resize_keyboard": true,
    "keyboard": [
        [{text: "Ferrari",
          callback_data: "Ferrari"}, 
          {text: "Pagani",
          callback_data: "Pagani",}],
        [{text: "Lamborghini",
          callback_data: "Lamborghini"}, 
          {text: "Maserati",
          callback_data: "Maserati"}]
    ]}
}

This is my first question online ever. Hope you guys can help me out a bit.

Update

Tried this, as suggested by @anton-trofymenko and i'm not getting errors, but keyboard still won't show.

const reply_markup = {
        'reply_markup': {
          'one_time_keyboard': true, 
          'resize_keyboard': true, 
          'keyboard': Marca.map(Marca => ({text: Marca, callback_data: Marca,}))}

Getting this from console.log(reply_markup);

{
  reply_markup: {
    one_time_keyboard: true,
    resize_keyboard: true,
    keyboard: [
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object]
    ]
  }
}
Francisco
  • 1
  • 2

1 Answers1

0

Basically, if you want to add an inline keyboard to a message you should add addreply_markup to the query of HTTP GET request. You use some library to create such requests and I don't know which library you use here const bot = new TelegramBot(token, { polling: true }); but anyway you can pass reply_markup to method sendMessage somehow. To generate a new reply_markup keyboard, for example for car brands, you can do something like this

const brands = await brands()
const reply_markup = {
      keyboard: brands.map(brand => ({text: brand, callback_data: brand})),
      one_time_keyboard: true,
      resize_keyboard: true,
}

and then pass the reply_markup into the sendMessage.

Tyler2P
  • 2,324
  • 26
  • 22
  • 31
  • Thanks a lot, Anton. Seems to be the right approach. After trying with several ways of implementing it, i'm not getting errors, but keyboard still won't show. – Francisco Dec 19 '22 at 14:17
  • Try this callback for map `brand => [{text: brand, callback_data: brand}]` If it won’t work, please tell which nodejs library you are using to create the bot instance. – Anton Trofymenko Dec 20 '22 at 15:13