import asyncio import json import os import os.path import platform import random import sys import aiohttp import aiosqlite import random from random import randint import requests from requests import get import time import datetime from datetime import datetime, timedelta, timezone import discord from discord.ext import commands, tasks from discord.ext.commands import Bot, Context from discord.utils import get import exceptions from helpers import checks # --------------------------------------------------------------------------------------- # Loads config.json # --------------------------------------------------------------------------------------- if not os.path.isfile("config.json"): sys.exit("'config.json' not found! Please add it and try again.") else: with open("config.json") as file: config = json.load(file) # --------------------------------------------------------------------------------------- # Intents Listing # --------------------------------------------------------------------------------------- intents = discord.Intents.all() intents.members = True intents.message_content = True intents.messages = True # `message_content` is required to get the content of the messages intents.presences = True intents.bans = True intents.dm_messages = True intents.dm_reactions = True intents.dm_typing = True intents.emojis = True intents.emojis_and_stickers = True intents.guild_messages = True intents.guild_reactions = True intents.guild_scheduled_events = True intents.guild_typing = True intents.guilds = True intents.integrations = True intents.invites = True intents.reactions = True intents.typing = True intents.voice_states = True intents.webhooks = True # --------------------------------------------------------------------------------------- # Def what happend on mention or msg # --------------------------------------------------------------------------------------- bot = Bot(command_prefix=commands.when_mentioned_or( config["prefix"]), intents=intents, help_command=None) bot.config = config # --------------------------------------------------------------------------------------- # DB Set # --------------------------------------------------------------------------------------- async def init_db(): async with aiosqlite.connect(f"{os.path.realpath(os.path.dirname(__file__))}/database/database.db") as db: with open(f"{os.path.realpath(os.path.dirname(__file__))}/database/schema.sql") as file: await db.executescript(file.read()) await db.commit() # --------------------------------------------------------------------------------------- # Webhook Logs # --------------------------------------------------------------------------------------- url = config["webhook"] def weblogsend(msg): data = { "content" : msg, "username": {context.author} } result = requests.post(url, json = data) try: result.raise_for_status() except requests.exceptions.HTTPError as err: print(err) else: print("Payload delivered successfully, code {}.".format(result.status_code)) # --------------------------------------------------------------------------------------- # Bot Ready Start # --------------------------------------------------------------------------------------- @bot.event async def on_ready() -> None: guilds = [guild.id for guild in bot.guilds] print("--------------------------------------") print(f"Logged in as {bot.user.name}") print(f"discord.py API version: {discord.__version__}") print(f"Python version: {platform.python_version()}") print(f"Running on: {platform.system()} {platform.release()} ({os.name})") print("--------------------------------------") print(f"The {bot.user.name} bot is in {len(guilds)} Guilds.\nThe guilds ids list : {guilds}") print("--------------------------------------") status_task.start() if config["sync_commands_globally"]: print("Syncing commands globally...") await bot.tree.sync() # --------------------------------------------------------------------------------------- # Presence Loop # --------------------------------------------------------------------------------------- @tasks.loop(minutes=5) async def status_task() -> None: activity = discord.Activity(name=f"over {len(bot.guilds)} guilds\nand {len(bot.users)} users!", type=discord.ActivityType.watching) await bot.change_presence(activity=activity) # --------------------------------------------------------------------------------------- # User joins guild events # --------------------------------------------------------------------------------------- @bot.event async def on_member_join(member) -> None: role = member.guild.get_role(1061402091542806648) # await member.add_roles(role, reason="Automatic role by bot") embed = ( (f"|| <@&MENTION_ROLE_ID> ||\nHello {member.mention}") # MENTION_ROLE_ID = ID of role the will be mentioned on [member.guild_join] ) discord.Embed( description=(f"Welcome to 🐱‍🚀{member.guild.name}!\nHope you enjoy your time here."), color=0x9C84EF ) embed.set_author( name="Welcome" ) embed.add_field( name="Embed Field Name", value="`➖➖➖➖➖➖➖➖➖`\n> **Frostbite Hosting**\n`🔗` [DISCORD SERVER]()\n`➖➖➖➖➖➖➖➖➖`\n> **Frostbite Hosting**\n`🔗` [Free Bot Hosting]()\n`➖➖➖➖➖➖➖➖➖`", inline=False ) channel = await bot.fetch_channel(GUILD_WELCOME_CHANNEL_ID) # Replace GUILD_WELCOME_CHANNEL_ID with to the channel ID where it should announce the embed. await channel.send(embed=embed) await member.send(embed=embed) # --------------------------------------------------------------------------------------- # The code in this event is executed every time someone sends a message, with or without the prefix # --------------------------------------------------------------------------------------- @bot.event async def on_message(message: discord.Message): if message.author.id == bot.user.id or message.author.bot: return if not message.guild: logchannel = bot.get_guild(guild_id).get_channel(channel_id) # Define the log channel when someone DM's the bot with [guild ID] and [channel ID] embed = discord.Embed( title="User MSG BOT DMs ", colour=0x000, description=f"**From:** {message.author.mention}\n\n*{message.content}*" ) embed.set_footer( text=message.author, icon_url=message.author.avatar.url ) await logchannel.send(embed=embed) await bot.process_commands(message) # --------------------------------------------------------------------------------------- # Error handling # This is global error handling, if you for instance want to except every CommandOnCooldown exception, you can do it like this # --------------------------------------------------------------------------------------- # on_command_completion # --------------------------------------------------------------------------------------- @bot.event async def on_command_completion(context: Context) -> None: full_command_name = context.command.qualified_name split = full_command_name.split(" ") executed_command = str(split[0]) if context.guild is not None: print( f"Executed {executed_command} command in {context.guild.name} (ID: {context.guild.id}) by {context.author} (ID: {context.author.id})") else: print( f"Executed {executed_command} command by {context.author} (ID: {context.author.id}) in DMs") # --------------------------------------------------------------------------------------- # on_command_error # --------------------------------------------------------------------------------------- @bot.event async def on_command_error(context: Context, error) -> None: if isinstance(error, commands.CommandOnCooldown): minutes, seconds = divmod(error.retry_after, 60) hours, minutes = divmod(minutes, 60) hours = hours % 24 embed = discord.Embed( title="Hey, Stop that . you will break me", description=f"You can use this command again in {f'{round(hours)} hours' if round(hours) > 0 else ''} {f'{round(minutes)} minutes' if round(minutes) > 0 else ''} {f'{round(seconds)} seconds' if round(seconds) > 0 else ''}.", color=0xE02B2B ) await context.send(embed=embed) elif isinstance(error, exceptions.UserBlacklisted): embed = discord.Embed( title="Error!", description="You are blacklisted from using the bot.", color=0xE02B2B ) await context.send(embed=embed) elif isinstance(error, exceptions.UserNotOwner): embed = discord.Embed( title="Error!", description="You are not the owner of the bot!", color=0xE02B2B ) await context.send(embed=embed) elif isinstance(error, commands.MissingPermissions): embed = discord.Embed( title="Error!", description="You are missing the permission(s) `" + ", ".join( error.missing_permissions) + "` to execute this command!", color=0xE02B2B ) await context.send(embed=embed) elif isinstance(error, commands.MissingRequiredArgument): embed = discord.Embed( title="Error!", # We need to capitalize because the command arguments have no capital letter in the code. description=str(error).capitalize(), color=0xE02B2B ) await context.send(embed=embed) raise error # --------------------------------------------------------------------------------------- # Load COGS for this bot # --------------------------------------------------------------------------------------- async def load_cogs() -> None: for file in os.listdir(f"./cogs"): if file.endswith(".py"): extension = file[:-3] try: await bot.load_extension(f"cogs.{extension}") print(f"Loaded extension '{extension}'") except Exception as e: exception = f"{type(e).__name__}: {e}" print(f"Failed to load extension {extension}\n{exception}") # --------------------------------------------------------------------------------------- # LEGACY BOT COMMANDS # --------------------------------------------------------------------------------------- # [perfix]groupDM {<@&role>} (message) # --------------------------------------------------------------------------------------- @bot.command() @checks.is_owner() async def groupDM(context, role: discord.Role, *, message: str) -> None: for member in role.members: await member.send(message) # --------------------------------------------------------------------------------------- # LIST categories, text channels, voice channels, all channels + categories # --------------------------------------------------------------------------------------- # Categories # --------------------------------------------------------------------------------------- @bot.command() @checks.is_owner() async def cata(context) -> None: # async def cat(context): for category in context.message.guild.categories: # for category in context.message.guild.categories: await context.send(f"`{category.id}` - <#{category.id}>") # print(category.name) # --------------------------------------------------------------------------------------- # Text channels # --------------------------------------------------------------------------------------- @bot.command() @checks.is_owner() async def txtChannel(context) -> None: for text_channel in context.message.guild.text_channels: await context.send(f"`{text_channel.id}` - <#{text_channel.id}>") # --------------------------------------------------------------------------------------- # Voice channels # --------------------------------------------------------------------------------------- @bot.command() @checks.is_owner() async def vc(context) -> None: for voice_channel in context.message.guild.voice_channels: await context.send(f"`{voice_channel.id}` - <#{voice_channel.id}>") # --------------------------------------------------------------------------------------- # All Channels + Categories # --------------------------------------------------------------------------------------- @bot.command() @checks.is_owner() async def channels(context) -> None: for channel in context.message.guild.channels: await context.send(f"`{channel.id}` - <#{channel.id}>") # --------------------------------------------------------------------------------------- # BOT logs on_guild_join # --------------------------------------------------------------------------------------- @bot.event async def on_guild_join(guild) -> None: print(guild.name) print(guild.id) # --------------------------------------------------------------------------------------- # BOT logs on_guild_leave # --------------------------------------------------------------------------------------- @bot.event async def on_guild_leave(guild) -> None: print(guild.name) print(guild.id) # --------------------------------------------------------------------------------------- # verify into the server # --------------------------------------------------------------------------------------- @bot.command() async def verifyme(context, member=None) -> None: verifyrole = discord.utils.get(context.guild.roles, name="ROLE_NAME") # YOU MUST SPECIFY THE ROLE NAME try: await context.author.add_roles(verifyrole) except Exception as errortoaddroles: await context.send(f'Error in add roles\n```py\n{errortoaddroles}```') await context.message.delete() await member.send(f'{context.author} | {context.author.id} Should now be verified.') # --------------------------------------------------------------------------------------- # Countdown/timer # --------------------------------------------------------------------------------------- @bot.command() async def countdown(ctx, t: int): await ctx.send(f"Counting down from {t}s") while t > 0: t -= 1 # Sleep for 1 second await asyncio.sleep(1) await ctx.send("Countdown end reached") # --------------------------------------------------------------------------------------- # Creating a role, only specifying it's name # --------------------------------------------------------------------------------------- @bot.command() async def create_role(ctx, *, name): # Create the role await ctx.guild.create_role(name=name) await ctx.send(f"Created role with name {name}") # --------------------------------------------------------------------------------------- # Adding a role to everybody in the server # --------------------------------------------------------------------------------------- @bot.command() async def addroles(ctx, *, role: discord.Role): for m in ctx.guild.members: await m.add_roles(role) await asyncio.sleep(1) await ctx.send("Added roles") # --------------------------------------------------------------------------------------- # You can also specify specific users to add a role to: # --------------------------------------------------------------------------------------- @bot.command() async def addrole(ctx, role: discord.Role, *members: discord.Member): for m in members: await m.add_roles(role) print(f":white_check_mark: Role {role} added to {m.mention}") # --------------------------------------------------------------------------------------- # Sending messages *, arg is useful if you want to consume all as a string # --------------------------------------------------------------------------------------- @bot.command() async def echo(ctx, *, message): # Delete message that invokes command await ctx.delete() # Repeat back the input and auto delete after 20 seconds await ctx.send(message, delete_after=20) # --------------------------------------------------------------------------------------- # Sending messages You can loop over each text channel in a guild, and send a message # --------------------------------------------------------------------------------------- @bot.command() async def sendToAll(ctx, *, message): for channel in ctx.guild.text_channels: await channel.send(message) # --------------------------------------------------------------------------------------- # User info # --------------------------------------------------------------------------------------- def getstatus(m): if str(m.status) == "dnd": return "do not disturb" return m.status @bot.command() async def userinfo(ctx, member: discord.Member): c_delta = datetime.utcnow() c_at = member.created_at.strftime("%c") join_pos = sorted(ctx.guild.members, key=lambda member: member.joined_at).index(member) + 1 embed = discord.Embed( title=f"{member.name}#{member.discriminator}", timestamp=datetime.utcnow(), colour=0x000 ) embed.add_field( name="Status:", value=getstatus(member), inline=True ) embed.add_field( name="Guild name:", value=member.display_name, inline=True ) embed.add_field( name="Join position:", value=f"{join_pos}/{len(ctx.guild.members)}", inline=True ) embed.add_field( name="Created at:", value=f"{c_at}", inline=True ) embed.add_field( name="ID:", value=member.id, inline=True ) embed.add_field( name="Bot:", value="✅ Yes" if member.bot else "❌ No", inline=True ) # Setting the thumbnail as the users profile picture embed.set_thumbnail( url=member.avatar ) # Setting a footer embed.set_footer( text=f"Requested by {ctx.author.name}", icon_url=ctx.author.avatar ) await ctx.send(embed=embed) # --------------------------------------------------------------------------------------- # Background task and command group # We can make command groups which will allow us make subcommands # --------------------------------------------------------------------------------------- @tasks.loop(seconds=60) # Loop every 60 seconds async def loop_function(ctx, message): await ctx.send(message) @bot.group(invoke_without_command=True) # Specify that we don't want the 'first' command called when we use a subcommand async def loop(ctx): await ctx.send("**1.** Start loop: `.loop start {message}`\n**2.** Stop loop: `.loop stop`") @loop.command() # Subcommand named 'start', so called like this: "PREFIXloop start message goes here" async def start(ctx, *, message): await ctx.send("**Starting loop...**") # Starting the loop function loop_function.start(ctx, message) @loop.command() # Subcommand named stop async def stop(ctx): await ctx.send("**Stopping loop...**") # Stopping the loop loop_function.stop() # --------------------------------------------------------------------------------------- # Getting online members/offline members # --------------------------------------------------------------------------------------- @bot.command() async def online(ctx): online_m, offline_m = [], [] # Loop over each member in guild.members for m in ctx.guild.members: # Add to list of online members (online_m) if status is online/dnd, else add to offline_m (online_m if str(m.status) in ("online", "dnd") else offline_m).append(str(m)) await ctx.send(f"Online: {', '.join(online_m)}\nOffline: {', '.join(offline_m)}") # --------------------------------------------------------------------------------------- # Fetching audit log # --------------------------------------------------------------------------------------- @bot.command() async def logs(ctx): actions = [] async for entry in ctx.guild.audit_logs(limit = 10): time = entry.created_at.strftime("%d-%m-%Y %H:%M:%S") actions.append(f"`{entry.user}` did `{entry.action}` at `{time}` to `{entry.target}`\n\n") embed = discord.Embed( title="Audit log", description=''.join(actions), colour=0x000 ) await ctx.send(embed=embed) # --------------------------------------------------------------------------------------- # Evaluates customized code # --------------------------------------------------------------------------------------- @bot.command(aliases=['e', 'evaluate']) @commands.is_owner() async def eval(context, *, code): """Evaluates customized code""" language_specifiers = ["python", "py", "javascript", "js", "html", "css", "php", "md", "markdown", "go", "golang", "c", "c++", "cpp", "c#", "cs", "csharp", "java", "ruby", "rb", "coffee-script", "coffeescript", "coffee", "bash", "shell", "sh", "json", "http", "pascal", "perl", "rust", "sql", "swift", "vim", "xml", "yaml"] loops = 0 while code.startswith("`"): code = "".join(list(code)[1:]) loops += 1 if loops == 3: loops = 0 break for language_specifier in language_specifiers: if code.startswith(language_specifier): code = code.lstrip(language_specifier) try: while code.endswith("`"): code = "".join(list(code)[0:-1]) loops += 1 if loops == 3: break code = "\n".join(f" {i}" for i in code.splitlines()) code = f"async def eval_expr():\n{code}" def send(text): bot.loop.create_task(context.send(text)) env = { "bot": bot, "client": bot, "context": context, "print": send, "_author": context.author, "_message": context.message, "_channel": context.channel, "_guild": context.guild, "_me": context.me } env.update(globals()) exec(code, env) eval_expr = env["eval_expr"] result = await eval_expr() await context.message.add_reaction("\N{WHITE HEAVY CHECK MARK}") if result: await context.send(result) except Exception as learntofuckingcode: await context.message.add_reaction("\N{WARNING SIGN}") await context.send(f'**Error**```py\n{learntofuckingcode}```') # --------------------------------------------------------------------------------------- # RUN BOT # --------------------------------------------------------------------------------------- asyncio.run(init_db()) asyncio.run(load_cogs()) bot.run(config["token"])