__version__ = (2, 0, 0)
# ©️ Dan Gazizullin, 2021-2023
# This file is a part of Hikka Userbot
# Code is licensed under CC-BY-NC-ND 4.0 unless otherwise specified.
# 🌐 https://github.com/hikariatama/Hikka
# 🔑 https://creativecommons.org/licenses/by-nc-nd/4.0/
# + attribution
# + non-commercial
# + no-derivatives
# You CANNOT edit this file without direct permission from the author.
# You can redistribute this file without any changes.
# meta pic: https://static.dan.tatar/tagall_icon.png
# meta developer: @hikarimods
# meta banner: https://mods.hikariatama.ru/badges/tagall.jpg
# scope: hikka_min 1.6.3
import asyncio
import contextlib
import logging
from aiogram import Bot
from hikkatl.tl.functions.channels import InviteToChannelRequest
from hikkatl.tl.types import Message
from .. import loader, utils
from ..inline.types import InlineCall
logger = logging.getLogger(__name__)
class StopEvent:
def __init__(self):
self.state = True
def stop(self):
self.state = False
@loader.tds
class TagAllMod(loader.Module):
"""Tags all people in chat with either inline bot or client"""
strings = {
"name": "TagAll",
"bot_error": "🚫 Unable to invite inline bot to chat",
"_cfg_doc_default_message": "Default message of mentions",
"_cfg_doc_delete": "Delete messages after tagging",
"_cfg_doc_use_bot": "Use inline bot to tag people",
"_cfg_doc_timeout": "What time interval to sleep between each tag message",
"_cfg_doc_silent": "Do not send message with cancel button",
"_cfg_doc_cycle_tagging": (
"Tag all participants over and over again until you stop the script using"
" the button in the message"
),
"_cfg_doc_cycle_delay": "Delay between each cycle of tagging in seconds",
"gathering": "🧚♀️ Calling participants of this chat...",
"cancel": "🚫 Cancel",
"cancelled": "🧚♀️ TagAll cancelled!",
}
strings_ru = {
"bot_error": "🚫 Не получилось пригласить бота в чат",
"_cls_doc": (
"Отмечает всех участников чата, используя инлайн бот или классическим"
" методом"
),
"_cfg_doc_default_message": "Сообщение по умолчанию для тегов",
"_cfg_doc_delete": "Удалять сообщения после тега",
"_cfg_doc_use_bot": "Использовать бота для тегов",
"_cfg_doc_timeout": "Время между сообщениями с тегами",
"_cfg_doc_silent": "Не отправлять сообщение с кнопкой отмены",
"_cfg_doc_cycle_tagging": (
"Тегать всех участников снова и снова, пока вы не остановите скрипт,"
" используя кнопку в сообщении"
),
"_cfg_doc_cycle_delay": "Задержка между циклами тегов в секундах",
"gathering": "🧚♀️ Отмечаю участников чата...",
"cancel": "🚫 Отмена",
"cancelled": "🧚♀️ Сбор участников отменен!",
}
strings_de = {
"bot_error": "🚫 Einladung des Inline-Bots in den Chat fehlgeschlagen",
"_cfg_doc_default_message": "Standardnachricht für Erwähnungen",
"_cfg_doc_delete": "Nachrichten nach Erwähnung löschen",
"_cfg_doc_use_bot": "Inline-Bot verwenden, um Leute zu erwähnen",
"_cfg_doc_timeout": (
"Zeitintervall, in dem zwischen den Erwähnungen gewartet wird"
),
"_cfg_doc_silent": "Nachricht ohne Abbrechen-Button senden",
"_cfg_doc_cycle_tagging": (
"Alle Teilnehmer immer wieder erwähnen, bis du das Skript mit der"
" Schaltfläche in der Nachricht stoppst"
),
"_cfg_doc_cycle_delay": (
"Verzögerung zwischen jedem Zyklus der Erwähnung in Sekunden"
),
"gathering": "🧚♀️ Erwähne Teilnehmer dieses Chats...",
"cancel": "🚫 Abbrechen",
"cancelled": "🧚♀️ TagAll abgebrochen!",
}
strings_tr = {
"bot_error": "🚫 Inline botunu sohbete davet edilemedi",
"_cfg_doc_default_message": "Varsayılan etiket mesajı",
"_cfg_doc_delete": "Etiketledikten sonra mesajları sil",
"_cfg_doc_use_bot": "İnsanları etiketlemek için inline botu kullan",
"_cfg_doc_timeout": "Her etiket mesajı arasında ne kadar bekleneceği",
"_cfg_doc_silent": "İptal düğmesi olmadan mesaj gönderme",
"_cfg_doc_cycle_tagging": (
"Mesajdaki düğmeyi kullanarak betiği durdurana kadar tüm katılımcıları"
" tekrar tekrar etiketle"
),
"_cfg_doc_cycle_delay": "Etiketleme döngüsü arasındaki gecikme süresi (saniye)",
"gathering": "🧚♀️ Bu sohbetteki katılımcıları çağırıyorum...",
"cancel": "🚫 İptal",
"cancelled": "🧚♀️ TagAll iptal edildi!",
}
strings_uz = {
"bot_error": (
"🚫 Inline botni chatga taklif qilish muvaffaqiyatsiz bo‘ldi"
),
"_cfg_doc_default_message": "Odatiy etiket xabari",
"_cfg_doc_delete": "Etiketdan so‘ng xabarlarni o‘chirish",
"_cfg_doc_use_bot": "Odamlarni etiketlash uchun inline botdan foydalanish",
"_cfg_doc_timeout": "Har bir etiket xabari orasida nechta kutish kerak",
"_cfg_doc_silent": "Bekor tugmasi olmadan xabar jo‘natish",
"_cfg_doc_cycle_tagging": (
"Xabar bo‘yicha tugmani ishlatib, skriptni to‘xtatguncha barcha"
" qatnashuvchilarni qayta-qayta etiketlash"
),
"_cfg_doc_cycle_delay": "Har bir etiketlash tsikli orasida gecikma (soniya)",
"gathering": "🧚♀️ Ushbu chatta qatnashganlarni chaqiraman...",
"cancel": "🚫 Bekor qilish",
"cancelled": "🧚♀️ TagAll bekor qilindi!",
}
def __init__(self):
self.config = loader.ModuleConfig(
loader.ConfigValue(
"default_message",
"@all",
lambda: self.strings("_cfg_doc_default_message"),
),
loader.ConfigValue(
"delete",
False,
lambda: self.strings("_cfg_doc_delete"),
validator=loader.validators.Boolean(),
),
loader.ConfigValue(
"use_bot",
False,
lambda: self.strings("_cfg_doc_use_bot"),
validator=loader.validators.Boolean(),
),
loader.ConfigValue(
"timeout",
0.1,
lambda: self.strings("_cfg_doc_timeout"),
validator=loader.validators.Float(minimum=0),
),
loader.ConfigValue(
"silent",
False,
lambda: self.strings("_cfg_doc_silent"),
validator=loader.validators.Boolean(),
),
loader.ConfigValue(
"cycle_tagging",
False,
lambda: self.strings("_cfg_cycle_tagging"),
validator=loader.validators.Boolean(),
),
loader.ConfigValue(
"cycle_delay",
0,
lambda: self.strings("_cfg_cycle_delay"),
validator=loader.validators.Integer(minimum=0),
),
)
async def cancel(self, call: InlineCall, event: StopEvent):
event.stop()
await call.answer(self.strings("cancel"))
@loader.command(
groups=True,
ru_doc="[текст] - Отметить всех участников чата",
de_doc="[Text] - Alle Chatteilnehmer erwähnen",
tr_doc="[metin] - Sohbet katılımcılarını etiketle",
uz_doc="[matn] - Chat qatnashuvchilarini tegish",
)
async def tagall(self, message: Message):
"""[text] - Tag all users in chat"""
args = utils.get_args_raw(message)
if message.out:
await message.delete()
if self.config["use_bot"]:
try:
await self._client(
InviteToChannelRequest(message.peer_id, [self.inline.bot_username])
)
except Exception:
await utils.answer(message, self.strings("bot_error"))
return
with contextlib.suppress(Exception):
Bot.set_instance(self.inline.bot)
chat_id = int(f"-100{utils.get_chat_id(message)}")
else:
chat_id = utils.get_chat_id(message)
event = StopEvent()
if not self.config["silent"]:
cancel = await self.inline.form(
message=message,
text=self.strings("gathering"),
reply_markup={
"text": self.strings("cancel"),
"callback": self.cancel,
"args": (event,),
},
)
first, br = True, False
while True if self.config["cycle_tagging"] else first:
for chunk in utils.chunks(
[
f'\xad'
async for user in self._client.iter_participants(message.peer_id)
],
5,
):
m = await (
self.inline.bot.send_message
if self.config["use_bot"]
else self._client.send_message
)(
chat_id,
utils.escape_html(args or self.config["default_message"])
+ "\xad".join(chunk),
)
if self.config["delete"]:
with contextlib.suppress(Exception):
await m.delete()
async def _task():
nonlocal event, cancel
if not self.config["silent"]:
return
while True:
if not event.state:
await cancel.edit(self.strings("cancelled"))
return
await asyncio.sleep(0.1)
task = asyncio.ensure_future(_task())
await asyncio.sleep(self.config["timeout"])
task.cancel()
if not event.state:
br = True
break
if br:
break
first = False
if self.config["cycle_tagging"]:
await asyncio.sleep(self.config["cycle_delay"])
await cancel.delete()