Бот для рассылки кружков по чатам
Traffic Cardinal Traffic Cardinal  написал 19.09.2025

Бот для рассылки кружков по чатам

Traffic Cardinal Traffic Cardinal  написал 19.09.2025
11 мин
0
28
Содержание

Кружки Иванова — это отдельный вид искусства. Вот только тех, кто способен подобное повторить, единицы. Оно и понятно, ведь спамить в каждый отдельный чат ручками — тот еще адище.

Впрочем, о тех, кто все же делает это вручную, не хочется даже и говорить… С другой стороны, у них ведь не было нашего бота, который возьмет на себя всю рутину и сделает твой спам кружками таким же весомым, как у Е. Ю.

Ты можешь так же! :D
Ты можешь так же! :D

Какие задачи решает бот для рассылки кружков по чатам

Внезапно, но основная задача, которую решает бот для рассылки кружков по чатам, — рассылка кружков по чатам. Собственно говоря, с технической точки зрения он больше никаких задач и не решает (ну, кроме обеспечения скрытности действий при привязке чата к боту, но говорить об одной-единственной функции как о фиче для решения задач — как будто бы не совсем уместно).

Как бы там ни было, путем обеспечения реализации своей основной задачи бот также может способствовать решению следующих задач:

  • Прокачка личного бренда — если мелькать лицом в каждом чате, тебя неизбежно запомнят.

  • Оперативное распространение инфоповода — на удивление, кто-то все эти кружки смотрит (но это не точно).

  • Нативная реклама — здесь все зависит от фантазии. Самое банальное — просто надеть мерч рекла и задвигать что-то свое по сабжу чата.

  • Повышение активности в чате — будучи элементом интерактива, кружки могут повысить вовлеченность в обсуждение.

  • Сведение активности в чате на ноль — а могут и убить любой актив. В особенности если спамить ими каждый день или вообще — после каждого «не кружка». Сотни мертвых аффилиат-чатов, где, кроме кружков Е. Ю., ничего нет — лучшее тому подтверждение.

А вообще, все упирается лишь в фантазию. Лопатой, знаете ли, тоже не только копать можно.

Нативная реклама в кружках
Нативная реклама в кружках

Принцип работы бота для рассылки кружков по чатам

Алгоритмически бот реализован на user-api. Банально потому, что в противном случае кружки будет рассылать не ваш профиль, а профиль бота с припиской «бот». А оно вам надо? Да и в чужой чат бота не добавишь. А пользовательский профиль — хоть тыщу раз. Сама логика же реализована следующим образом:

  1. Бот постоянно слушает эфир, игнорируя любые сообщения, кроме исходящих от аккаунта, к которому он подвязан.
  2. Игнорирует ввод команд в любом месте, кроме «Избранного».
  3. При вводе команды /add — добавляет чат в список.
  4. При вводе команды /del — удаляет чат из списка.
  5. При вводе команды /clear — очищает список.
  6. При вводе команды /list — выводит список списков.
  7. В случае если синтаксис или условия выполнения вводимой команды не соблюдены — оповещает юзера об этом, уточняя, что нужно сделать, чтоб все работало.
  8. В случае отсутствия указания списка в синтаксисе команды — производит текущую манипуляцию со списком default.
  9. В случае отсутствия указания ID чата, но при наличии пересланного от имени этого чата сообщения в сообщения с вводимой командой, — автоматически его подставляет.
  10. При вводе команды /go делает рассылку выбранного кружка.
  11. При вводе сообщений (не путать с командой) «йоу!» в ЛЮБОМ чате — автоматически добавляет этот в список default (сделано для добавления тех чатов, где от имени чата ничего не пишется).
  12. При вводе сообщений (не путать с командой) «йоу2» в ЛЮБОМ чате — создает сообщение с id этого чата в «Избранном» (сделано для обеспечения возможности разделения чатов, где от имени чата ничего не пишется, по разным спискам).

