Что получится: скрипт на Python создаёт группу для клиентов — учебную группу, проект, мероприятие. Он настраивает права и фото и добавляет участников. Кого нельзя добавить из-за настроек приватности, тот получает ссылку-приглашение личным сообщением. Обработчик событий держит состав группы в вашей системе актуальным.
createGroup ──► updateGroupSettings ──► setGroupPicture ──► участники по одному
(с первым │
участником) не добавился → ссылка лично
│
groupEvent ◄── вошёл по ссылке, вышел, исключили
Что понадобится
- канал MAX, Telegram или WhatsApp с ключом и переменные
GRATIO_URL,GRATIO_ID,GRATIO_TOKEN; - Python 3.10+,
pip install requests; - фото группы в JPEG —
logo.jpg.
Правила
- Создавать группу можно не чаще раза в 5 минут — иначе
429(too_frequent, в WhatsApp —group_tempo) сRetry-After. В MAX и Telegram групповые методы идут по одному с паузой 2 секунды. - В WhatsApp группу создают с одним участником. Остальных добавляют по одному, не чаще раза в минуту и только тех, кому номер уже писал после привязки, — иначе
addGroupParticipantответитfalseс причинойgroup_tempoилиmember_not_engaged. - Участники, права, название и фото на отказ площадки отвечают
200сfalseи причиной — проверяйте флаг в ответе.createGroupна отказ отвечает обычной ошибкой.
Шаг 1. Создайте группу
Создайте файл group.py:
import os
import time
import requests
BASE = f"{os.environ['GRATIO_URL']}/waInstance{os.environ['GRATIO_ID']}"
TOKEN = os.environ["GRATIO_TOKEN"]
MEMBERS = ["79991234567@c.us", "79997654321@c.us"] # номера или chatId участников
def call(method: str, payload: dict | None = None, files: dict | None = None) -> dict:
url = f"{BASE}/{method}/{TOKEN}"
if files:
r = requests.post(url, data=payload, files=files, timeout=120)
else:
r = requests.post(url, json=payload, timeout=90)
if r.status_code == 429:
time.sleep(int(r.headers.get("Retry-After", 60)))
return call(method, payload, files)
r.raise_for_status()
return r.json()
group = call("createGroup", {"groupName": "3А · Робототехника", "chatIds": MEMBERS[:1]})
chat_id, link = group["chatId"], group["groupInviteLink"]
print("Группа:", chat_id, link)
Вы увидите: Группа: -80040066617372 https://max.ru/join/… и группу в мессенджере с первым участником.
Шаг 2. Права и фото
Участники не добавляют людей и не меняют название и фото — этим управляет ваша система. Допишите:
flags = call("updateGroupSettings", {"chatId": chat_id,
"allowParticipantsAddMembers": False,
"allowParticipantsChangeAvatar": False})
print("Права:", flags)
with open("logo.jpg", "rb") as f:
picture = call("setGroupPicture", {"chatId": chat_id},
files={"file": ("logo.jpg", f, "image/jpeg")})
print("Фото:", picture.get("setGroupPicture"), picture.get("reason", ""))
Вы увидите: Права: {'updateGroupSettings': True} и Фото: True. В Telegram у прав нет «звонить» — такой флаг вернул бы false с unsupported_setting.
Шаг 3. Участники
Добавляем по одному. Не получилось — отправляем ссылку-приглашение личным сообщением:
for member in MEMBERS[1:]:
time.sleep(61) # WhatsApp: один человек в минуту
added = call("addGroupParticipant", {"chatId": chat_id, "participantChatId": member})
if added.get("addParticipant"):
print("Добавлен:", member)
continue
print("Не добавлен:", member, added.get("reason"))
call("sendMessage", {"chatId": member,
"message": f"Приглашаем в группу «3А · Робототехника»: {link}",
"clientMessageId": f"invite-{chat_id}-{member}"})
Вы увидите для каждого — «Добавлен» или «Не добавлен … privacy_restricted» и приглашение у этого человека.
Шаг 4. Приветствие
call("sendMessage", {"chatId": chat_id,
"message": "Добро пожаловать! Здесь будут расписание и новости группы.",
"clientMessageId": f"welcome-{chat_id}"})
Шаг 5. Следите за составом
Кто вошёл по ссылке, вышел или был исключён — приходит уведомлением groupEvent. Подключите обработчик к своей очереди или вебхуку:
members: dict[str, set[str]] = {} # в работе — таблица в вашей базе
def on_group_event(body: dict) -> None:
group_id = body["chatId"]
people = {p["chatId"] for p in body["participants"]}
current = members.setdefault(group_id, set())
event = body["event"]
if event in ("groupCreated", "participantAdded", "participantJoinedByLink"):
current |= people
elif event in ("participantRemoved", "participantLeft"):
current -= people
if body["self"] and event in ("participantRemoved", "groupDeleted"):
print("Номер канала больше не в группе", group_id) # пометить группу недоступной
print(event, group_id, sorted(current))
Вы увидите при входе человека по ссылке: participantJoinedByLink -80040066617372 [...]. События групп есть в MAX и Telegram. В WhatsApp состав проверяйте методом getGroupData.
Шаг 6. Закройте группу
Когда группа больше не нужна, выйдите из неё — leaveGroup. В WhatsApp есть deleteGroup: номер-админ убирает всех участников и выходит.
Что дальше
- Все поля событий групп — groupEvent.
- Сбросить ссылку-приглашение, если она утекла, — revokeInviteLink.
- Назначить администратора из сотрудников — setGroupAdmin.
