@paulbraam
Начинающий Node.js разработчик

Как получить chat_id из базы данных — Telegram bot?

Привет
Я делаю бота на Telegraf, использую cron для отправки оповещений и mongodb для хранения данных юзеров.
Пытаюсь запустить примерно такой скрипт:

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();
})

Когда я использую db.User.findOne(), получается взять только первого юзера из базы данных.
Также я могу получить нужный chat_id в событии, когда я обращаюсь к ctx.
Вот пример:

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

Подскажите, пожалуйста, решение проблемы. Уже несколько дней с этим мучаюсь.
  • Вопрос задан
  • 1149 просмотров
Пригласить эксперта
Ответы на вопрос 2
@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');
})


Эта функция не видит контекст ctx, т.е. в теории chatid в нее не передается
Ответ написан
@paulbraam Автор вопроса
Начинающий Node.js разработчик
Дмитрий Гололобов, попробовал ваш вариант, работает.
Пытаюсь сделать так, чтобы бот отправлял определённое количество сообщений из БД:

// беру сообщения из бд
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()
 })

Когда юзеры оправляют запрос, то последний, кто начал, подхватывает скрипт, то есть у него приходит следующее сообщение из списка для первого юзера.

Вот ещё один вариант попробовал. Тут плюс, что можно остановить скрипт. Берется список юзеров, которые оправили запрос, и сообщения распределяются между юзерами, то есть если начали одновременно, то из 4 сообщений каждому придет по 2 разных.

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)
})

В обоих вариантах кажется проблема в том, что cron работает для всех юзеров глобально.
Подскажите, пожалуйста, можно как-то запускать скрипт отдельно для каждого chat_id?
Благодарю заранее!
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы