Files
limoka/hikariatama/ftg/tagall.py
2025-07-10 21:02:34 +03:00

283 lines
11 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

__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": "🚫 <b>Unable to invite inline bot to chat</b>",
"_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": "🧚‍♀️ <b>Calling participants of this chat...</b>",
"cancel": "🚫 Cancel",
"cancelled": "🧚‍♀️ <b>TagAll cancelled!</b>",
}
strings_ru = {
"bot_error": "🚫 <b>Не получилось пригласить бота в чат</b>",
"_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": "🧚‍♀️ <b>Отмечаю участников чата...</b>",
"cancel": "🚫 Отмена",
"cancelled": "🧚‍♀️ <b>Сбор участников отменен!</b>",
}
strings_de = {
"bot_error": "🚫 <b>Einladung des Inline-Bots in den Chat fehlgeschlagen</b>",
"_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": "🧚‍♀️ <b>Erwähne Teilnehmer dieses Chats...</b>",
"cancel": "🚫 Abbrechen",
"cancelled": "🧚‍♀️ <b>TagAll abgebrochen!</b>",
}
strings_tr = {
"bot_error": "🚫 <b>Inline botunu sohbete davet edilemedi</b>",
"_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": "🧚‍♀️ <b>Bu sohbetteki katılımcıları çağırıyorum...</b>",
"cancel": "🚫 İptal",
"cancelled": "🧚‍♀️ <b>TagAll iptal edildi!</b>",
}
strings_uz = {
"bot_error": (
"🚫 <b>Inline botni chatga taklif qilish muvaffaqiyatsiz boldi</b>"
),
"_cfg_doc_default_message": "Odatiy etiket xabari",
"_cfg_doc_delete": "Etiketdan song xabarlarni ochirish",
"_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 jonatish",
"_cfg_doc_cycle_tagging": (
"Xabar boyicha tugmani ishlatib, skriptni toxtatguncha barcha"
" qatnashuvchilarni qayta-qayta etiketlash"
),
"_cfg_doc_cycle_delay": "Har bir etiketlash tsikli orasida gecikma (soniya)",
"gathering": "🧚‍♀️ <b>Ushbu chatta qatnashganlarni chaqiraman...</b>",
"cancel": "🚫 Bekor qilish",
"cancelled": "🧚‍♀️ <b>TagAll bekor qilindi!</b>",
}
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'<a href="tg://user?id={user.id}">\xad</a>'
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()