* Триггерные фразы «йоу!» и «йоу2» рекомендуется заменить. Мы специально оставили их нарочито неорганичными, чтобы потенциальные пользователи бота заменяли стандартный вариант, а не спамили одинаковыми сообщениями (хотя если начнется массовое йоу2, то автор кнш покекает…) и не палились друг перед другом.

Мало кто знает, но «йоу» на английском — это qje!
Мало кто знает, но «йоу» на английском — это qje!

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

Данный бот полностью реализован через user_api, поэтому вместо привычного BotFather у нас здесь авторизация через веб-версию Телеги для разрабов. Собственно:

  1. Открываем веб-версию.
  2. Находим и жамкаем по «API development tools», заполняем анкету.
  3. Копипастим куда-то api_id и api_hash.

Затем нам нужен сервер. Гайд, как развернуть собственный, вот здесь. Но в целом подойдет любой, который поддерживает Python. Также сервер нужно настроить, для этого вводим в его консоли:

pip install telethon

Далее

1. В корневой директории сервера создаем bot.py

2. Открываем его текстовым редактором и вводим:

import json

import os

from telethon import TelegramClient, events

api_id = ВАШ АПИ ИД

api_hash = 'ВАШ АПИ ХЭШ'

phone_number = 'ВАШ ТЕЛЕФОН'

DATA_FILE = "chats.json"

YO_WORD_ADD = "йоу!"

YO_WORD_SHOW = "йоу2"

if os.path.exists(DATA_FILE):

with open(DATA_FILE, "r", encoding="utf-8") as f:

chat_lists = json.load(f)

else:

chat_lists = {"default": []}

client = TelegramClient("circle_forwarder", api_id, api_hash)

def save_data():

with open(DATA_FILE, "w", encoding="utf-8") as f:

json.dump(chat_lists, f, ensure_ascii=False, indent=2)

async def resolve_chat(ref):

try:

entity = await client.get_entity(ref)

return entity

except Exception as e:

print(f"Ошибка при получении entity {ref}: {e}")

return None

@client.on(events.NewMessage)

async def handler(event):

text = (event.text or "").strip()

me = await client.get_me()

if event.sender_id != me.id:

return

if text == YO_WORD_ADD:

chat = await event.get_chat()

if chat.id not in chat_lists["default"]:

chat_lists["default"].append(chat.id)

save_data()

await client.send_message("me", f"✅ Чат {getattr(chat,'title',chat.id)} автоматически добавлен в default")

return

elif text == YO_WORD_SHOW:

chat = await event.get_chat()

await client.send_message("me", f"Чат: {getattr(chat,'title',chat.id)}, id:")

await client.send_message("me", f"{chat.id}")

return

if text.startswith("/add"):

parts = text.split(maxsplit=2)

list_name = "default"

if len(parts) == 3:

list_name = parts[2].strip()

if list_name not in chat_lists:

chat_lists[list_name] = []

chat_id = None

if event.is_reply:

reply = await event.get_reply_message()

if reply.forward and reply.forward.chat:

chat_id = reply.forward.chat.id

else:

try:

chat_id = int(reply.text.strip())

except:

await client.send_message("me", "Неверный формат. Ответьте на репост или на сообщение с ID")

return

else:

if len(parts) >= 2:

ref = parts[1].strip()

try:

entity = await resolve_chat(ref)

chat_id = entity.id if entity else int(ref)

except:

await client.send_message("me", "Неверный формат id/username")

return

else:

await client.send_message("me", "Используй: /add <id|username> [список] или ответом на репост/сообщение с id")

return

if chat_id not in chat_lists[list_name]:

chat_lists[list_name].append(chat_id)

save_data()

await client.send_message("me", f"✅ Добавлен чат в список '{list_name}': {chat_id}")

else:

await client.send_message("me", f"Этот чат уже есть в списке '{list_name}'")

elif text == "/list":

if not chat_lists:

await client.send_message("me", "Списки пусты ❌")

return

msg = "📋 Текущие списки:\n\n"

