From 757dd7fc2a51e367fc2cb73b3d29b00a0504a745 Mon Sep 17 00:00:00 2001 From: shiv munot <90679591+ItzSHIV@users.noreply.github.com> Date: Wed, 3 Nov 2021 13:02:23 +0530 Subject: [PATCH 1/2] Update chatbot.py --- AsunaRobot/modules/chatbot.py | 528 ++++++++++------------------------ 1 file changed, 157 insertions(+), 371 deletions(-) diff --git a/AsunaRobot/modules/chatbot.py b/AsunaRobot/modules/chatbot.py index 8acc7013..b7d0d0dd 100644 --- a/AsunaRobot/modules/chatbot.py +++ b/AsunaRobot/modules/chatbot.py @@ -1,387 +1,173 @@ -# Copyright (C) 2021 Red-Aura & TeamDaisyX & HamkerCat - -# This file is part of AsunaRobot (Telegram Bot) - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. - -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -import re - -import emoji - -url = "https://acobot-brainshop-ai-v1.p.rapidapi.com/get" +import json import re +import os +import html +import requests +import AsunaRobot.modules.sql.chatbot_sql as sql -import aiohttp - -# from google_trans_new import google_translator -from googletrans import Translator as google_translator -from pyrogram import filters - -from AsunaRobot import BOT_ID, pbot as asuna -from AsunaRobot.bot_plugins.chatbot import add_chat, get_session, remove_chat -from AsunaRobot.utils.pluginhelper import admins_only, edit_or_reply - -translator = google_translator() - - -async def lunaQuery(query: str, user_id: int): - luna = await arq.luna(query, user_id) - return luna.result - - -def extract_emojis(s): - return "".join(c for c in s if c in emoji.UNICODE_EMOJI) - - -async def fetch(url): - try: - async with aiohttp.Timeout(10.0): - async with aiohttp.ClientSession() as session: - async with session.get(url) as resp: - try: - data = await resp.json() - except: - data = await resp.text() - return data - except: - print("AI response Timeout") - return - - -asuna_chats = [] -en_chats = [] -# AI Chat (C) 2020-2021 by @InukaAsith +from time import sleep +from telegram import ParseMode +from AsunaRobot import dispatcher, updater, SUPPORT_CHAT +from AsunaRobot.modules.log_channel import gloggable +from telegram import (CallbackQuery, Chat, MessageEntity, InlineKeyboardButton, + InlineKeyboardMarkup, Message, ParseMode, Update, Bot, User) -from Python_ARQ import ARQ -from aiohttp import ClientSession +from telegram.ext import (CallbackContext, CallbackQueryHandler, CommandHandler, + DispatcherHandlerStop, Filters, MessageHandler, + run_async) -ARQ_API_URL = "https://thearq.tech" -ARQ_API_KEY = "WKGIUP-CUQZXG-QSUGEM-WRFYFJ-ARQ" +from telegram.error import BadRequest, RetryAfter, Unauthorized -aiohttpsession = ClientSession() -arq = ARQ(ARQ_API_URL, ARQ_API_KEY, aiohttpsession) +from AsunaRobot.modules.helper_funcs.filters import CustomFilters +from AsunaRobot.modules.helper_funcs.chat_status import user_admin, user_admin_no_reply +from telegram.utils.helpers import mention_html, mention_markdown, escape_markdown -@asuna.on_message( - filters.command("chatbot") & ~filters.edited & ~filters.bot & ~filters.private -) -@admins_only -async def hmm(_, message): - global asuna_chats - if len(message.command) != 2: - await message.reply_text( - "I only recognize `/chatbot on` and /chatbot `off only`" - ) - message.continue_propagation() - status = message.text.split(None, 1)[1] - chat_id = message.chat.id - if status == "ON" or status == "on" or status == "On": - lel = await edit_or_reply(message, "`Processing...`") - lol = add_chat(int(message.chat.id)) - if not lol: - await lel.edit("Asuna AI Already Activated In This Chat") - return - await lel.edit( - f"Asuna AI Successfully Added For Users In The Chat {message.chat.id}" - ) - - elif status == "OFF" or status == "off" or status == "Off": - lel = await edit_or_reply(message, "`Processing...`") - Escobar = remove_chat(int(message.chat.id)) - if not Escobar: - await lel.edit("Asuna AI Was Not Activated In This Chat") - return - await lel.edit( - f"Asuna AI Successfully Deactivated For Users In The Chat {message.chat.id}" - ) - - elif status == "EN" or status == "en" or status == "english": - if not chat_id in en_chats: - en_chats.append(chat_id) - await message.reply_text("English AI chat Enabled!") - return - await message.reply_text("AI Chat Is Already Disabled.") - message.continue_propagation() - else: - await message.reply_text( - "I only recognize `/chatbot on` and /chatbot `off only`" - ) - - -@asuna.on_message( - filters.text - & filters.reply - & ~filters.bot - & ~filters.edited - & ~filters.via_bot - & ~filters.forwarded, - group=2, -) -async def hmm(client, message): - if not get_session(int(message.chat.id)): - return - if not message.reply_to_message: - return - try: - senderr = message.reply_to_message.from_user.id - except: - return - if senderr != BOT_ID: - return - msg = message.text - chat_id = message.chat.id - if msg.startswith("/") or msg.startswith("@"): - message.continue_propagation() - if chat_id in en_chats: - test = msg - test = test.replace("asuna", "Aco") - test = test.replace("Asuna", "Aco") - response = await lunaQuery( - test, message.from_user.id if message.from_user else 0 - ) - response = response.replace("Aco", "Asuna") - response = response.replace("aco", "Asuna") - - pro = response - try: - await asuna.send_chat_action(message.chat.id, "typing") - await message.reply_text(pro) - except CFError: - return - - else: - u = msg.split() - emj = extract_emojis(msg) - msg = msg.replace(emj, "") - if ( - [(k) for k in u if k.startswith("@")] - and [(k) for k in u if k.startswith("#")] - and [(k) for k in u if k.startswith("/")] - and re.findall(r"\[([^]]+)]\(\s*([^)]+)\s*\)", msg) != [] - ): - - h = " ".join(filter(lambda x: x[0] != "@", u)) - km = re.sub(r"\[([^]]+)]\(\s*([^)]+)\s*\)", r"", h) - tm = km.split() - jm = " ".join(filter(lambda x: x[0] != "#", tm)) - hm = jm.split() - rm = " ".join(filter(lambda x: x[0] != "/", hm)) - elif [(k) for k in u if k.startswith("@")]: - - rm = " ".join(filter(lambda x: x[0] != "@", u)) - elif [(k) for k in u if k.startswith("#")]: - rm = " ".join(filter(lambda x: x[0] != "#", u)) - elif [(k) for k in u if k.startswith("/")]: - rm = " ".join(filter(lambda x: x[0] != "/", u)) - elif re.findall(r"\[([^]]+)]\(\s*([^)]+)\s*\)", msg) != []: - rm = re.sub(r"\[([^]]+)]\(\s*([^)]+)\s*\)", r"", msg) + +@user_admin_no_reply +@gloggable +def kukirm(update: Update, context: CallbackContext) -> str: + query: Optional[CallbackQuery] = update.callback_query + user: Optional[User] = update.effective_user + match = re.match(r"rm_chat\((.+?)\)", query.data) + if match: + user_id = match.group(1) + chat: Optional[Chat] = update.effective_chat + is_kuki = sql.rem_kuki(chat.id) + if is_kuki: + is_kuki = sql.rem_kuki(user_id) + return ( + f"{html.escape(chat.title)}:\n" + f"AI_DISABLED\n" + f"Admin: {mention_html(user.id, html.escape(user.first_name))}\n" + ) else: - rm = msg - # print (rm) - try: - lan = translator.detect(rm) - lan = lan.lang - except: - return - test = rm - if not "en" in lan and not lan == "": - try: - test = translator.translate(test, dest="en") - test = test.text - except: - return - # test = emoji.demojize(test.strip()) - - test = test.replace("asuna", "Aco") - test = test.replace("Asuna", "Aco") - response = await lunaQuery( - test, message.from_user.id if message.from_user else 0 - ) - response = response.replace("Aco", "Asuna") - response = response.replace("aco", "Asuna") - response = response.replace("Luna", "Asuna") - response = response.replace("luna", "Asuna") - pro = response - if not "en" in lan and not lan == "": - try: - pro = translator.translate(pro, dest=lan) - pro = pro.text - except: - return - try: - await asuna.send_chat_action(message.chat.id, "typing") - await message.reply_text(pro) - except CFError: - return - - -@asuna.on_message( - filters.text & filters.private & ~filters.edited & filters.reply & ~filters.bot -) -async def inuka(client, message): - msg = message.text - if msg.startswith("/") or msg.startswith("@"): - message.continue_propagation() - u = msg.split() - emj = extract_emojis(msg) - msg = msg.replace(emj, "") - if ( - [(k) for k in u if k.startswith("@")] - and [(k) for k in u if k.startswith("#")] - and [(k) for k in u if k.startswith("/")] - and re.findall(r"\[([^]]+)]\(\s*([^)]+)\s*\)", msg) != [] - ): - - h = " ".join(filter(lambda x: x[0] != "@", u)) - km = re.sub(r"\[([^]]+)]\(\s*([^)]+)\s*\)", r"", h) - tm = km.split() - jm = " ".join(filter(lambda x: x[0] != "#", tm)) - hm = jm.split() - rm = " ".join(filter(lambda x: x[0] != "/", hm)) - elif [(k) for k in u if k.startswith("@")]: - - rm = " ".join(filter(lambda x: x[0] != "@", u)) - elif [(k) for k in u if k.startswith("#")]: - rm = " ".join(filter(lambda x: x[0] != "#", u)) - elif [(k) for k in u if k.startswith("/")]: - rm = " ".join(filter(lambda x: x[0] != "/", u)) - elif re.findall(r"\[([^]]+)]\(\s*([^)]+)\s*\)", msg) != []: - rm = re.sub(r"\[([^]]+)]\(\s*([^)]+)\s*\)", r"", msg) - else: - rm = msg - # print (rm) - try: - lan = translator.detect(rm) - lan = lan.lang - except: - return - test = rm - if not "en" in lan and not lan == "": - try: - test = translator.translate(test, dest="en") - test = test.text - except: - return - - # test = emoji.demojize(test.strip()) - - # Kang with the credits bitches @InukaASiTH - test = test.replace("asuna", "Aco") - test = test.replace("Asuna", "Aco") - - response = await lunaQuery(test, message.from_user.id if message.from_user else 0) - response = response.replace("Aco", "Asuna") - response = response.replace("aco", "Asuna") - - pro = response - if not "en" in lan and not lan == "": - pro = translator.translate(pro, dest=lan) - pro = pro.text - try: - await asuna.send_chat_action(message.chat.id, "typing") - await message.reply_text(pro) - except CFError: - return - - -@asuna.on_message( - filters.regex("Asuna|asuna|asuna|ASUNA|asuna") - & ~filters.bot - & ~filters.via_bot - & ~filters.forwarded - & ~filters.reply - & ~filters.channel - & ~filters.edited -) -async def inuka(client, message): - msg = message.text - if msg.startswith("/") or msg.startswith("@"): - message.continue_propagation() - u = msg.split() - emj = extract_emojis(msg) - msg = msg.replace(emj, "") - if ( - [(k) for k in u if k.startswith("@")] - and [(k) for k in u if k.startswith("#")] - and [(k) for k in u if k.startswith("/")] - and re.findall(r"\[([^]]+)]\(\s*([^)]+)\s*\)", msg) != [] - ): - - h = " ".join(filter(lambda x: x[0] != "@", u)) - km = re.sub(r"\[([^]]+)]\(\s*([^)]+)\s*\)", r"", h) - tm = km.split() - jm = " ".join(filter(lambda x: x[0] != "#", tm)) - hm = jm.split() - rm = " ".join(filter(lambda x: x[0] != "/", hm)) - elif [(k) for k in u if k.startswith("@")]: - - rm = " ".join(filter(lambda x: x[0] != "@", u)) - elif [(k) for k in u if k.startswith("#")]: - rm = " ".join(filter(lambda x: x[0] != "#", u)) - elif [(k) for k in u if k.startswith("/")]: - rm = " ".join(filter(lambda x: x[0] != "/", u)) - elif re.findall(r"\[([^]]+)]\(\s*([^)]+)\s*\)", msg) != []: - rm = re.sub(r"\[([^]]+)]\(\s*([^)]+)\s*\)", r"", msg) + update.effective_message.edit_text( + "Chatbot disable by {}.".format(mention_html(user.id, user.first_name)), + parse_mode=ParseMode.HTML, + ) + + return "" + +@user_admin_no_reply +@gloggable +def kukiadd(update: Update, context: CallbackContext) -> str: + query: Optional[CallbackQuery] = update.callback_query + user: Optional[User] = update.effective_user + match = re.match(r"add_chat\((.+?)\)", query.data) + if match: + user_id = match.group(1) + chat: Optional[Chat] = update.effective_chat + is_kuki = sql.set_kuki(chat.id) + if is_kuki: + is_kuki = sql.set_kuki(user_id) + return ( + f"{html.escape(chat.title)}:\n" + f"AI_ENABLE\n" + f"Admin: {mention_html(user.id, html.escape(user.first_name))}\n" + ) + else: + update.effective_message.edit_text( + "Chatbot enable by {}.".format(mention_html(user.id, user.first_name)), + parse_mode=ParseMode.HTML, + ) + + return "" + +@user_admin +@gloggable +def kuki(update: Update, context: CallbackContext): + user = update.effective_user + message = update.effective_message + msg = f"Choose an option" + keyboard = InlineKeyboardMarkup([[ + InlineKeyboardButton( + text="Enable", + callback_data="add_chat({})")], + [ + InlineKeyboardButton( + text="Disable", + callback_data="rm_chat({})")]]) + message.reply_text( + msg, + reply_markup=keyboard, + parse_mode=ParseMode.HTML, + ) + +def kuki_message(context: CallbackContext, message): + reply_message = message.reply_to_message + if message.text.lower() == "kuki": + return True + if reply_message: + if reply_message.from_user.id == context.bot.get_me().id: + return True else: - rm = msg - # print (rm) - try: - lan = translator.detect(rm) - lan = lan.lang - except: + return False + + +def chatbot(update: Update, context: CallbackContext): + message = update.effective_message + chat_id = update.effective_chat.id + bot = context.bot + is_kuki = sql.is_kuki(chat_id) + if not is_kuki: return - test = rm - if not "en" in lan and not lan == "": - try: - test = translator.translate(test, dest="en") - test = test.text - except: + + if message.text and not message.document: + if not kuki_message(context, message): return - - # test = emoji.demojize(test.strip()) - - test = test.replace("asuna", "Aco") - test = test.replace("Asuna", "Aco") - response = await lunaQuery(test, message.from_user.id if message.from_user else 0) - response = response.replace("Aco", "Asuna") - response = response.replace("aco", "Asuna") - - pro = response - if not "en" in lan and not lan == "": + Message = message.text + bot.send_chat_action(chat_id, action="typing") + kukiurl = requests.get('https://www.kukiapi.xyz/api/apikey=KUKIsb9C90gVW/Kuki/MoeZilla/message='+Message) + Kuki = json.loads(kukiurl.text) + kuki = Kuki['reply'] + sleep(0.3) + message.reply_text(kuki, timeout=60) + +def list_all_chats(update: Update, context: CallbackContext): + chats = sql.get_all_kuki_chats() + text = "KUKI-Enabled Chats\n" + for chat in chats: try: - pro = translator.translate(pro, dest=lan) - pro = pro.text - except Exception: - return - try: - await asuna.send_chat_action(message.chat.id, "typing") - await message.reply_text(pro) - except CFError: - return - + x = context.bot.get_chat(int(*chat)) + name = x.title or x.first_name + text += f"• {name}\n" + except (BadRequest, Unauthorized): + sql.rem_kuki(*chat) + except RetryAfter as e: + sleep(e.retry_after) + update.effective_message.reply_text(text, parse_mode="HTML") __help__ = """ - AI Chatbot -Asuna AI 3.0 IS THE ONLY AI SYSTEM WHICH CAN DETECT & REPLY UPTO 200 LANGUAGES - - - /chatbot [ON/OFF]: Enables and disables AI Chat mode (EXCLUSIVE) - - /chatbot EN : Enables English only chatbot - - - Chatbot - - /ask [question]: Ask question from Asuna - - /ask [reply to voice note]: Get voice reply - +Chatbot utilizes the Kuki's api which allows Kuki to talk and provide a more interactive group chat experience. +*Admins only Commands*: + ➢ `/Chatbot`*:* Shows chatbot control panel + + Reports bugs at Kuki-api.tk +*Powered by ItelAi* (https://github/itelai) from @KukiUpdates """ -__mod_name__ = "Chatbot" +__mod_name__ = "ChatBot" + +CHATBOTK_HANDLER = CommandHandler("chatbot", kuki) +ADD_CHAT_HANDLER = CallbackQueryHandler(kukiadd, pattern=r"add_chat") +RM_CHAT_HANDLER = CallbackQueryHandler(kukirm, pattern=r"rm_chat") +CHATBOT_HANDLER = MessageHandler( + Filters.text & (~Filters.regex(r"^#[^\s]+") & ~Filters.regex(r"^!") + & ~Filters.regex(r"^\/")), chatbot) +LIST_ALL_CHATS_HANDLER = CommandHandler( + "allchats", list_all_chats, filters=CustomFilters.dev_filter) + +dispatcher.add_handler(ADD_CHAT_HANDLER) +dispatcher.add_handler(CHATBOTK_HANDLER) +dispatcher.add_handler(RM_CHAT_HANDLER) +dispatcher.add_handler(LIST_ALL_CHATS_HANDLER) +dispatcher.add_handler(CHATBOT_HANDLER) + +__handlers__ = [ + ADD_CHAT_HANDLER, + CHATBOTK_HANDLER, + RM_CHAT_HANDLER, + LIST_ALL_CHATS_HANDLER, + CHATBOT_HANDLER, +] From 1ebc28675a2bf72428a5da437a0b4bdc75647394 Mon Sep 17 00:00:00 2001 From: shiv munot <90679591+ItzSHIV@users.noreply.github.com> Date: Wed, 3 Nov 2021 13:05:29 +0530 Subject: [PATCH 2/2] Create chatbot_sql.py --- AsunaRobot/modules/sql/chatbot_sql.py | 42 +++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 AsunaRobot/modules/sql/chatbot_sql.py diff --git a/AsunaRobot/modules/sql/chatbot_sql.py b/AsunaRobot/modules/sql/chatbot_sql.py new file mode 100644 index 00000000..8799ab2a --- /dev/null +++ b/AsunaRobot/modules/sql/chatbot_sql.py @@ -0,0 +1,42 @@ +import threading +from sqlalchemy import Column, String +from AsunaRobot.modules.sql import BASE, SESSION +class KukiChats(BASE): + __tablename__ = "kuki_chats" + chat_id = Column(String(14), primary_key=True) + + def __init__(self, chat_id): + self.chat_id = chat_id + +KukiChats.__table__.create(checkfirst=True) +INSERTION_LOCK = threading.RLock() + + +def is_kuki(chat_id): + try: + chat = SESSION.query(KukiChats).get(str(chat_id)) + return bool(chat) + finally: + SESSION.close() + +def set_kuki(chat_id): + with INSERTION_LOCK: + kukichat = SESSION.query(KukiChats).get(str(chat_id)) + if not kukichat: + kukichat = KukiChats(str(chat_id)) + SESSION.add(kukichat) + SESSION.commit() + +def rem_kuki(chat_id): + with INSERTION_LOCK: + kukichat = SESSION.query(KukiChats).get(str(chat_id)) + if kukichat: + SESSION.delete(kukichat) + SESSION.commit() + + +def get_all_kuki_chats(): + try: + return SESSION.query(KukiChats.chat_id).all() + finally: + SESSION.close()