diff --git a/callbacks.py b/callbacks.py index bb526e8..8e40ed9 100644 --- a/callbacks.py +++ b/callbacks.py @@ -1030,3 +1030,64 @@ async def donate_callback(callback: CallbackQuery): ) await callback.answer() + + +@router.callback_query(F.data.startswith("gset%")) +async def group_set_callback(callback: CallbackQuery): + current_user_id = str(callback.from_user.id) + data = callback.data.split("%", 4) + group_id, user_id, key, val = data[1], data[2], data[3], data[4] + if user_id != current_user_id: + await callback.answer("нет, не трогай это не для тебя") + return + + if key in ["post_reply", "polls", "lurk"]: + set_group_setting(group_id, **{key: val}) + elif key in ["lurk_chance", "lurk_reply_chance"]: + g_config = get_group_config(group_id) + new_val = g_config[key] + int(val) + if new_val < 0: + new_val = 0 + if new_val > 100: + new_val = 100 + set_group_setting(group_id, **{key: new_val}) + + await group_settings_handler(callback, dataalo=f"group%{group_id}") + + +@router.callback_query(F.data.startswith("gpost%")) +async def group_post_prompt_callback(callback: CallbackQuery): + current_user_id = str(callback.from_user.id) + data = callback.data.split("%", 2) + group_id, user_id = data[1], data[2] + if user_id != current_user_id: + await callback.answer("нет, не трогай это не для тебя") + return + + alo_command[int(user_id)] = {"action": "g_prompt", "chat_id": callback.message.chat.id, "message_id": callback.message.message_id, "group_id": group_id} + + await callback.message.edit_text( + "установи промпт для ответов на посты канала (просто текст):", + reply_markup=InlineKeyboardMarkup( + inline_keyboard=[ + [ + InlineKeyboardButton(text="❌ отменить", callback_data=f"gcancel%{group_id}%{user_id}") + ] + ] + ), + ) + await callback.answer() + + +@router.callback_query(F.data.startswith("gcancel%")) +async def group_cancel_callback(callback: CallbackQuery): + current_user_id = str(callback.from_user.id) + data = callback.data.split("%", 2) + group_id, user_id = data[1], data[2] + if user_id != current_user_id: + await callback.answer("нет, не трогай это не для тебя") + return + + alo_command[int(user_id)] = {"action": None, "chat_id": callback.message.chat.id, "message_id": callback.message.message_id} + + await group_settings_handler(callback, dataalo=f"group%{group_id}") diff --git a/commands.py b/commands.py index 71570c8..8559abf 100644 --- a/commands.py +++ b/commands.py @@ -51,6 +51,7 @@ commands = [ "/clean", "/reset", "/tben", + "/group", ] @router.message(Command("stats")) @@ -563,3 +564,127 @@ async def clear_handler(message: Message): async def alo(message: Message): await message.reply_rich(InputRichMessage(markdown="# ало")) return + + +async def group_settings_handler(event: Union[Message, CallbackQuery], dataalo=""): + if dataalo: + group_id = int(dataalo.split("%", 1)[1]) + elif isinstance(event, Message): + group_id = event.chat.id + else: + group_id = int(event.data.split("%", 1)[1]) + + user_id = event.from_user.id + + g_config = get_group_config(group_id) + + if g_config["post_reply"] == "da": + post_reply_status = "да" + post_reply_cb = "net" + else: + post_reply_status = "нет" + post_reply_cb = "da" + + if g_config["polls"] == "da": + polls_status = "да" + polls_cb = "net" + else: + polls_status = "нет" + polls_cb = "da" + + if g_config["lurk"] == "da": + lurk_status = "да" + lurk_cb = "net" + else: + lurk_status = "нет" + lurk_cb = "da" + + if g_config["post_prompt"]: + post_prompt_status = g_config["post_prompt"][:40].replace("\n", " ") + else: + post_prompt_status = "не задан" + + keyboard = InlineKeyboardMarkup( + inline_keyboard=[ + [ + InlineKeyboardButton( + text=f"посты канала: {post_reply_status}", + callback_data=f"gset%{group_id}%{user_id}%post_reply%{post_reply_cb}" + ), + InlineKeyboardButton( + text=f"опросы: {polls_status}", + callback_data=f"gset%{group_id}%{user_id}%polls%{polls_cb}" + ), + ], + [ + InlineKeyboardButton( + text=f"промпт постов: {post_prompt_status}", + callback_data=f"gpost%{group_id}%{user_id}" + ), + ], + [ + InlineKeyboardButton( + text=f"подгляд: {lurk_status}", + callback_data=f"gset%{group_id}%{user_id}%lurk%{lurk_cb}" + ), + InlineKeyboardButton( + text="−", + callback_data=f"gset%{group_id}%{user_id}%lurk_chance%-2" + ), + InlineKeyboardButton( + text=f"глядит {g_config['lurk_chance']}%", + callback_data="hamza" + ), + InlineKeyboardButton( + text="+", + callback_data=f"gset%{group_id}%{user_id}%lurk_chance%+2" + ), + ], + [ + InlineKeyboardButton( + text="−", + callback_data=f"gset%{group_id}%{user_id}%lurk_reply_chance%-1" + ), + InlineKeyboardButton( + text=f"пишет {g_config['lurk_reply_chance']}%", + callback_data="hamza" + ), + InlineKeyboardButton( + text="+", + callback_data=f"gset%{group_id}%{user_id}%lurk_reply_chance%+1" + ), + ], + ] + ) + + text = f"⚡ *настройки группы*\n" \ + f"промпт для постов: `{post_prompt_status}`\n" \ + f"посты канала: {post_reply_status}\n" \ + f"опросы: {polls_status}\n" \ + f"подглядывание: {lurk_status} (глядит {g_config['lurk_chance']}%, пишет {g_config['lurk_reply_chance']}%)" + + if isinstance(event, Message): + await event.reply(text, reply_markup=keyboard) + else: + await event.message.edit_text(text, reply_markup=keyboard) + await event.answer() + + +@router.message(Command("group")) +async def group_handler(message: Message): + if message.chat.type not in [ChatType.GROUP, ChatType.SUPERGROUP]: + return await message.reply("эта команда работает только в группах да✅") + + if not message.from_user: + return + + if message.from_user.id != ADMIN_ID: + try: + member = await message.bot.get_chat_member(message.chat.id, message.from_user.id) + except Exception as e: + print(f"{RED} -- group check - {e}{RESET}") + return await message.reply("🚫 не смог проверить что ты владелец группы.") + if member.status != "creator": + return await message.reply("🚫 настройки группы только для владельца группы да✅") + + await group_settings_handler(message) diff --git a/helpers.py b/helpers.py index 3193275..521c9f0 100644 --- a/helpers.py +++ b/helpers.py @@ -494,3 +494,50 @@ def get_user_config(user_id): db[str(user_id)] = config return config + +def get_group_config(group_id): + with shelve.open("groups") as db: + config = db.get(str(group_id), {}) + defaults = { + "post_prompt": SYSTEM_PROMPTS[DEFAULT_PROMPT]["text"]+ADD_TO_PROMPT+OLD_MD, + "post_reply": "da", + "polls": "da", + "lurk": "da", + "lurk_chance": 10, + "lurk_reply_chance": 2, + } + updated = False + for key, value in defaults.items(): + if key not in config: + config[key] = value + updated = True + if updated: + db[str(group_id)] = config + return config + + +def set_group_setting( + group_id, + post_prompt=None, + post_reply=None, + polls=None, + lurk=None, + lurk_chance=None, + lurk_reply_chance=None, +): + with shelve.open("groups") as db: + group_id = str(group_id) + if group_id not in db: + db[group_id] = {} + + settings = db[group_id] + + if post_prompt is not None: settings["post_prompt"] = post_prompt + if post_reply is not None: settings["post_reply"] = post_reply + if polls is not None: settings["polls"] = polls + if lurk is not None: settings["lurk"] = lurk + if lurk_chance is not None: settings["lurk_chance"] = lurk_chance + if lurk_reply_chance is not None: settings["lurk_reply_chance"] = lurk_reply_chance + + db[group_id] = settings + diff --git a/input_msg.py b/input_msg.py index d034f5f..36e0f5e 100644 --- a/input_msg.py +++ b/input_msg.py @@ -4,7 +4,7 @@ from random import choices from vars import * from config import * -from helpers import get_user_config, set_user_setting +from helpers import get_user_config, set_user_setting, set_group_setting from aiogram.types import ( InlineKeyboardButton, @@ -152,4 +152,22 @@ async def da(bot, message, user_id): ] ) ) + elif alo_command[user_id]["action"] == "g_prompt": + alo_command[user_id]["action"] = None + set_group_setting(alo_command[user_id]["group_id"], post_prompt=message.text[:1000]) + + return await bot.edit_message_text( + text="промпт для постов канала обновлён✅", + chat_id=alo_command[user_id]["chat_id"], + message_id=alo_command[user_id]["message_id"], + reply_markup=InlineKeyboardMarkup( + inline_keyboard=[ + [ + InlineKeyboardButton( + text="⬅️ назад", callback_data=f"gcancel%{alo_command[user_id]['group_id']}%{user_id}" + ), + ], + ] + ) + ) return None diff --git a/main.py b/main.py index 822cbe4..579a49e 100644 --- a/main.py +++ b/main.py @@ -39,7 +39,7 @@ from helpers import * from vars import * from commands import * from dotenv import load_dotenv -from random import uniform, shuffle, choices +from random import uniform, shuffle, choices, randint try: from config import * @@ -107,8 +107,48 @@ async def guest_middleware(handler, event, data): current_time = time.time() stream = config.get("stream") user_text = message.text or message.caption or "" - + + if is_channel and get_group_config(message.chat.id)["post_reply"] == "net": + return + + if message.chat.type in [ChatType.GROUP, ChatType.SUPERGROUP] and user_text and not user_text.startswith("/"): + if message.sender_chat: + author = message.sender_chat.title or message.sender_chat.username or "канал" + elif message.from_user: + author = message.from_user.first_name or "кто-то" + else: + author = "кто-то" + if message.chat.id not in group_last_messages: + group_last_messages[message.chat.id] = [] + group_last_messages[message.chat.id] = (group_last_messages[message.chat.id] + [{"user": author, "text": user_text[:200]}])[-10:] + if not is_replied_bot(message, is_channel, user_text, config) and event.message: + if ( + message.chat.type in [ChatType.GROUP, ChatType.SUPERGROUP] + and message.from_user + and not message.from_user.is_bot + and message.from_user.id != 777000 + ): + g_config = get_group_config(message.chat.id) + if g_config["lurk"] == "da" and randint(1, 100) <= g_config["lurk_chance"]: + if randint(1, 100) <= g_config["lurk_reply_chance"]: + history = group_last_messages.get(message.chat.id, [])[-10:] + if history: + chat_log = "\n".join(f"{m['user']}: {m['text']}" for m in history) + lurk_prompt = f"<переписка юзеров>\n{chat_log}\n\n" \ + "ты узбекгпт и ты иногда подглядел за перепиской в этой группе. " \ + "напиши короткое сообщение от себя в этот чат." + try: + lurk_result = await generate( + bot=bot, + prompt=lurk_prompt, + chat_id=message.chat.id, + user_id=None + ) + if lurk_result: + await message.reply(lurk_result) + except Exception as e: + print(f"{RED} -- lurk - {e}{RESET}") return if user_id: @@ -378,6 +418,7 @@ async def guest_middleware(handler, event, data): if len(last_command_time[user_id][2]) == 1: if is_channel and event.message: + g_config = get_group_config(message.chat.id) result = await generate( bot=bot, prompt=prompt, @@ -385,6 +426,7 @@ async def guest_middleware(handler, event, data): user_id=None, message_id=message_id, images=images, + system_prompt=g_config["post_prompt"] if g_config["post_prompt"] else None, ) elif event.message: result = await generate( @@ -435,7 +477,11 @@ async def guest_middleware(handler, event, data): document=file ) - if POLLS and not message.chat.id in POLLS_BL: + polls_on = True + if message.chat.type in [ChatType.GROUP, ChatType.SUPERGROUP] and get_group_config(message.chat.id)["polls"] == "net": + polls_on = False + + if POLLS and polls_on and not message.chat.id in POLLS_BL: try: if ":" in result and ("poll" in result or "quiz" in result): pw = ["[poll]", "poll", "quiz"] diff --git a/supergenerator.py b/supergenerator.py index 6e9ca84..d4d897b 100644 --- a/supergenerator.py +++ b/supergenerator.py @@ -11,7 +11,7 @@ from aiogram.exceptions import TelegramBadRequest async def generate( - prompt: str, bot=None, user_id=None, chat_id=None, message_id=None, images=None, msg=None, process=None, message=None, inline_id=None + prompt: str, bot=None, user_id=None, chat_id=None, message_id=None, images=None, msg=None, process=None, message=None, inline_id=None, system_prompt=None ) -> str: if user_id: if user_id not in user_contexts: @@ -94,7 +94,11 @@ async def generate( content = [] content += [{"type": "text", "text": prompt}] - messages = [{"role": "system", "content": SYSTEM_PROMPTS[DEFAULT_PROMPT]["text"]+ADD_TO_PROMPT+OLD_MD}] + [ + if system_prompt: + sp = system_prompt + else: + sp = SYSTEM_PROMPTS[DEFAULT_PROMPT]["text"]+ADD_TO_PROMPT+OLD_MD + messages = [{"role": "system", "content": sp}] + [ {"role": "user", "content": content} ] diff --git a/vars.py b/vars.py index 793ca2e..b10d676 100644 --- a/vars.py +++ b/vars.py @@ -10,5 +10,7 @@ alo_command = {} user_contexts = {} # темпбан temp_benned = {} +# последние сообщения групп для подглядывания +group_last_messages = {} # доверие к провейдерам и моделям по ошибкам для автовыбора и значков в выборе моделей models_trust = {}