Как обойти лимит Telegram API для групп свыше 10,000 участников

Введение

Здравствуйте! Если вы когда-либо пытались извлечь данные пользователей из крупных телеграм-групп и каналов, вы наверняка знаете о технических сложностях, которые могут возникнуть. В рамках нашего проекта — платформы для спикеров и коучей — мы столкнулись с необходимостью эффективно продвигать наши курсы, используя рекламу в других группах и каналах. Однако далеко не каждый готов предоставить доступ к своему каналу или группе, особенно если предлагаемые темы курсов перекликаются с их собственными.

Для решения этой задачи наша маркетинговая команда разработала трехуровневую партнёрскую программу. Суть программы заключается в том, что владельцы групп, согласные на сотрудничество, получают уникальный идентификатор в нашей системе. Под этим ID регистрируются все новые пользователи, которые, в случае покупки курсов, генерируют вознаграждение для владельца группы.

Эта инициатива казалась нам многообещающей, однако в процессе реализации мы столкнулись с серьёзным ограничением. При попытке загрузить список пользователей из группы на 13,000 человек, система смогла обработать только 10,000. Это ограничение API Telegram значительно усложнило выполнение задуманного плана, требуя от нас дополнительных технических решений.

Решение

В API Telegram channels→getParticipants нашелся параметр поиска 'filter' => ['_' => 'channelParticipantsSearch', 'q' => «Перебираем все символы которые могут быть в логине»]

Пример решения на PHP используем библиотеку MadelineProto

getFullInfo($telegram_group_id);
$participantCount = $groupInfo['full']['participants_count'] ?? 0;
echo "В группе $participantCount пользователей!
"; $allParticipants = []; $limit = 200; if ($participantCount > 10000) { $nextchar = $group['nextchar']; if ($nextchar === '00') { echo "Все символы были обработаны.
"; echo ' '; echo ''; exit; } if ($nextchar === '' || is_null($nextchar)) { $nextchar = 'a'; } $alphabet = array_merge(range('a', 'z'), range('0', '9')); //можно добавить еще символов $currentCharIndex = array_search($nextchar, $alphabet); if ($currentCharIndex === false) { die("Неверное значение nextchar."); } $currentChar = $alphabet[$currentCharIndex]; $offset = 0; do { $response = $MadelineProto->channels->getParticipants([ 'channel' => $telegram_group_id, 'filter' => ['_' => 'channelParticipantsSearch', 'q' => $currentChar], 'offset' => $offset, 'limit' => $limit ]); foreach ($response['participants'] as $participant) { if (!isset($participant['user_id'])) { continue; // Пропускаем текущую итерацию, если ключа нет } $allParticipants[$participant['user_id']] = $participant; } $offset += $limit; } while (count($response['participants']) == $limit); $nextCharIndex = $currentCharIndex + 1; if ($nextCharIndex >= count($alphabet)) { $updateNextChar = '00'; //прошли все символы } else { $updateNextChar = $alphabet[$nextCharIndex]; } // Обновление следующего символа в базе данных $updateQuery = "UPDATE telegram_group SET nextchar = :nextchar WHERE id = :id_telegram_group"; $updateStmt = $currentDb->prepare($updateQuery); $updateStmt->bindParam(':nextchar', $updateNextChar); $updateStmt->bindParam(':id_telegram_group', $id_telegram_group); $updateStmt->execute(); $linkToAdd = strtolower("https://Формируем ссылку для запуска cron на этот скрипт"); //типа INSERT INTO crons (links, active, minuts) VALUES (:link, 1, 5) //убираем задачу если прошли все варианты //if ($updateNextChar === '00') { // Если обработка символов завершена, устанавливаем статус активна в 0 для этой ссылки // $query = " // UPDATE crons SET active = 0 WHERE links = :link // "; // $statement = $db->prepare($query); // $statement->bindParam(':link', $linkToAdd); // $statement->execute(); // } ?>

для того чтобы не создавать большие нагрузки на проект скрипт запускается раз в 5 минут, код успешно прошел испытание и используется в проекте

29fdb89b689a922c87f6f502a369471c.png

Заключение

Надеюсь, что представленное решение проблемы с ограничением API Telegram на обработку данных более чем 10,000 пользователей окажется полезным для Вас. Эта задача, хотя и может показаться сложной на первый взгляд, решается довольно просто.

Habrahabr.ru прочитано 3255 раз