2023-06-19 16:39:15 -04:00
import asyncio
import os
2023-06-21 17:41:12 -04:00
import time
2023-06-19 16:39:15 -04:00
import aiohttp
2023-06-19 21:50:15 -04:00
import dotenv
2023-06-21 17:41:12 -04:00
import revolt
2023-06-19 19:10:03 -04:00
from dotenv import load_dotenv
2023-06-21 17:41:12 -04:00
from revolt . ext import commands
2023-06-20 20:31:36 -04:00
from cogs . moderation import Moderation
2023-06-21 22:06:41 -04:00
from cogs . info import Info
2023-06-21 17:41:12 -04:00
from utils . embed import CustomEmbed
2023-06-19 16:39:15 -04:00
2023-06-20 09:39:29 -04:00
# This code reads the variables set in the bot's '.env' file.
2023-06-19 21:50:15 -04:00
env = dotenv . find_dotenv ( )
load_dotenv ( env )
2023-06-19 16:39:15 -04:00
token = os . getenv ( ' TOKEN ' )
api_url = os . getenv ( ' API_URL ' )
2023-06-19 16:47:48 -04:00
prefix = os . getenv ( ' PREFIX ' )
2023-06-30 16:22:45 -04:00
message_logging_channel = os . getenv ( ' MESSAGE_LOGGING_CHANNEL ' )
2023-07-01 11:01:39 -04:00
app_url = os . getenv ( ' APP_URL ' )
2023-06-19 16:39:15 -04:00
2023-06-19 22:28:30 -04:00
class Client ( commands . CommandsClient ) :
2023-06-30 16:22:45 -04:00
""" This class contains all of the commands/methods required for core functionality. Everything else will be relegated to cogs (eventually). """
2023-06-20 01:05:42 -04:00
async def get_prefix ( self , message : revolt . Message , input : str | None = None ) : # pylint: disable=W0622
2023-06-20 01:02:22 -04:00
if input is None :
return prefix
2023-06-19 21:50:15 -04:00
return input
2023-06-20 01:06:40 -04:00
2023-06-30 16:22:45 -04:00
async def on_message_delete ( self , message : revolt . Message ) :
if isinstance ( message . author , revolt . Member ) :
2023-06-30 16:26:22 -04:00
if message . author . bot is True :
2023-06-30 16:22:45 -04:00
return
2023-06-30 16:26:22 -04:00
truncated_content = message . content [ : 1500 ] + " ... "
embed = [ CustomEmbed ( description = f " ## Message Deleted in { message . channel . mention } \n **Author:** { message . author . name } # { message . author . discriminator } ( { message . author . id } ) \n **Content:** { message . content } " , colour = " #5d82d1 " ) , CustomEmbed ( description = f " ## Message Deleted in { message . channel . mention } \n **Author:** { message . author . name } # { message . author . discriminator } ( { message . author . id } ) \n **Content:** { truncated_content } \n \n *Message content is over the character limit.* " , colour = " #5d82d1 " ) ]
2023-06-30 16:22:45 -04:00
embed [ 0 ] . set_footer ( f " Message ID: { message . id } " )
2023-06-30 16:26:22 -04:00
embed [ 1 ] . set_footer ( f " Message ID: { message . id } " )
2023-06-30 16:30:24 -04:00
channel = self . get_channel ( message_logging_channel )
2023-06-30 16:22:45 -04:00
try :
try :
2023-06-30 16:30:24 -04:00
await channel . send ( embed = embed [ 0 ] )
2023-06-30 16:22:45 -04:00
except LookupError :
print ( " Message logging channel not found for server ID: " + message . server . id )
except ( revolt . errors . HTTPError ) :
try :
2023-06-30 16:30:24 -04:00
await channel . send ( embed = embed [ 1 ] )
2023-06-30 16:22:45 -04:00
except LookupError :
print ( " Message logging channel not found for server ID: " + message . server . id )
else :
print ( f " { message . author . name } # { message . author . discriminator } ( { message . author . id } ): { message . content } \n ⤷ Deleted from Direct Messages \n Message ID: { message . id } " )
2023-07-01 10:50:27 -04:00
async def on_message_update ( self , before : revolt . Message , message : revolt . Message ) :
if isinstance ( message . author , revolt . Member ) :
if message . author . bot is True :
return
2023-07-01 11:01:39 -04:00
message_link = f " { app_url } /server/ { message . server . id } /channel/ { message . channel . id } /message/ { message . id } "
embeds = [ CustomEmbed ( description = f " ## Message Edited in { message . channel . mention } \n **Author:** { message . author . name } # { message . author . discriminator } ( { message . author . id } ) \n **Message ID:** [ { message . id } ]( { message_link } ) " , colour = " #5d82d1 " ) , CustomEmbed ( title = " Old Content " , description = before . content , colour = " #5d82d1 " ) , CustomEmbed ( title = " New Content " , description = message . content , colour = " #5d82d1 " ) ]
2023-07-01 10:50:27 -04:00
channel = self . get_channel ( message_logging_channel )
try :
await channel . send ( embed = embeds [ 0 ] )
await channel . send ( embed = embeds [ 1 ] )
await channel . send ( embed = embeds [ 2 ] )
except LookupError :
print ( " Message logging channel not found for server ID: " + message . server . id )
else :
print ( f " { message . author . name } # { message . author . discriminator } ( { message . author . id } ): { before . content } \n ⤷ Edited in Direct Messages \n New Content: { message . content } " )
2023-06-19 17:15:19 -04:00
2023-06-19 16:39:15 -04:00
@commands.command ( )
async def ping ( self , ctx : commands . Context ) :
2023-06-30 16:22:45 -04:00
""" This command checks the bot ' s latency. """
2023-06-19 19:01:43 -04:00
before = time . monotonic ( )
2023-07-01 09:59:18 -04:00
msg = await ctx . message . reply ( " 🏓 " )
2023-06-19 19:01:43 -04:00
ping = ( time . monotonic ( ) - before ) * 1000
2023-06-21 17:41:12 -04:00
embeds = [ CustomEmbed ( title = " 🏓 Pong! " , description = f " ` \n { int ( ping ) } ms` " , colour = " #5d82d1 " ) ]
2023-07-01 09:59:18 -04:00
await msg . edit ( content = " " , embeds = embeds )
2023-06-19 19:01:43 -04:00
print ( f ' Ping { int ( ping ) } ms ' )
2023-06-19 16:39:15 -04:00
@commands.command ( )
2023-06-22 20:01:04 -04:00
async def avatar ( self , ctx : commands . Context , target : commands . UserConverter ) :
2023-06-30 16:22:45 -04:00
""" This command retrieves a user ' s avatar. - NOTE: Move to cog """
2023-06-19 21:50:15 -04:00
if not isinstance ( target , revolt . User ) :
2023-06-19 22:23:40 -04:00
await ctx . message . reply ( " Please provide a user argument! " )
2023-06-19 16:39:15 -04:00
return
2023-06-19 21:50:15 -04:00
avatar = target . avatar . url
2023-06-19 22:23:40 -04:00
await ctx . message . reply ( f " { avatar } " )
2023-06-19 16:39:15 -04:00
2023-06-20 01:02:22 -04:00
async def prefix_change ( self , message : revolt . Message , new_prefix : str , silent : bool | None = False ) :
2023-06-20 01:05:42 -04:00
dotenv . set_key ( env , ' PREFIX ' , new_prefix )
if silent is not True :
await message . reply ( f " Prefix has been changed from ` { prefix } ` to ` { new_prefix } `! " )
print ( f " Prefix changed: { prefix } → { new_prefix } " )
await Client . get_prefix ( message , new_prefix )
2023-06-20 01:02:22 -04:00
2023-06-19 21:50:15 -04:00
@commands.command ( )
async def prefix ( self , ctx : commands . Context , new_prefix : str = None ) :
2023-06-30 16:22:45 -04:00
""" This command sets the bot ' s prefix. CURRENTLY BROKEN """
2023-06-20 10:36:13 -04:00
if new_prefix is not None and ctx . author . id == ctx . client . user . owner_id :
2023-06-20 01:02:22 -04:00
await Client . prefix_change ( self = self , message = ctx . message , new_prefix = new_prefix )
2023-06-19 21:50:15 -04:00
else :
2023-06-19 22:23:40 -04:00
await ctx . message . reply ( f " The prefix is currently set to ` { prefix } `. " )
2023-06-19 21:50:15 -04:00
2023-06-19 16:39:15 -04:00
async def main ( ) :
2023-06-30 16:22:45 -04:00
""" This function logs into the bot user. """
2023-06-19 16:39:15 -04:00
async with aiohttp . ClientSession ( ) as session :
2023-06-19 22:28:30 -04:00
client = Client ( session , token , api_url = api_url )
2023-06-20 12:28:40 -04:00
client . add_cog ( Moderation ( client ) )
2023-06-21 22:06:41 -04:00
client . add_cog ( Info ( client ) )
2023-06-19 16:39:15 -04:00
await client . start ( )
2023-06-19 17:11:20 -04:00
asyncio . run ( main ( ) )