import contextlib
import json
import logging
import os
import platform
import random
import string
import time
import traceback
from typing import Union
import discord
from captcha.image import ImageCaptcha
from colorama import Back, Fore, Style
from discord import ui
from discord.ext import commands
import settings
logger = settings.logging.getLogger("bot")
config = None
verify_channel = None
verify_role = None
verify_guild = None
length = 6
def run():
class PersistentViewBot(commands.Bot):
def __init__(self):
intents = discord.Intents().all()
super().__init__(command_prefix="-", intents=intents)
async def setup_hook(self) -> None:
self.add_view(VerifyButton())
bot = PersistentViewBot()
@bot.event
async def on_ready():
global config
global verify_channel
global verify_role
global verify_guild
prfx = (
Fore.BLUE
+ time.strftime("%H:%M:%S PST", time.localtime())
+ Back.RESET
+ Fore.WHITE
+ Style.BRIGHT
)
print(f"{prfx} Loading config... {Fore.CYAN}")
# for cmd_file in settings.CMDS_DIR.glob("*.py"):
# if cmd_file.name != "__init__.py":
# await bot.load_extension(f"cmds.{cmd_file.name[:-3]}")
try:
config = json.loads(open("config.json", "r").read())
except Exception:
print(f"{prfx} No config found! Run -setup in your server!")
else:
verify_guild = bot.get_guild(config["guild"])
verify_channel = bot.get_channel(config["channel"])
verify_role = verify_guild.get_role(config["role"])
synced = await bot.tree.sync()
print(f"{prfx} Slash CMDs Synced {len(synced)} Commands")
logger.info(f"User: {bot.user} (ID: {bot.user.id})")
class VerifyButton(discord.ui.View):
def __init__(self, variable):
super().__init__(timeout=None)
@discord.ui.button(label="verify", custom_id="verify_button")
async def verify(
self, interaction: discord.Interaction, Button: discord.ui.Button
):
global config
global verify_channel
global verify_role
global verify_guild
text = "".join(
random.choice(
string.ascii_uppercase + string.digits + string.ascii_lowercase
)
for _ in range(length)
)
file_name = "".join(
random.choice(
string.ascii_uppercase + string.digits + string.ascii_lowercase
)
for _ in range(20)
)
image = ImageCaptcha(width=280, height=90)
captcha = image.generate(text)
# Print Captcha Text
print(text)
image.write(text, f"captchas\\{file_name}.png")
file = discord.File(
f"captchas//{file_name}.png", filename=f"{file_name}.png"
)
embed = discord.Embed(
title="Verification",
description="This server is using Captcha Verification\n to protect their server.\n\nPlease type out the letters you see in\nthe captcha below.\n\n**Note:** The captcha is **case-sensitive.**",
color=0x000001,
)
embed.set_footer(text="Captcha Verification by /bran#6666")
embed.set_image(url=f"attachment://{file_name}.png")
await interaction.response.send_message(
embed=embed,
file=file,
ephemeral=True,
view=MyView2(),
)
class MyView2(discord.ui.View):
def __init__(self):
super().__init__(timeout=None)
@discord.ui.button(
label="Input Code",
row=0,
style=discord.ButtonStyle.secondary,
custom_id="InputCode",
)
async def button_callback(self, interaction, button):
await interaction.response.send_modal(MyModal())
print("Modal has been sent successfully")
class MyModal(ui.Modal, title="Verification"):
code = ui.TextInput(
label="Captcha",
placeholder="Input Captcha Code",
style=discord.TextStyle.short,
)
async def on_submit(self, interaction: discord.Interaction):
try:
if code == text:
await interaction.user.add_roles(verify_role)
await interaction.response.send_message(
"You have been verified!", ephemeral=True
)
if code != text:
await interaction.response.send_message(
"Incorrect captcha code, please try again."
)
return
except:
pass
@bot.tree.command(name="verify")
async def verify(interaction: discord.Interaction):
buttembed = discord.Embed(
title="This is a test embed",
description="I hate Discord bots.",
color=0x000001,
)
buttembed.set_footer(text="Captcha Verification by /bran#6666")
await interaction.channel.send(
content="",
embed=buttembed,
view=VerifyButton(),
)
@bot.event
async def on_channel_create(channel):
global config
global verify_channel
global verify_role
global verify_guild
if channel.id == int(config["channel"]):
try:
overwrites = {
verify_role: discord.PermissionOverwrite(
read_messages=False, send_messages=False, add_reactions=False
)
}
await channel.edit(overwrites=overwrites)
except:
pass
@bot.command()
@commands.guild_only()
@commands.has_permissions(administrator=True)
async def setup(ctx):
if os.path.exists("config.json"):
await ctx.send("config.json already exists!")
return
global config
msg = await ctx.send("Setting up guild...")
role = await ctx.guild.create_role(name="Verifing")
for channel in ctx.guild.channels:
try:
overwrites = {
role: discord.PermissionOverwrite(
read_messages=False, send_messages=False, add_reactions=False
)
}
await channel.edit(overwrites=overwrites)
except:
pass
overwrites = {
ctx.guild.default_role: discord.PermissionOverwrite(
read_messages=False,
send_messages=False,
),
role: discord.PermissionOverwrite(
read_messages=True,
send_messages=True,
),
}
channel = await ctx.guild.create_text_channel(
name="verify-here", overwrites=overwrites, slowmode_delay=10
)
con_json = {"role": role.id, "channel": channel.id, "guild": ctx.guild.id}
config = con_json
with open("config.json", "a") as conf:
conf.write(json.dumps(con_json))
await msg.edit(content="Finished Setup!")
@bot.command()
@commands.guild_only()
@commands.has_permissions(administrator=True)
async def perms_setup(ctx):
if not os.path.exists("config.json"):
await ctx.send("config.json doesn't exists!")
return
global config
msg = await ctx.send("Rechecking perms...")
for channel in ctx.guild.channels:
try:
overwrites = {
verify_role: discord.PermissionOverwrite(
read_messages=False, send_messages=False, add_reactions=False
)
}
await channel.edit(overwrites=overwrites)
except:
pass
overwrites = {
ctx.guild.default_role: discord.PermissionOverwrite(
read_messages=False,
send_messages=False,
),
verify_role: discord.PermissionOverwrite(
read_messages=True,
send_messages=True,
),
}
await msg.edit("Finished Setup!")
bot.run(settings.DISCORD_TOKEN, root_logger=True)
if __name__ == "__main__":
run()