Как стать автором
Обновить

Комментарии 13

Ссылка на gitlab не работает.

Поправил. Спасибо.
Хорошая статья, спасибо! Не сравнивали как использование рефлекта повлияло на производительность приложения? Возможно ли его не использовать вовсе?
Ну замеров никаких, честно говоря не производилось, но ощутимых ухудшений не было замечено. В моем случае только море радости как у меня, так и у игроков. Избежать использования этого пакета не получилось, хоть и искал достаточно. Но инструмент мне очень понравился.
Если кому нужно, для своих ботов написал на Node.js небольшой модуль, который рекурсивно рассылает всем юзерам сообщение в рамках лимитов. Удобно для апдейтов по функционалу.

Жми меня!
/**
 * Used to send messages to all users
 *
 * @module sendout
 * @license MIT
 */

/** Dependencies */

const db = require('./db');

/**
 * Used to send messages to all chats
 * @param {Telegram:Bot} bot Bot that should send messages
 * @param {String} text Text to be sent
 */
function sendAll(bot, text) {
  db.getChats()
    .then((chats) => {
      sendMessage(text, chats, bot, {});
    })
    .catch(/** todo: handle error */);
}

/**
 * Recursive function to send text to an array of chats; please don't use this
 *    function twice at any given point of time. Sends at most 30 messages/sec
 *
 * @param {String} text - Text to be sent
 * @param {[Mongoose:Chat]} chats - Chats to get this message
 * @param  {Telegram:Bot} bot - Bot that should respond
 */
function sendMessage(text, chats, bot, results) {
  if (chats.length <= 0) {
    const keys = Object.keys(results);
    const successKeyIndex = keys.indexOf('success');
    if (successKeyIndex > -1) {
      keys.splice(successKeyIndex, 1);
    }
    let message = `All messages were sent, here are the results:\n\nSuccess: ${results.success || 0}`;

    keys.forEach((key) => {
      message = `${message}\n${key}: ${results[key]}`;
    });

    bot.sendMessage('ваш id', message);
    return;
  }

  /** Get current users and users for the next loop */
  const nextUsers = Object.create(chats);
  const currentUsers = nextUsers.splice(0, 30);
  const resultsCopy = Object.create(results);

  const promises = [];
  currentUsers.forEach((user) => {
    promises.push(new Promise((resolve) => {
      bot.sendMessage(user.id, text, {
        disable_web_page_preview: 'true',
      })
        .then(() => resolve('success'))
        .catch((err) => {
          resolve(String(err.message));
        });
    }));
  });
  Promise.all(promises)
    .then((values) => {
      values.forEach((value) => {
        if (resultsCopy[value]) {
          resultsCopy[value] += 1;
        } else {
          resultsCopy[value] = 1;
        }
      });
      setTimeout(() => {
        sendMessage(text, nextUsers, bot, resultsCopy);
      }, 1500);
    })
    .catch(err => bot.sendMessage('ваш id', err.message));
}

module.exports = {
  sendAll,
};

Я так понимаю, что 30 сообщений в секунду — это лимит на бота в целом, незавимимо от количества пользователей онлайн? А что, если у моего бота 1 млн. человек онлайн, с таким лимитом они будут ждать вечность??

как только у какого-то бота будет 1 млн онлайн, то лимит будет пересмотрен.
Смею вас огорчить, но не будет. Я разработчик бота Etlgr.
Пока не 1млн пользователей, но лимита мы достигли достаточно быстро, ибо сообщения шлются крайне неравномерно, да и еще много групповых чатов.

Вот что ребята из саппорта говорят на подобный запрос:

image

Павел Дуров на личные сообщения не отвечает.
Крайне неприятная ситуация, в общем.
Теперь TDLib релизнулся, там можно подключить уже существующего бота и написать свой слой абстракции. Я так полагаю лимиты там уже гораздо выше и ограничены лимитами MTProto.
Ситуация вдвойне неприятная — лимит для длинных сообщений (1000 букв, например) ещё ниже. Отчасти дело в систематическом бане из-за тестов, но у меня бот не банится только если соблюдается 15 секунд между сообщениями одному и тому же пользователю. Пробовал и на других своих ботах. У меня практически идея бота запорота этим лимитом(
Взгляните в сторону TDLib. Да, это уже не легкий Bot API, но возможности и лимиты там куда шире.
Спасибо большое, посмотрю)
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории