P
P
Pasha2020-05-03 01:37:48
MongoDB
Pasha, 2020-05-03 01:37:48

How to get chat_id from database - Telegram bot?

Hi
I'm making a bot on Telegraf, I use cronit to send alerts and mongodbstore user data.
I'm trying to run a script like this:

const CronJob = require('cron').CronJob;

const job = new CronJob('*/5 * * * * *', async function() {
    const user = await db.User.findOne({chat_id: ctx.chat.id});
    await bot.telegram.sendMessage(user.chat_id, 'Hello World');
})

bot.command('launch', async (ctx) => {
  job.start()
})

bot.command('stop', async (ctx) => {
  job.stop();
})

When I use db.User.findOne(), it turns out to take only the first user from the database.
Also I can get the desired one chat_idin the event when I access the ctx.
Here is an example:

bot.command('launch', async (ctx) => {
  const user = await db.User.findOne({chat_id: ctx.chat.id});
  console.log(user.chat_id)
})

Please tell me the solution to the problem. I've been suffering with this for several days now.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
D
Dmitry Gololobov, 2020-05-03
@dGololobov

const job = new CronJob('*/5 * * * * *', async function() {
    const user = await db.User.findOne({chat_id: ctx.chat.id});
    await bot.telegram.sendMessage(user.chat_id, 'Hello World');
})

This function does not see the ctx context , i.e. in theory, chatid is not transferred to it

P
Pasha, 2020-05-03
@paulbraam

Dmitry Gololobov , I tried your version, it works.
I'm trying to make the bot send a certain number of messages from the database:

// беру сообщения из бд
const messages = data.get('messages')
    .map('message')
    .value();

let i=0;

const CronJob = require('cron').CronJob;

const createJob = async function(chatid) {
  return new CronJob('*/15 * * * * *', async function() {
    const user = await db.User.findOne({chat_id: chatid});
    await bot.telegram.sendMessage(user.chat_id, messages[i]);
    console.log('Job running');
    i++;
 });
 }
 
 bot.command('launch', async (ctx) => {
   const myNewJob = await createJob(ctx.chat.id)
   await bot.telegram.sendMessage(ctx.chat.id, `Let's start`);
   myNewJob.start()
 })

When users send a request, the last one who started picks up the script, that is, he receives the next message from the list for the first user.
Here's another option I tried. Here plus that it is possible to stop a script. A list of users who sent a request is taken, and messages are distributed among users, that is, if they started at the same time, then out of 4 messages, each will receive 2 different ones.
const messages = data.get('messages')
    .map('message')
    .value();

const CronJob = require('cron').CronJob;

const usersToNotify = []

let i=0;

const job = new CronJob('*/15 * * * * *', async function() {
  for await (const user of usersToNotify) {
    await bot.telegram.sendMessage(user, messages[i]);
    i++;
    if (messages.length == i) {
      job.stop();
      }
}
})

job.start()

bot.command('launch', async (ctx) => {
  const User = await db.User.findOne({chat_id: ctx.chat.id});
  usersToNotify.push(User.chat_id)
})

bot.command('stop', async (ctx) => {
  const User = await db.User.findOne({chat_id: ctx.chat.id});
  const index = usersToNotify.findIndex(value => value === User.chat_id)
  usersToNotify.splice(index,1)
})

In both options, the problem seems to be that it cronworks for all users globally.
Tell me, please, can I somehow run the script separately for each chat_id?
Thanks in advance!

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question