diff --git a/BotBase/config.py b/BotBase/config.py new file mode 100644 index 0000000..6e96e6b --- /dev/null +++ b/BotBase/config.py @@ -0,0 +1,187 @@ +from pyrogram import InlineKeyboardMarkup, InlineKeyboardButton, Client +from collections import defaultdict +from pyrogram import Filters +import re +import os + +# Antiflood module configuration +# The antiflood works by accumulating up to MAX_UPDATE_THRESHOLD updates (user-wise) +# and when that limit is reached, perform some checks to tell if the user is actually flooding + + +BAN_TIME = 300 # The amount of seconds the user will be banned +MAX_UPDATE_THRESHOLD = 7 # How many updates to accumulate before starting to count +PRIVATE_ONLY = True # If True, the antiflood will only work in private chats +# The percentage (from 0 to 100) of updates that when below ANTIFLOOD_SENSIBILITY will trigger the anti flood + +# Example, if FLOOD_PERCENTAGE == 75, if at least 75% of the messages from a user are marked as flood it will be blocked +FLOOD_PERCENTAGE = 75 +# The minimum amount of seconds between updates. Updates that are sent faster than this limit will trigger the antiflood +# This should not be below 1, but you can experiment if you feel bold enough +ANTIFLOOD_SENSIBILITY = 1 +# If you want the user to be notified of being flood-blocked, set this to the desired message, False to disable +FLOOD_NOTICE = f"πŸ€™ **Hey amico**!\nπŸ• Rilassati! Sei stato bloccato per {BAN_TIME / 60:.1f} minuti" +DELETE_MESSAGES = True # Set this to false if you do not want the messages to be deleted after flood is detected + +# Various options and global variables + +CACHE = defaultdict(lambda: ["none", 0]) # Global cache. DO NOT TOUCH IT, really just don't +VERSION = "1.0A" # These will be shown in the 'Credits' section +RELEASE_DATE = "29/05/2020" +CREDITS = "πŸ§‘β€πŸ’»Bot sviluppato da nocturn9x in Python3.8 e Pyrogram 0.17.1" \ + f"\nβš™οΈ **Versione**: {VERSION}\nπŸ—“ **Data di rilascio**: {RELEASE_DATE}" + +# Telegram client configuration + +WORKERS_NUM = 15 # The number of worker threads that pyrogram will spawn at startup. +# 10 workers means that the bot will process up to 10 users at the same time and then block until one worker has done +BOT_TOKEN = "TOKEN HERE" # Get it with t.me/BotFather +SESSION_NAME = "BotBase" # The name of the Telegram Session that the bot will have, will be visible from Telegram +PLUGINS_ROOT = {"root": f"BotBase/modules"} # Do not change this unless you know what you're doing +API_ID = 1234567 # Get it at https://my.telegram.org/apps +API_HASH = "abcdef123456" # Same as above + +# Logging configuration +# To know more about what these options mean, check https://docs.python.org/3/library/logging.html + +LOGGING_FORMAT = "[%(levelname)s %(asctime)s] In thread '%(threadName)s', " \ + f"module %(module)s, function %(funcName)s at line %(lineno)d -> [{SESSION_NAME}] %(message)s" +DATE_FORMAT = "%d/%m/%Y %H:%M:%S %p" +LOGGING_LEVEL = 30 +bot = Client(api_id=API_ID, api_hash=API_HASH, bot_token=BOT_TOKEN, plugins=PLUGINS_ROOT, + session_name=SESSION_NAME, workers=WORKERS_NUM) + +# Start module +# P.S.: {mention} in the GREET message will be replaced with a mention to the user, same applies for {id} and {username} + +GREET = """Ciao {mention} [`{id}`]!""" # The message that will be sent as a reply to the /start command. If this string is empty the bot will not reply +SUPPORT_BUTTON = "πŸ’­ Chat" # The text for the button that triggers the live chat +BACK_BUTTON = "πŸ”™ Indietro" +CREDITS_BUTTON = "β„Ή Crediti" # The text for the 'Credits' button +BUTTONS = InlineKeyboardMarkup([ # This keyboard will be sent along with GREET, feel free to add or remove buttons + [InlineKeyboardButton(CREDITS_BUTTON, "info")], + [InlineKeyboardButton(SUPPORT_BUTTON, "sos")] + ] + ) + + +# Database configuration +# The only natively supported database is SQLite3, but you can easily tweak +# this section and the BotBase/database/query.py file to work with any DBMS +# If you do so and want to share your code feel free to open a PR on the repo! + +DB_PATH = os.path.join(os.getcwd(), f"BotBase/database/database.db") +DB_CREATE = """CREATE TABLE IF NOT EXISTS users( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + tg_id INTEGER UNIQUE NOT NULL, + uname TEXT UNIQUE NULL DEFAULT 'null', + date TEXT NOT NULL, + banned INTEGER NOT NULL DEFAULT 0); + """ + +DB_GET_USERS = "SELECT tg_id FROM users" +DB_GET_USER = "SELECT * FROM users where users.tg_id = ?" +DB_SET_USER = "INSERT INTO users (id, tg_id, uname, date, banned) VALUES(?, ?, ?, ?, ?)" +DB_BAN_USER = "UPDATE users SET banned = 1 WHERE users.tg_id = ?" +DB_UNBAN_USER = "UPDATE users SET banned = 0 WHERE users.tg_id = ?" +DB_UPDATE_NAME = "UPDATE users SET uname = ? WHERE users.tg_id = ?" +DB_GET_USER_BY_NAME = "SELECT * FROM users where users.uname = ?" +from .database.query import get_user + + +# Admin module configuration + +# Edit this dict adding the ID:NAME pair of the admin that you want to add. You can add as many admins as you want +ADMINS = {669152898: "Matt-sama :3", 836296867: "Ξ±β„“Ρ•ΟƒΖ“AMƐR"} +MARKED_BUSY = "🎲 Ora sei impegnato, invia nuovamente /busy per resettare questo stato" +UNMARKED_BUSY = "✍ Da ora riceverai nuovamente le richieste di assistenza" +CANNOT_BAN_ADMIN = "❌ L'utente Γ© un amministratore" +USER_BANNED = "βœ… Utente bannato" +USER_UNBANNED = "βœ… Utente sbannato" +YOU_ARE_UNBANNED = "βœ… Sei stato sbannato" +USER_NOT_BANNED = "❌ L'utente non Γ© bannato" +CLOSE_CHAT_BUTTON = "❌ Chiudi chat" +UPDATE_BUTTON = "πŸ”„ Aggiorna" +USER_ALREADY_BANNED = "❌ L'utente Γ© giΓ  bannato" +YOU_ARE_BANNED = "❌ Sei stato bannato" +WHISPER_FROM = "πŸ“£ Messaggio da {admin}: {msg}" +WHISPER_SUCCESSFUL = "βœ… Inviato" +NAME = "tg://user?id={}" +BYPASS_FLOOD = True # If False, admins can be flood-blocked too, otherwise the antiflood will ignore them +USER_INFO_UPDATED = "βœ… Informazioni aggiornate" +USER_INFO_UNCHANGED = "❌ Non ho rilevato cambiamenti per questo utente" +USER_INFO = """**ℹ️ Informazioni** + +πŸ†” **ID**: `{uid}` +✍️ **Username**: {uname} +πŸ—“ **Registrato il**: {date} +**⌨️ Bannato**: {status} +**πŸ’‘ Admin**: {admin}""" # The message that is sent with /getuser and /getranduser +INVALID_SYNTAX = "❌ **Sintassi invalida**: Usa `{correct}`" # This is sent when a command is used the wrong way +ERROR = "❌ **Errore**" # This is sent when a command returns an error +NONNUMERIC_ID = "L'ID deve essere numerico!" # This is sent if the parameter to /getuser is not a numerical ID +USERS_COUNT = "**Utenti totali**: `{count}`" # This is sent as a result of the /count command +NO_PARAMETERS = "❌ {command} non richiede parametri" # Error saying that the given command takes no parameters +ID_MISSING = "L'ID selezionato ({uid}) non Γ© nel database" # Error when given ID is not in database +NAME_MISSING = "L'username selezionato ({uname}) non Γ© nel database" # Error when given username is not in database +YES = "SΓ¬" +NO = "No" +GLOBAL_MESSAGE_STATS = """**Statistiche messaggio** + +✍️** Messaggio**: {msg} +πŸ”„ **Tentativi**: {count} +**βœ… Consegnati**: {success}""" # Statistics that are sent to the admin after /global command + +# Live chat configuration + +ADMINS_LIST_UPDATE_DELAY = 30 # How many seconds between an update and another + +# These strings are pretty self explanatory, aren't they? +LIVE_CHAT_STATUSES = "Legenda: 🟒 = Disponibile, πŸ”΄ = Occupato\n\n" +SUPPORT_NOTIFICATION = "πŸ”” Nuova richiesta di supporto!\n\n{uinfo}" +ADMIN_JOINS_CHAT = " [{admin_name}]({admin_id}) entra in chat!" +USER_CLOSES_CHAT = "πŸ”” [{user_name}]({user_id}) ha chiuso la chat" +USER_LEAVES_CHAT = "βœ… Hai lasciato la chat" +USER_JOINS_CHAT = "βœ… Sei entrato in chat" +CHAT_BUSY = "⚠️ Un altro admin Γ© giΓ  entrato" +LEAVE_CURRENT_CHAT = "⚠️ Chiudi prima la chat corrente!" +CANNOT_REQUEST_SUPPORT = "⚠️ Non puoi richiedere supporto" +STATUS_FREE = "🟒 " +STATUS_BUSY = "πŸ”΄ " +SUPPORT_REQUEST_SENT = "βœ… Ora sei in coda, attendi che un admin ti risponda\n\n" \ + "**πŸ”„ Admin disponibili**\n{queue}\n**Aggiornato il**: {date}\n\n**Nota**: Se non ci sono admin disponibili al momento, premi il bottone 'Aggiorna' ogni tanto per scoprire se si Γ© liberato un posto!" +JOIN_CHAT_BUTTON = "❗ Entra in chat" +USER_MESSAGE = "πŸ—£ [{user_name}]({user_id}): {message}" +ADMIN_MESSAGE = "πŸ§‘β€πŸ’» [{user_name}]({user_id}): {message}" +TOO_FAST = "βœ‹ Non cosΓ¬ veloce! Riprova piΓΊ tardi" + +# Custom filters - Don't touch them as well but feel free to add more! + + +def check_user_banned(tg_id: int): + res = get_user(tg_id) + if isinstance(res, Exception): + return False + else: + if not res: + return False + if res[-1]: + return True + else: + return False + + +def callback_regex(pattern: str): + return Filters.create(lambda _, update: re.match(pattern, update.data)) + + +def admin_is_chatting(): + return Filters.create(lambda _, update: update.from_user.id in ADMINS and CACHE[update.from_user.id][0] == "IN_CHAT") + + +def user_is_chatting(): + return Filters.create(lambda _, update: update.from_user.id not in ADMINS and CACHE[update.from_user.id][0] == "IN_CHAT") + + +def user_banned(): + return Filters.create(lambda _, update: check_user_banned(update.from_user.id))