import asyncio from datetime import datetime from random import choice import traceback from typing import List import discord, ujson import os from modules.booruGet import booruGet from discord import Embed, ButtonStyle, ApplicationContext, Option # type: ignore #from discord_slash import SlashCommand, SlashContext intents = discord.Intents().all() client = discord.Bot(intents=intents) # Technical ============================================================================================================== def nowtime(): return datetime.now().strftime("%d.%m.%Y | %H:%M:%S") def logWrite(message): print(f"[{nowtime()}] {message}") def jsonSave(filename, value): with open(filename, 'w', encoding="utf-8") as f: f.write(ujson.dumps(value, indent=4, ensure_ascii=False)) def jsonLoad(filename): with open(filename, 'r', encoding="utf-8") as f: value = ujson.loads(f.read()) return value #========================================================================================================================= # Configuration ========================================================================================================== def configGet(key: str, *args: str): this_dict = jsonLoad("config.json") this_key = this_dict for dict_key in args: this_key = this_key[dict_key] return this_key[key] def configSet(key, value): config = jsonLoad("config.json") config[key] = value jsonSave("config.json", config) #========================================================================================================================= # Discord Utils ========================================================================================================== def getChan(channels, id): return discord.utils.get(channels, id=id) async def rmMsg(channel_id, message_id): try: channel = client.get_channel(channel_id) message = await channel.fetch_message(message_id) await message.delete() except: pass def makeEmbed(title="", description="", footer="", image=None, color=0xffffff): embed=Embed(title=title, description=description, color=color) if footer is not None: embed.set_footer(text=footer) if image is not None: embed.set_image(url=image) return embed async def is_correct_answer(answer: str, correct: List[str]) -> bool: for entry in correct: if (answer.lower().replace(" ", "").replace(",", "").replace(".", "").replace("–", "-").replace("—", "-")).startswith(entry.lower().replace(" ", "")): return True return False #========================================================================================================================= # Booru Function ========================================================================================================= async def booruAuto(channel, booru, tags, limit): try: output = await booruGet(booru, tags, limit=limit) if output["kind"] == "image" and output["error"] == "": await channel.send( embed=makeEmbed(image=output["image"], footer=f'Теги: {output["tags"]}', color=0x2400e8), view=discord.ui.View(discord.ui.Button(style=ButtonStyle.link, label="Джерело Фото", url=output["source"])) ) elif output["kind"] == "video" and output["thumbnail"] != "": await channel.send( embed=makeEmbed(image=output["thumbnail"], footer=f'Теги: {output["tags"]}', color=0x2400e8), view=discord.ui.View(discord.ui.Button(style=ButtonStyle.link, label="Дивитись Відео", url=output["source"])) ) except: # traceback.print_exc() pass async def booruCommand(ctx, booru, tags, limit, page, times): for _ in range(times): try: output = await booruGet(booru, tags, limit=limit, page=page) if output["kind"] == "image" and output["error"] == "": await ctx.respond( embed=makeEmbed(image=output["image"], footer=f'Теги: {output["tags"]}', color=0x2400e8), view=discord.ui.View(discord.ui.Button(style=ButtonStyle.link, label="Джерело Фото", url=output["source"])) ) elif output["kind"] == "video" and output["thumbnail"] != "": await ctx.respond( embed=makeEmbed(image=output["thumbnail"], footer=f'Теги: {output["tags"]}', color=0x2400e8), view=discord.ui.View(discord.ui.Button(style=ButtonStyle.link, label="Дивитись Відео", url=output["source"])) ) else: traceback.print_exc() if configGet("debug"): await ctx.respond(embed=makeEmbed(image=output["image"], footer="Exception: "+output["error"], color=0xf74b3a)) else: await ctx.respond(embed=makeEmbed(image=output["image"], color=0xf74b3a)) except: # traceback.print_exc() pass await asyncio.sleep(.25) #========================================================================================================================= # Auto Nudes Sender ====================================================================================================== async def sendNudes(): await client.wait_until_ready() guild = client.get_guild(configGet("guild")) while True: for entry in configGet("auto_nsfw"): await booruAuto(getChan(guild.channels, entry["channel"]), entry["booru"], entry["tags"], entry["limit"]) await asyncio.sleep(.25) await asyncio.sleep(60) #========================================================================================================================= # @client.slash_command(name="autonsfw", description="2д пікча з бордів за тегом") # async def autonsfw( # ctx: ApplicationContext, # booru: Option(str, "Назва booru сервісу", choices=["realbooru", "yandere", "danbooru", "konachan", "rule34"]), # type: ignore # tags: Option(str, "Теги (через пробіл)", required=False, default=""), # type: ignore # limit: Option(int, "Сторінки (Кількість зображень/сторінку) (20 якщо не задано)", required=False, default=20), # type: ignore # page: Option(int, "Номер сторінки результатів (Рандомна якщо не задано)", required=False, default=None), # type: ignore # cooldown: Option(int, "Затримка між запитами", required=False, default=1, min_value=1, max_value=5) # type: ignore # ): # await booruCommand(ctx, "2d", tags, limit, page, times) # NSFW Commands ========================================================================================================== nsfw = client.create_group("nsfw", "Команди з відвертим вмістом") @nsfw.command(name="2d", description="2д пікча з бордів за тегом") async def nsfw_2d( ctx: ApplicationContext, tags: Option(str, "Теги (через пробіл)", required=False, default=""), # type: ignore limit: Option(int, "Сторінки (Кількість зображень/сторінку)", required=False, default=20), # type: ignore page: Option(int, "Номер сторінки результатів", required=False, default=None), # type: ignore times: Option(int, "Кількість бажаних зображень", required=False, default=1, min_value=1, max_value=5) # type: ignore ): await booruCommand(ctx, "2d", tags, limit, page, times) @nsfw.command(name="3d", description="3д пікча з бордів за тегом") async def nsfw_3d( ctx: ApplicationContext, tags: Option(str, "Теги (через пробіл)", required=False, default=""), # type: ignore limit: Option(int, "Сторінки (Кількість зображень/сторінку)", required=False, default=20), # type: ignore page: Option(int, "Номер сторінки результатів", required=False, default=None), # type: ignore times: Option(int, "Кількість бажаних зображень", required=False, default=1, min_value=1, max_value=5) # type: ignore ): await booruCommand(ctx, "3d", tags, limit, page, times) @nsfw.command(name="yandere", description="Пікча з yande.re за тегом") async def nsfw_yandere( ctx: ApplicationContext, tags: Option(str, "Теги (через пробіл)", required=False, default=""), # type: ignore limit: Option(int, "Сторінки (Кількість зображень/сторінку)", required=False, default=20), # type: ignore page: Option(int, "Номер сторінки результатів", required=False, default=None), # type: ignore times: Option(int, "Кількість бажаних зображень", required=False, default=1, min_value=1, max_value=5) # type: ignore ): await booruCommand(ctx, "yandere", tags, limit, page, times) @nsfw.command(name="konachan", description="Пікча з konachan.com за тегом") async def nsfw_konachan( ctx: ApplicationContext, tags: Option(str, "Теги (через пробіл)", required=False, default=""), # type: ignore limit: Option(int, "Сторінки (Кількість зображень/сторінку)", required=False, default=20), # type: ignore page: Option(int, "Номер сторінки результатів", required=False, default=None), # type: ignore times: Option(int, "Кількість бажаних зображень", required=False, default=1, min_value=1, max_value=5) # type: ignore ): await booruCommand(ctx, "konachan", tags, limit, page, times) @nsfw.command(name="danbooru", description="Пікча з danbooru.donmai.us за тегом") async def nsfw_danbooru( ctx: ApplicationContext, tags: Option(str, "Теги (через пробіл)", required=False, default=""), # type: ignore limit: Option(int, "Сторінки (Кількість зображень/сторінку)", required=False, default=20), # type: ignore page: Option(int, "Номер сторінки результатів", required=False, default=None), # type: ignore times: Option(int, "Кількість бажаних зображень", required=False, default=1, min_value=1, max_value=5) # type: ignore ): await booruCommand(ctx, "danbooru", tags, limit, page, times) @nsfw.command(name="rule34", description="Пікча rule34.xxx за тегом") async def nsfw_rule34( ctx: ApplicationContext, tags: Option(str, "Теги (через пробіл)", required=False, default=""), # type: ignore limit: Option(int, "Сторінки (Кількість зображень/сторінку)", required=False, default=20), # type: ignore page: Option(int, "Номер сторінки результатів", required=False, default=None), # type: ignore times: Option(int, "Кількість бажаних зображень", required=False, default=1, min_value=1, max_value=5) # type: ignore ): await booruCommand(ctx, "rule34", tags, limit, page, times) @nsfw.command(name="realbooru", description="Пікча з realbooru.com за тегом") async def nsfw_realbooru( ctx: ApplicationContext, tags: Option(str, "Теги (через пробіл)", required=False, default=""), # type: ignore limit: Option(int, "Сторінки (Кількість зображень/сторінку)", required=False, default=20), # type: ignore page: Option(int, "Номер сторінки результатів", required=False, default=None), # type: ignore times: Option(int, "Кількість бажаних зображень", required=False, default=1, min_value=1, max_value=5) # type: ignore ): await booruCommand(ctx, "realbooru", tags, limit, page, times) #========================================================================================================================= async def pidozra(ctx, user, reason="Не вказана"): userdata = jsonLoad("data.json") if str(user.id) not in userdata["dms"]: captcha = choice(configGet("captchas")) userdata["dms"][str(user.id)] = {} userdata["dms"][str(user.id)]["captcha"] = captcha else: captcha = userdata["dms"][str(user.id)]["captcha"] logWrite(f"User {user.name}#{user.discriminator} manually sent to verification due to '{reason}' (q: '{captcha['question']}' a: {str(captcha['answer'])})") try: sent_msg = await user.send(content=f"{user.mention} Вибачте, але вам потрібно пройти невеличкий тест для продовження користування сервером Crue-11 Raise\n\n**{captcha['question']} ...**\n\n```\nПродовжіть речення або надішліть правильну відповідь щоб пройти перевірку\n```") if not isinstance(ctx, discord.Message): await ctx.respond(content=f"Юзеру `{user.name}#{user.discriminator}` оголешно про підозру") except Exception as exp: if not isinstance(ctx, discord.Message): await ctx.respond(content=f"Не вдалось оголосити `{user.name}#{user.discriminator}` про підозру:\n`{exp}`") return await getChan(user.guild.channels, configGet("captcha_log", "channels", "verification")).send(embed=makeEmbed(title="❓ Відправлено на перевірку", description=f"**Ім'я:** `{user.name}#{user.discriminator}`\n**Причина:** `{reason}`\n**Питання:** `{captcha['question']}`\n**Відповіді:** `{str(captcha['answer'])}`", color=0x6996e4)) await user.remove_roles(getChan(user.guild.roles, configGet("verified", "roles"))) await user.add_roles(getChan(user.guild.roles, configGet("additional_verification", "roles"))) userdata["dms"][str(user.id)]["question_id"] = sent_msg.id jsonSave("data.json", userdata) @client.event async def on_ready(): print(f"Logged in as {client.user}") await client.change_presence(activity=discord.Activity(type=discord.ActivityType.listening, name="Гімн України")) await sendNudes() # Guild Commands ========================================================================================================= @client.slash_command(name="verify", description="Підтвердити що юзер не московит") async def verify(ctx: ApplicationContext, user: Option(discord.User, "Юзер сервера")): # type: ignore if ctx.author.id in configGet("admins"): if ctx.guild is not None: userdata = jsonLoad("data.json") logWrite(f"User {user.name}#{user.discriminator} verified by admin {ctx.author.name}#{ctx.author.discriminator}") await ctx.respond(content=f"{user.mention} Ласкаво просимо!\nУ вас тепер є повний доступ до всього сервера. Приємного спілкування!", delete_after=3) await user.add_roles(getChan(user.guild.roles, configGet("verified", "roles"))) await getChan(user.guild.channels, configGet("chat", "channels", "general")).send(content=f"У нас поповнення у вигляді {user.mention}. Познайомтесь :)") await user.remove_roles(getChan(user.guild.roles, configGet("failed_captcha", "roles"))) await getChan(user.guild.channels, configGet("captcha_log", "channels", "verification")).send(embed=makeEmbed(title="✅ Юзера верифіковано вручну", description=f"**Ім'я:** `{user.name}#{user.discriminator}`\n**Адмін**: `{ctx.author.name}#{ctx.author.discriminator}`", color=0xffc300)) try: del userdata[str(user.id)] jsonSave("data.json", userdata) except: pass return else: await ctx.respond(content=configGet("denied_guild", "msg")) else: await ctx.respond(content=configGet("denied", "msg")) @client.slash_command(name="pidozra", description="Оголосити юзеру про підозру") async def pidozra_cmd(ctx: ApplicationContext, user: Option(discord.User, "Юзер сервера"), reason: Option(str, "Причина", required=False, default="Не вказана")): # type: ignore if ctx.author.id in configGet("admins"): if ctx.guild is not None: await pidozra(ctx, user, reason=reason) else: await ctx.respond(content=configGet("denied_guild", "msg")) else: await ctx.respond(content=configGet("denied", "msg")) @client.slash_command(name="nazi", description="Денацифікувати обраного московита") async def nazi(ctx: ApplicationContext, user: Option(discord.User, "Обраний московит")): # type: ignore if ctx.author.id in configGet("admins"): if ctx.guild is not None: userdata = jsonLoad("data.json") logWrite(f"User {user.name}#{user.discriminator} was sent to russian warship by {ctx.author.name}#{ctx.author.discriminator}") await ctx.respond(content=f"{user.mention} {choice(configGet('forbidden_replies'))}", delete_after=4) await asyncio.sleep(3) await user.ban(reason="Московит йобаний", delete_message_days=3) await getChan(user.guild.channels, configGet("captcha_log", "channels", "verification")).send(embed=makeEmbed(title="☠ Юзера послано нахуй", description=f"**Ім'я:** `{user.name}#{user.discriminator}`\n**Адмін:** `{ctx.author.name}#{ctx.author.discriminator}`", color=0xea3319)) try: del userdata[str(user.id)] jsonSave("data.json", userdata) except: pass return else: await ctx.respond(content=configGet("denied_guild", "msg")) else: await ctx.respond(content=configGet("denied", "msg")) #========================================================================================================================= # Utility Commands ======================================================================================================= @client.slash_command(name="debug", description="Переключити режим відлагодження") async def debug(ctx: ApplicationContext, value: Option(bool, "Стан режиму")): # type: ignore if ctx.author.id in configGet("admins"): configSet("debug", value) logWrite(f"User {ctx.author.name}#{ctx.author.discriminator} set debug mode to {str(value)}") await ctx.respond(content=f"Режим відлагодження змінено на `{str(value)}`") else: await ctx.respond(content=configGet("denied", "msg")) @client.slash_command(name="reboot", description="Перезапустити бота") async def reboot(ctx: ApplicationContext): if ctx.author.id in configGet("admins"): logWrite(f"User {ctx.author.name}#{ctx.author.discriminator} called reboot") await ctx.respond(content=f"Вимикаюсь з номером процесу `{os.getpid()}`") os.system(f"kill -9 {os.getpid()}") else: await ctx.respond(content=configGet("denied", "msg")) #========================================================================================================================= # Discord Events ========================================================================================================= @client.event async def on_member_join(member): userdata = jsonLoad("data.json") if str(member.id) not in userdata: captcha = choice(configGet("captchas")) userdata[str(member.id)] = {} userdata[str(member.id)]["captcha"] = captcha else: captcha = userdata[str(member.id)]["captcha"] logWrite(f"User {member.name}#{member.discriminator} joined with (q: '{captcha['question']}' a: {str(captcha['answer'])})") await getChan(member.guild.channels, configGet("captcha_log", "channels", "verification")).send(embed=makeEmbed(title="🆕 Юзер зайшов", description=f"**Ім'я:** `{member.name}#{member.discriminator}`\n**Питання:** `{captcha['question']}`\n**Відповіді:** `{str(captcha['answer'])}`", color=0x6996e4)) await asyncio.sleep(3) sent_msg = await getChan(member.guild.channels, configGet("captcha", "channels", "verification")).send(content=f"{member.mention} Ласкаво просимо!\n\n**{captcha['question']} ...**\n\n```\nПродовжіть речення або надішліть правильну відповідь щоб пройти перевірку\n```", delete_after=1800) userdata[str(member.id)]["question_id"] = sent_msg.id jsonSave("data.json", userdata) await asyncio.sleep(300) userdata = jsonLoad("data.json") if str(member.id) in userdata: try: logWrite(f"User {member.name}#{member.discriminator} ignored verification (q: '{userdata[str(member.id)]['captcha']['question']}' a: {str(userdata[str(member.id)]['captcha']['answer'])})") await getChan(member.guild.channels, configGet("captcha_log", "channels", "verification")).send(embed=makeEmbed(title="🔇 Юзер проігнорував тест", description=f"**Ім'я:** `{member.name}#{member.discriminator}`\n**Питання:** `{userdata[str(member.id)]['captcha']['question']}`\n**Відповіді:** `{str(userdata[str(member.id)]['captcha']['answer'])}`", color=0xffc300)) await getChan(member.guild.channels, configGet("captcha", "channels", "verification")).send(content=f"{member.mention} Тест проігноровано, до побачення", delete_after=4) await asyncio.sleep(3) await member.kick(reason="Ігнорування вступного тесту") del userdata[str(member.id)] jsonSave("data.json", userdata) except: traceback.print_exc() @client.event async def on_member_remove(member): logWrite(f"User {member.name}#{member.discriminator} left") userdata = jsonLoad("data.json") if str(member.id) in userdata: try: await getChan(member.guild.channels, configGet("captcha_log", "channels", "verification")).send(embed=makeEmbed(title="🚪 Юзер вийшов", description=f"**Ім'я:** `{member.name}#{member.discriminator}`\n**Питання:** `{userdata[str(member.id)]['question']}`\n**Відповіді:** `{str(userdata[str(member.id)]['answer'])}`", color=0x6996e4)) except: await getChan(member.guild.channels, configGet("captcha_log", "channels", "verification")).send(embed=makeEmbed(title="🚪 Юзер вийшов", description=f"**Ім'я:** `{member.name}#{member.discriminator}`", color=0x6996e4)) if "question_id" in userdata[str(member.id)]: await rmMsg(configGet("captcha", "channels", "verification"), userdata[str(member.id)]["question_id"]) del userdata[str(member.id)]["question_id"] if userdata[str(member.id)] == {}: del userdata[str(member.id)] jsonSave("data.json", userdata) @client.event async def on_raw_reaction_add(payload): if payload.channel_id == configGet("access", "channels", "nsfw"): if str(payload.emoji) == "✅": logWrite(f"User {payload.member.name}#{payload.member.discriminator} gets NSFW role") await payload.member.add_roles(getChan(payload.member.guild.roles, configGet("nsfw", "roles"))) @client.event async def on_raw_reaction_remove(payload): user = discord.utils.get(client.get_all_members(), id=payload.user_id) if payload.channel_id == configGet("access", "channels", "nsfw"): if str(payload.emoji) == "✅": logWrite(f"User {user.name}#{user.discriminator} lost NSFW role") await user.remove_roles(getChan(user.guild.roles, configGet("nsfw", "roles"))) @client.event async def on_message(message): userdata = jsonLoad("data.json") if message.channel.id == configGet("art", "channels", "general"): await message.add_reaction('🔺') await message.add_reaction('🔻') thread = await message.create_thread(name=f"{message.author.name} ({datetime.now().strftime('%d.%m.%Y')})", auto_archive_duration=10080) await thread.send(content="**Гілку для коментарів створено!**\nНадсилайте коментарі до цієї роботи/фотографії користуючись гілкою.") elif message.channel.id == configGet("captcha", "channels", "verification"): if message.author != client.user: if await is_correct_answer(message.content, userdata[str(message.author.id)]["captcha"]["answer"]): logWrite(f"User {message.author.name}#{message.author.discriminator} verified") await message.reply(content=f"{message.author.mention} Ласкаво просимо!\nУ вас тепер є повний доступ до всього сервера. Приємного спілкування!", delete_after=3) await message.delete() await rmMsg(configGet("captcha", "channels", "verification"), userdata[str(message.author.id)]["question_id"]) await message.author.add_roles(getChan(message.guild.roles, configGet("verified", "roles"))) await getChan(message.author.guild.channels, configGet("captcha_log", "channels", "verification")).send(embed=makeEmbed(title="✅ Юзера верифіковано", description=f"**Ім'я:** `{message.author.name}#{message.author.discriminator}`\n**Питання:** `{userdata[str(message.author.id)]['captcha']['question']}`\n**Відповіді:** `{str(userdata[str(message.author.id)]['captcha']['answer'])}`", color=0xffc300)) await getChan(message.author.guild.channels, configGet("chat", "channels", "general")).send(content=f"У нас поповнення у вигляді {message.author.mention}. Познайомтесь :)") del userdata[str(message.author.id)]["captcha"] del userdata[str(message.author.id)] jsonSave("data.json", userdata) return if message.content.lower().replace(" ", "") in configGet("forbidden_answers"): logWrite(f"User {message.author.name}#{message.author.discriminator} was piece of shit and replied '{message.content}'") await message.reply(content=f"{message.author.mention} {choice(configGet('forbidden_replies'))}", delete_after=4) await message.delete() await rmMsg(configGet("captcha", "channels", "verification"), userdata[str(message.author.id)]["question_id"]) await asyncio.sleep(3) await message.author.ban(reason="Московит йобаний", delete_message_days=1) await getChan(message.author.guild.channels, configGet("captcha_log", "channels", "verification")).send(embed=makeEmbed(title="☠ Юзер руснявий виблядок", description=f"**Ім'я:** `{message.author.name}#{message.author.discriminator}`\n**Питання:** `{userdata[str(message.author.id)]['captcha']['question']}`\n**Відповів:** `{message.content}`\n**Правильні відповіді:** `{str(userdata[str(message.author.id)]['captcha']['answer'])}`", color=0xea3319)) del userdata[str(message.author.id)]["captcha"] del userdata[str(message.author.id)] jsonSave("data.json", userdata) return else: logWrite(f"User {message.author.name}#{message.author.discriminator} failed verification (q: '{userdata[str(message.author.id)]['captcha']['question']}' a: {str(userdata[str(message.author.id)]['captcha']['answer'])} replied: '{message.content}')") await message.reply(content=f"{message.author.mention} відповідь неправильна!\nВідправляйтесь у канал {getChan(message.guild.channels, configGet('verification', 'channels', 'verification')).mention}", delete_after=3) await getChan(message.guild.channels, configGet("verification", "channels", "verification")).send(content=f"Користувач {message.author.mention} потребує перевірки {getChan(message.guild.roles, configGet('admin', 'roles')).mention}\n\nПитання: `{userdata[str(message.author.id)]['captcha']['question']}`\nВідповідь: `{str(userdata[str(message.author.id)]['captcha']['answer'])}`\n\nВідповів: `{message.content}`", delete_after=300) await message.delete() await rmMsg(configGet("captcha", "channels", "verification"), userdata[str(message.author.id)]["question_id"]) await asyncio.sleep(1) await message.author.add_roles(getChan(message.guild.roles, configGet("failed_captcha", "roles"))) await getChan(message.author.guild.channels, configGet("captcha_log", "channels", "verification")).send(embed=makeEmbed(title="☠ Юзер не пройшов", description=f"**Ім'я:** `{message.author.name}#{message.author.discriminator}`\n**Питання:** `{userdata[str(message.author.id)]['captcha']['question']}`\n**Відповів:** `{message.content}`\n**Правильні відповіді:** `{str(userdata[str(message.author.id)]['captcha']['answer'])}`", color=0xea3319)) del userdata[str(message.author.id)]["captcha"] del userdata[str(message.author.id)] jsonSave("data.json", userdata) return elif isinstance(message.channel, discord.DMChannel) and str(message.author.id) in userdata["dms"]: guild = client.get_guild(configGet("guild")) member = guild.get_member(message.author.id) for answer in userdata["dms"][str(message.author.id)]["captcha"]["answer"]: if answer.lower().replace(" ", "") in message.content.lower().replace(" ", "").replace(",", "").replace(".", ""): logWrite(f"User {message.author.name}#{message.author.discriminator} additionally verified") await message.reply(content=f"{message.author.mention} Ласкаво просимо!\nУ вас тепер є повний доступ до всього сервера. Приємного спілкування!") #await rmMsg(message.channel.id, userdata["dms"][str(message.author.id)]["question_id"]) await member.add_roles(guild.get_role(configGet("verified", "roles"))) await member.remove_roles(guild.get_role(configGet("additional_verification", "roles"))) await getChan(guild.channels, configGet("captcha_log", "channels", "verification")).send(embed=makeEmbed(title="✅ Юзера додатково верифіковано", description=f"**Ім'я:** `{message.author.name}#{message.author.discriminator}`\n**Питання:** `{userdata['dms'][str(message.author.id)]['captcha']['question']}`\n**Відповіді:** `{str(userdata['dms'][str(message.author.id)]['captcha']['answer'])}`", color=0xffc300)) del userdata["dms"][str(message.author.id)]["captcha"] del userdata["dms"][str(message.author.id)] jsonSave("data.json", userdata) return if message.content.lower().replace(" ", "") in configGet("forbidden_answers"): logWrite(f"User {message.author.name}#{message.author.discriminator} was piece of shit and replied '{message.content}'") await message.reply(content=f"{choice(configGet('forbidden_replies'))}") await rmMsg(message.channel.id, userdata["dms"][str(message.author.id)]["question_id"]) await member.ban(reason="Московит йобаний", delete_message_days=7) await getChan(guild.channels, configGet("captcha_log", "channels", "verification")).send(embed=makeEmbed(title="☠ Юзер руснявий виблядок", description=f"**Ім'я:** `{message.author.name}#{message.author.discriminator}`\n**Питання:** `{userdata['dms'][str(message.author.id)]['captcha']['question']}`\n**Відповів:** `{message.content}`\n**Правильні відповіді:** `{str(userdata['dms'][str(message.author.id)]['captcha']['answer'])}`", color=0xea3319)) del userdata["dms"][str(message.author.id)]["captcha"] del userdata["dms"][str(message.author.id)] jsonSave("data.json", userdata) return else: logWrite(f"User {message.author.name}#{message.author.discriminator} failed verification (q: '{userdata['dms'][str(message.author.id)]['captcha']['question']}' a: {str(userdata['dms'][str(message.author.id)]['captcha']['answer'])} replied: '{message.content}')") await message.reply(content=f"{message.author.mention} відповідь неправильна!\nВідправляйтесь у канал {getChan(guild.channels, configGet('verification', 'channels', 'verification')).mention}") await getChan(guild.channels, configGet("verification", "channels", "verification")).send(content=f"Користувач {message.author.mention} потребує перевірки {getChan(guild.roles, configGet('admin_id')).mention}", delete_after=300) await rmMsg(message.channel.id, userdata["dms"][str(message.author.id)]["question_id"]) await asyncio.sleep(2) await member.add_roles(guild.get_role(configGet("failed_captcha", "roles"))) await member.remove_roles(guild.get_role(configGet("additional_verification", "roles"))) await getChan(guild.channels, configGet("captcha_log", "channels", "verification")).send(embed=makeEmbed(title="☠ Юзер не пройшов", description=f"**Ім'я:** `{message.author.name}#{message.author.discriminator}`\n**Питання:** `{userdata['dms'][str(message.author.id)]['captcha']['question']}`\n**Відповів:** `{message.content}`\n**Правильні відповіді:** `{str(userdata['dms'][str(message.author.id)]['captcha']['answer'])}`", color=0xea3319)) del userdata["dms"][str(message.author.id)]["captcha"] del userdata["dms"][str(message.author.id)] jsonSave("data.json", userdata) return if "🇷🇺" in message.content: await pidozra(message, message.author, "Прапор московитів") await message.delete() return #========================================================================================================================= client.run(configGet("token"))