User database logic in node-telegram-bot-api

114 Views Asked by At

I am making tg bot with Firebase for students of our college, which will send notifications from Learning Management System, when our homework ready-to-do. It was pretty easy to make parser for LMS using Puppeteer and push it to Firebase, but for me it's pretty hard to understand how Firebase works.

In Firebase I have one DB with two collections, which is Assignments and Users, for now there are only Assignments collection.

class Firebase {
  static id = 0;

  constructor(config) {
    const app = initializeApp(config.firebaseConfig.firebase);
    this.db = getDatabase(app);
    this.config = config;
  }

  async auth() {
    try {
      const auth = getAuth();
      const user = await signInWithEmailAndPassword(
        auth,
        this.config.firebaseConfig.auth.email,
        this.config.firebaseConfig.auth.password
      );
      return user;
    } catch (err) {
      throw new Error('User not found!');
    }
  }

  async get(key) {
    const dbRef = ref(getDatabase());
    try {
      const snapshot = await get(child(dbRef, key));
      if (!snapshot.exists()) {
        throw new Error('No data available!');
      }
      return snapshot.val();
    } catch (err) {
      return err;
    }
  }

  set(data, key) {
    set(ref(this.db, `${key}/${id}`), data);
  }

  push(data, key) {
    return push(ref(this.db, key), data).key;
  }

  update(data, key, id) {
    update(ref(this.db, `${key}/${id}`), data);
  }

  remove(key, id) {
    remove(ref(this.db, `${key}/${id}`));
  }

  async getId(data, key) {
    const dbData = await this.get(key);
    const sortedData = sortKeys(data);
    return Object.entries(dbData).find(
      ([, value]) => JSON.stringify(value) === JSON.stringify(sortedData)
    )[0];
  }
}

export default Firebase;

This is my OOP-styled class, for Puppeteer and bot, but I'm not sure about set and remove methods. So, as I understood node-telegram-bot-api, there is only way to make things work is something like this:

const { token } = config;

const firebase = new Firebase(config);
await firebase.auth();

const bot = new TelegramBot(token, {polling: true});

const { prompts, buttons } = telegramTemplates;
const restartSyncTriggers = buttons.start.concat(buttons.restart);

bot.on ('message', async msg => {
  const coll = firebase.get(id);
  const { text, chat }  = msg;  
  const { id } = chat;
  
  if (text === '/start') {
    const startOptions = { parse_mode: "Markdown", disable_web_page_preview: true };
    const startKeyboard = new Keyboard(buttons.start, startOptions);
    firebase.push(id, 'users');
    await bot.sendMessage(id, prompts.start, startKeyboard);
  }; /* Welcome message & adding users tg id to database */

  if (text === '/restart') {
    const restartKeyboard = new Keyboard(buttons.restart);
 
    //Removing whole user from 'Users' Collection
    //Pushing user with same tg id to 'Users' Collection
    //How i think that will work:

    const coll = firebase.get(id);
    firebase.remove('users', id);
    firebase.push('users', id);

    await bot.sendMessage(id, prompts.restart, restartKeyboard);
  } /* Deleting & Creating new User to '/restart' command */

  if (restartSyncTriggers.includes(text)) {
    const courseKeyboard = new Keyboard(buttons.course)
    /* Asking user question for next info */
    await bot.sendMessage(id, prompts.course, courseKeyboard);
  };


  if (buttons.course.includes(text)) {
    if (text === buttons.course[0]) {
      //Set key 'Grade' to 1 if User typed string from keyboard
    } else if (text === buttons.course[1]) {
      //Set key 'Grade' to 2 if User typed another string from keyboard
    }
    const secondDiplomaKeyboard = new Keyboard(buttons.secondDiploma);

    await bot.sendMessage(id, prompts.secondDiploma, secondDiplomaKeyboard);
  }; /* Grade sync */

  if (buttons.secondDiploma.includes(text)) {
    if (text === buttons.secondDiploma[0]) {
      // another push to db
    } else if (text === buttons.secondDiploma[1]) {
      // another push to db
    }
    const registrationKeyboard = new Keyboard(buttons.registration);
    
    await bot.sendMessage(id, prompts.registration, registrationKeyboard);
  }; /* SecondDiploma sync*/

  if(buttons.registration.includes(text)) {
    if(text === buttons.registration[1]) {
      // another push to db
      bot.sendMessage(id, prompts.restart, buttons.restart)
    } else if (text === buttons.registration[0]) {
      // another push to db
      bot.sendMessage(id, prompts.finish, buttons.finish[0])
    }
  } /* Are you sure? Y- go to notify schedule, otherwise /restart*/
});

In each if-statement there is a script which triggers syncing that stuff to DB, I've done this like that because I'm thinking that all of the context on each message to the bot is messing down, so I have to push every key-value of ONE USER instead of collecting all of pairs to the one single USER Object, and pushing it to the Firebase. Maybe it will be easier if I picked Telegraf instead of that API, because most of the correlated guide-videos on YouTube about Telegraf?

Am I doing this whole thing right?

I've tried looking throw all of tg bots written on node-telegram-bot-api, but I haven't find any of solutions to this. All of them were using same if-statements for each thing, or they were something like weather apps, when u just typing in some city. I'm very lost.

0

There are 0 best solutions below