for lst, chats in chat_lists.items():

msg += f"🔹 {lst}:\n"

if chats:

for cid in chats:

try:

entity = await client.get_entity(cid)

title = getattr(entity, 'title', getattr(entity, 'first_name', str(cid)))

msg += f" • {title} (id: {cid})\n"

except:

msg += f" • {cid}\n"

else:

msg += " (пусто)\n"

await client.send_message("me", msg)

elif text.startswith("/clear"):

parts = text.split(maxsplit=1)

if len(parts) == 2:

list_name = parts[1].strip()

if list_name in chat_lists:

chat_lists[list_name] = []

save_data()

await client.send_message("me", f"🧹 Список '{list_name}' очищен")

else:

await client.send_message("me", "Такого списка нет")

else:

await client.send_message("me", "Используй: /clear <имя_списка>")

elif text.startswith("/del"):

parts = text.split(maxsplit=2)

list_name = parts[2].strip() if len(parts) == 3 else "default"

if list_name not in chat_lists:

await client.send_message("me", "Такого списка нет")

return

chat_id = None

if event.is_reply:

reply = await event.get_reply_message()

if reply.forward and reply.forward.chat:

chat_id = reply.forward.chat.id

else:

try:

chat_id = int(reply.text.strip())

except:

await client.send_message("me", "Ответьте на репост или сообщение с id")

return

else:

if len(parts) >= 2:

ref = parts[1].strip()

try:

entity = await resolve_chat(ref)

chat_id = entity.id if entity else int(ref)

except:

await client.send_message("me", "Неверный формат id/username")

return

else:

await client.send_message("me", "Используй: /del <id|username> [список] или ответом на репост/сообщение с id")

return

if chat_id in chat_lists[list_name]:

chat_lists[list_name].remove(chat_id)

save_data()

await client.send_message("me", f"❌ Удалён {chat_id} из списка {list_name}")

else:

await client.send_message("me", "Такого чата нет в списке")

elif text.startswith("/go") and event.is_reply:

parts = text.split(maxsplit=1)

list_name = parts[1].strip() if len(parts) == 2 else "default"

if list_name not in chat_lists or not chat_lists[list_name]:

await client.send_message("me", f"Список '{list_name}' пуст ❌")

return

reply_msg = await event.get_reply_message()

if reply_msg.video_note:

for cid in chat_lists[list_name]:

try:

await client.send_file(cid, file=reply_msg.video_note, caption=reply_msg.text or "")

print(f"Отправлено в {cid}")

except Exception as e:

print(f"Ошибка при отправке в {cid}: {e}")

await client.send_message("me", f"✅ Кружок разослан в список '{list_name}'")

else:

await client.send_message("me", "Это не кружок 🤔")

print("Запуск...")

client.start()

client.run_until_disconnected()

3. Заменяем ВАШ АПИ ИД, ВАШ АПИ ХЭШ, и ВАШ ТЕЛЕФОН на свои.

4. Опционально заменяем фразы йоу! и йоу2 на свои фразы. На работу бота не влияет, но настоятельно советуем так сделать.

5. Сохраняем.

6. Вводим в консоль python bot.py.

7. Проверяем работоспособность.

Демонстрация работы

Демонстрация работы добавления как напрямую, так и через указание ID
Демонстрация работы добавления как напрямую, так и через указание ID

Демонстрация работы функционала управления списками
Демонстрация работы функционала управления списками

Продолжение демонстрации работы функционала управления списками + демонстрация работы рассылки кружков
Продолжение демонстрации работы функционала управления списками + демонстрация работы рассылки кружков

Все работает
Все работает

Подводя итоги

Как видите, спамить кружками, как Иванов, не так уж и сложно. И для этого даже не нужно марать руки. Всего-то и нужно было быть подписанным на нашу Телегу, чтобы вовремя заметить анонс этой статьи. С чем мы вас и поздравляем!

Здравствуйте! У вас включен блокировщик рекламы, часть сайта не будет работать!