Making the checks into functions to decrease repeated lines of code

Moving starboard commands into here
Adding starboard status into the modstatus command
Making modmail/starboard into classes
pull/9/head
sgoudham 4 years ago
parent 986b65cbc1
commit 92bf0415b8

@ -14,151 +14,111 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
import asyncio
import datetime import datetime
import io
import random
import asyncpg import asyncpg
import discord
from discord import Embed, TextChannel from discord import Embed, TextChannel
from discord import File
from discord.ext.commands import has_permissions, Cog, group, bot_has_permissions, BadArgument, MissingRequiredArgument, \ from discord.ext.commands import has_permissions, Cog, group, bot_has_permissions, BadArgument, MissingRequiredArgument, \
command command
from cogs.libs.modmail import Modmail
from cogs.libs.starboard import Starboard
def anon_or_not(self, author):
"""Method to ask the user if they want to be anonymous or not"""
# Set up embed to let the user how to start sending modmail async def get_starboard_from_db(self, ctx, action):
AnonModMailEmbed = Embed(title="**Want to send it Anonymously?**", """Get the starboard record from DB"""
colour=self.bot.admin_colour,
timestamp=datetime.datetime.utcnow())
AnonModMailEmbed.set_thumbnail(url=author.avatar_url) # Setup up pool connection
AnonModMailEmbed.set_footer(text=f"Sent by {author}") pool = self.bot.db
async with pool.acquire() as conn:
fields = [(self.bot.blank_space, "**We understand that for some things," # Get the row of the guild from the starboard table
"you may want to remain Anonymous." try:
"\nUse the reactions below to choose!**", False), select_query = """SELECT * FROM starboard WHERE guild_id = $1"""
(self.bot.blank_space, "**Use :white_check_mark: for** `Yes`", True), result = await conn.fetchrow(select_query, ctx.guild.id)
(self.bot.blank_space, "**Use :x: for** `No`", True),
(self.bot.blank_space, self.bot.blank_space, True),
(self.bot.blank_space,
"The Staff will not know who is sending this"
"\nPurely negative feedback will not be considered.", True)]
for name, value, inline in fields:
AnonModMailEmbed.add_field(name=name, value=value, inline=inline)
return AnonModMailEmbed
def send_instructions(self, author):
"""Method to send an embed to to let the user know to type into chat"""
SendModMailEmbed = Embed(title="**Please enter a message for it to be sent to the staff!**",
colour=self.bot.admin_colour,
timestamp=datetime.datetime.utcnow())
SendModMailEmbed.set_thumbnail(url=author.avatar_url)
SendModMailEmbed.set_footer(text=f"Sent by {author}")
fields = [("**Make sure that the message is above **50** and below **1024** characters!**",
"**Include as much detail as possible :P**",
False)]
for name, value, inline in fields:
SendModMailEmbed.add_field(name=name, value=value, inline=inline)
return SendModMailEmbed
def error_handling(self, author):
"""Method to let the user know that the message must be above 50 characters"""
ErrorHandlingEmbed = Embed(
title="Uh Oh! Please make sure the message is above **50** and below **1024** characters!",
colour=self.bot.admin_colour,
timestamp=datetime.datetime.utcnow())
ErrorHandlingEmbed.set_thumbnail(url=author.avatar_url)
ErrorHandlingEmbed.set_footer(text=f"Sent by {author}")
fields = [("Please enter in a message which is above **50** and below **1024** characters!",
"**This helps us reduce spam and allows you to include more detail in your mail!**",
False)]
for name, value, inline in fields:
ErrorHandlingEmbed.add_field(name=name, value=value, inline=inline)
return ErrorHandlingEmbed
def message_sent_confirmation(self, author):
"""Method to send an embed into chat to let the user know that their mail has been sent successfully"""
ConfirmationEmbed = Embed(title="**Message relayed to Staff!!**",
colour=self.bot.admin_colour,
timestamp=datetime.datetime.utcnow())
ConfirmationEmbed.set_thumbnail(url=author.avatar_url)
ConfirmationEmbed.set_footer(text=f"Sent by {author}")
fields = [("Thank you for your input! The staff team appreciate it very much!", # Catch errors
f"\n As mentioned previously, please don't be hesistant to DM the Staff for anything! :P", except asyncpg.PostgresError as e:
False)] print("PostGres Error: Starboard Record Could Not Be Retrieved For Starboard", e)
for name, value, inline in fields: # Throw error if the guild already exists
ConfirmationEmbed.add_field(name=name, value=value, inline=inline) else:
if action == "setup" and result:
text = "**Starboard** Already Setup!" \
f"\nDo **{ctx.prefix}help starboard** to find out more!"
await self.bot.generate_embed(ctx, desc=text)
return None
elif (action == "update" or action == "delete") and not result:
text = "**Starboard** Not Setup!" \
f"\nDo **{ctx.prefix}help starboard** to find out more!"
await self.bot.generate_embed(ctx, desc=text)
return None
return ConfirmationEmbed return not None
def send_modmail(self, msg, author): async def get_modlogs_from_db(self, ctx, action):
"""Method to actually allow the message to be sent to modmail logging channel""" """Get the starboard record from DB"""
embed = Embed(title="Modmail", # Setup up pool connection
colour=self.bot.admin_colour, pool = self.bot.db
timestamp=datetime.datetime.utcnow()) async with pool.acquire() as conn:
if self.anon: # Get the entire row of the guild from the guilds table
try:
select_query = """SELECT * FROM guilds WHERE guild_id = $1"""
result = await conn.fetchrow(select_query, ctx.guild.id)
embed.set_thumbnail(url=random.choice(self.avatars)) # Catch errors
embed.set_footer(text=f"Sent By Anon Member") except asyncpg.PostgresError as e:
print("PostGres Error: Modlog Record Could Not Be Retrieved For Modlogs", e)
fields = [("Member", "Anon Member", False), # Throw error if the modlogs already exists
("Message", msg.content, False)] else:
else: if action == "setup" and result["modlogs"]:
text = "**Modlogs** Already Setup!" \
f"\nDo **{ctx.prefix}help modlogs** to find out more!"
await self.bot.generate_embed(ctx, desc=text)
return None
elif (action == "update" or action == "delete") and not result["modlogs"]:
text = "**Modlogs** Not Setup!" \
f"\nDo **{ctx.prefix}help modlogs** to find out more!"
await self.bot.generate_embed(ctx, desc=text)
return None
embed.set_thumbnail(url=author.avatar_url) return not None
embed.set_footer(text=f"Sent By {author}")
fields = [("Member", author, False),
("Message", msg.content, False)]
for name, value, inline in fields: async def get_modmail_from_db(self, ctx, action):
embed.add_field(name=name, value=value, inline=inline) """Get the starboard record from DB"""
return embed # Setup up pool connection
pool = self.bot.db
async with pool.acquire() as conn:
# Get the entire row of the guild from the guilds table
try:
select_query = """SELECT * FROM moderatormail WHERE guild_id = $1"""
result = await conn.fetchrow(select_query, ctx.guild.id)
async def wait_for_msg(self, check, user_channel): # Catch errors
""" except asyncpg.PostgresError as e:
Method to check if the user actually types in a message print("PostGres Error: Modlog Record Could Not Be Retrieved For Modlogs", e)
If not, delete the channel
"""
try: # Throw error if the modlogs already exists
# Wait for the message from the author else:
mod_message = await self.bot.wait_for('message', check=check, timeout=300.0) if action == "setup" and result:
text = "**Modmail** Already Setup!" \
f"\nDo **{ctx.prefix}help modmail** to find out more!"
await self.bot.generate_embed(ctx, desc=text)
return None
elif (action == "update" or action == "delete") and not result:
text = "**Modmail** Not Setup!" \
f"\nDo **{ctx.prefix}help modmail** to find out more!"
await self.bot.generate_embed(ctx, desc=text)
return None
# Delete channel if user does not send a message within 5 minutes return not None
except asyncio.TimeoutError:
await user_channel.delete()
return None
else:
return mod_message
# Set up the Cog # Set up the Cog
@ -167,12 +127,8 @@ class Guild(Cog):
def __init__(self, bot): def __init__(self, bot):
self.bot = bot self.bot = bot
self.anon = None self.modmail = Modmail(self.bot)
self.avatars = ["https://cdn.discordapp.com/embed/avatars/0.png", self.starboard = Starboard(self.bot)
"https://cdn.discordapp.com/embed/avatars/1.png",
"https://cdn.discordapp.com/embed/avatars/2.png",
"https://cdn.discordapp.com/embed/avatars/3.png",
"https://cdn.discordapp.com/embed/avatars/4.png"]
@Cog.listener() @Cog.listener()
async def on_ready(self): async def on_ready(self):
@ -192,17 +148,14 @@ class Guild(Cog):
desc += f"**{self.bot.tick} Role Persist**\n" desc += f"**{self.bot.tick} Role Persist**\n"
# Get status of modlogs # Get status of modlogs
ml_channel = self.bot.get_modlog_for_guild(ctx.guild.id) if ml_channel := self.bot.get_modlog_for_guild(ctx.guild.id):
if ml_channel:
channel = ctx.guild.get_channel(ml_channel) channel = ctx.guild.get_channel(ml_channel)
desc += f"**{self.bot.tick} Modlogs | {channel.mention}**\n" desc += f"**{self.bot.tick} Modlogs | {channel.mention}**\n"
else: else:
desc += f"**{self.bot.cross} Modlogs**\n" desc += f"**{self.bot.cross} Modlogs**\n"
# Get status of modmail # Get status of modmail
modmail = self.bot.get_modmail(ctx.guild.id) if modmail := self.bot.get_modmail(ctx.guild.id):
if modmail:
modmail_channel = ctx.guild.get_channel(modmail["modmail_channel_id"]) modmail_channel = ctx.guild.get_channel(modmail["modmail_channel_id"])
modmail_logging = ctx.guild.get_channel(modmail["modmail_logging_channel_id"]) modmail_logging = ctx.guild.get_channel(modmail["modmail_logging_channel_id"])
@ -210,6 +163,13 @@ class Guild(Cog):
else: else:
desc += f"**{self.bot.cross} Modmail**\n" desc += f"**{self.bot.cross} Modmail**\n"
if starboard := self.bot.get_starboard_channel(ctx.guild.id):
channel = self.bot.get_channel(starboard)
min_stars = self.bot.get_starboard_min_stars(ctx.guild.id)
desc += f"**{self.bot.tick} Starboard | Channel: {channel.mention} | Minimum Stars: {min_stars} :star:**\n"
else:
desc += f"**{self.bot.cross} Starboard**\n"
embed = Embed(title="Moderation Systems", embed = Embed(title="Moderation Systems",
description=desc, description=desc,
colour=self.bot.random_colour(), colour=self.bot.random_colour(),
@ -224,15 +184,6 @@ class Guild(Cog):
async def roles_persist(self, ctx): async def roles_persist(self, ctx):
"""Role Persist! Keep user roles when they leave/join!""" """Role Persist! Keep user roles when they leave/join!"""
@roles_persist.command(name="status")
async def rp_status(self, ctx):
"""Showing the status of the role persist within the guild"""
if self.bot.get_roles_persist(ctx.guild.id) == 0:
await self.bot.generate_embed(ctx, desc=f"**Role Persist is currently disabled within {ctx.guild}**")
else:
await self.bot.generate_embed(ctx, desc=f"**Role Persist is currently enabled within {ctx.guild}**")
@roles_persist.command(name="enable") @roles_persist.command(name="enable")
async def rp_enable(self, ctx): async def rp_enable(self, ctx):
"""Enabling role persist within the guild""" """Enabling role persist within the guild"""
@ -253,116 +204,188 @@ class Guild(Cog):
else: else:
await self.bot.generate_embed(ctx, desc=f"**Role Persist is already disabled within {ctx.guild}!**") await self.bot.generate_embed(ctx, desc=f"**Role Persist is already disabled within {ctx.guild}!**")
@group(name="modlogs", case_insensitive=True, usage="`<setup|update|delete>`") @group(name="starboarde", case_insensitive=True, usage="`<setup|update|delete|stars>`")
@has_permissions(manage_guild=True)
@bot_has_permissions(embed_links=True) @bot_has_permissions(embed_links=True)
async def modlogs(self, ctx): @has_permissions(manage_guild=True)
async def starboard(self, ctx):
""" """
Log updates in your server! (Nicknames/Deleted Msgs/etc!) Starboard! Let the community star messages!
""" """
@modlogs.command(name="setup") @starboard.command(name="stars")
async def mlsetup(self, ctx, user_channel: TextChannel): @bot_has_permissions(embed_links=True)
"""Setup a channel for Kick/Ban/Mute actions to be logged""" async def sb_min_stars(self, ctx, stars: int):
"""Update the minimum amount of stars needed for the message to appear on the starboard"""
# Setup pool connection if await get_starboard_from_db(self, ctx, "update") and stars > 0:
pool = self.bot.db # Setup up pool connection
async with pool.acquire() as conn: pool = self.bot.db
async with pool.acquire() as conn:
# Get the row of the guild from database # Update the starboard min_stars in the database
try: try:
select_query = """SELECT * FROM guilds WHERE guild_id = $1""" update_query = """UPDATE starboard SET min_stars = $1 WHERE guild_id = $2"""
result = await conn.fetchrow(select_query, ctx.guild.id) await conn.execute(update_query, stars, ctx.guild.id)
# Catch errors # Catch errors
except asyncpg.PostgresError as e: except asyncpg.PostgresError as e:
print("PostGres Error: Guild Record Could Not Be Retrieved For Modlog Setup", e) print(f"PostGres Error: Starboard Record Could Not Be Updated For Guild {ctx.guild.id}", e)
# Throw error if the modlog channel already exists # Send confirmation that the channel has been updated
else: else:
if result["modlogs"]: star_channel = self.bot.get_starboard_channel(ctx.guild.id)
text = "**Modlogs Channel** already set up!" \ channel = self.bot.get_channel(star_channel)
f"\nDo **{ctx.prefix}help modlogs** to find out more!" text = "**Minimum Stars Updated!**" \
f"\nMessages will now need {stars} :star: to appear in {channel.mention}"
await self.bot.generate_embed(ctx, desc=text) await self.bot.generate_embed(ctx, desc=text)
# Set up the modlogs channel within the guild # Update cache
else: self.bot.update_starboard_min_stars(ctx.guild.id, stars)
mod_log_setup = True
await self.bot.storage_modlog_for_guild(ctx, user_channel.id, mod_log_setup)
@modlogs.command(name="update") elif stars <= 0:
async def mlupdate(self, ctx, user_channel: TextChannel): await self.bot.generate_embed(ctx, desc="Minimum Stars Must Be Over or Equal to 1!")
"""Change the channel that your modlogs are sent to"""
@starboard.command(name="setup", usage="`<#channel>`")
@bot_has_permissions(embed_links=True)
async def sb_setup(self, ctx, starboard_channel: TextChannel):
"""
Setup Starboard
First Argument: Input Channel(Mention or ID) where starred messages will be sent
"""
# Setup up pool connection if await get_starboard_from_db(self, ctx, "setup"):
pool = self.bot.db # Setup up pool connection
async with pool.acquire() as conn: pool = self.bot.db
async with pool.acquire() as conn:
# Get the guilds row from the guilds table # Insert the information about the starboard into database
try: try:
select_query = """SELECT * FROM guilds WHERE guild_id = $1""" insert_query = """INSERT INTO starboard (guild_id, channel_id) VALUES ($1, $2)"""
result = await conn.fetchrow(select_query, ctx.guild.id) await conn.execute(insert_query, ctx.guild.id, starboard_channel.id)
# Catch errors # Catch errors
except asyncpg.PostgresError as e: except asyncpg.PostgresError as e:
print("PostGres Error: Guild Record Could Not Be Retrieved For Modlog Update", e) print(f"PostGres Error: Starboard Record Could Not Be Inserted For Guild {ctx.guild.id}", e)
# Throw error if the modlog channel already exists # Send confirmation message
else: else:
if not result["modlogs"]: text = "**Starboard** is successfully set up!" \
text = "**Modlogs Channel** not set up!" \ f"\nRefer to **{ctx.prefix}help starboard** for more information"
f"\nDo **{ctx.prefix}help modlogs** to find out more!"
await self.bot.generate_embed(ctx, desc=text) await self.bot.generate_embed(ctx, desc=text)
# Update the modlog channel within the database and cache # Store into cache
self.bot.cache_store_starboard(ctx.guild.id, starboard_channel.id, 1)
@starboard.command(name="update", usage="`<channel>`")
@bot_has_permissions(embed_links=True)
async def sb_update(self, ctx, starboard_channel: TextChannel):
"""
Update the channel that the starred messages are sent to
You can Mention or use the Channel ID
"""
if await get_starboard_from_db(self, ctx, "update"):
# Setup up pool connection
pool = self.bot.db
async with pool.acquire() as conn:
# Update the starboard channel in the database
try:
update_query = """UPDATE starboard SET channel_id = $1 WHERE guild_id = $2"""
await conn.execute(update_query, starboard_channel.id, ctx.guild.id)
# Catch errors
except asyncpg.PostgresError as e:
print(f"PostGres Error: Starboard Record Could Not Be Updated For Guild {ctx.guild.id}", e)
# Send confirmation that the channel has been updated
else: else:
mod_log_setup = False text = "**Channel Updated**" \
await self.bot.storage_modlog_for_guild(ctx, user_channel.id, mod_log_setup) f"\nNew Starred Messages will be sent to {starboard_channel.mention}"
await self.bot.generate_embed(ctx, desc=text)
@modlogs.command("delete") # Update cache
async def mldelete(self, ctx): self.bot.update_starboard_channel(ctx.guild.id, starboard_channel.id)
"""Delete the existing modlogs channel"""
@starboard.command(name="delete")
@bot_has_permissions(embed_links=True)
async def sb_delete(self, ctx):
"""Delete the starboard from the guild"""
# Setup up pool connection if await get_starboard_from_db(self, ctx, "delete"):
pool = self.bot.db # Setup up pool connection
async with pool.acquire() as conn: pool = self.bot.db
async with pool.acquire() as conn:
# Get the guilds row from the guilds table # Remove the starboard record from the database
try: try:
select_query = """SELECT * FROM guilds WHERE guild_id = $1""" delete_query = """DELETE FROM starboard WHERE guild_id = $1"""
result = await conn.fetchrow(select_query, ctx.guild.id) await conn.execute(delete_query, ctx.guild.id)
# Catch errors # Catch errors
except asyncpg.PostgresError as e: except asyncpg.PostgresError as e:
print("PostGres Error: Guild Record Could Not Be Retrieved For Modlog Delete", e) print(f"PostGres Error: Starboard Record Could Not Be Deleted for Guild {ctx.guild.id}", e)
# Throw error that modlogs have not been setup # Sending confirmation message that the starboard has been deleted
else: else:
if not result["modlogs"]: text = "**Starboard** successfully deleted!" \
text = "**Modlogs Channel** not set up!" \ f"\nDo **{ctx.prefix}help starboard** to find out more!"
f"\nDo **{ctx.prefix}help modlogs** to find out more!"
await self.bot.generate_embed(ctx, desc=text) await self.bot.generate_embed(ctx, desc=text)
return
# Update the existing modlogs for guild # Delete from cache
try: self.bot.delete_starboard(ctx.guild.id)
update = """UPDATE guilds SET modlogs = NULL WHERE guild_id = $1"""
await conn.execute(update, ctx.guild.id) @group(name="modlogs", case_insensitive=True, usage="`<setup|update|delete>`")
@has_permissions(manage_guild=True)
@bot_has_permissions(embed_links=True)
async def modlogs(self, ctx):
"""
Log updates in your server! (Nicknames/Deleted Msgs/etc!)
"""
@modlogs.command(name="setup", usage="`<#channel>`")
async def mlsetup(self, ctx, user_channel: TextChannel):
"""Setup a channel for Kick/Ban/Mute actions to be logged"""
if await get_modlogs_from_db(self, ctx, "setup"):
# Set up the modlogs channel within the guild
mod_log_setup = True
await self.bot.storage_modlog_for_guild(ctx, user_channel.id, mod_log_setup)
@modlogs.command(name="update", usage="`<#channel>`")
async def mlupdate(self, ctx, user_channel: TextChannel):
"""Change the channel that your modlogs are sent to"""
if await get_modlogs_from_db(self, ctx, "update"):
# Update the modlog channel within the database and cache
mod_log_setup = False
await self.bot.storage_modlog_for_guild(ctx, user_channel.id, mod_log_setup)
@modlogs.command("delete")
async def mldelete(self, ctx):
"""Delete the existing modlogs channel"""
if await get_modlogs_from_db(self, ctx, "delete"):
# Setup up pool connection
pool = self.bot.db
async with pool.acquire() as conn:
# Catch errors # Update the existing modlogs for guild
except asyncpg.PostgresError as e: try:
print(f"PostGres Error: Guild Modlogs Could Not Be Deleted For {ctx.guild.id}", e) update = """UPDATE guilds SET modlogs = NULL WHERE guild_id = $1"""
await conn.execute(update, ctx.guild.id)
# Delete channel from cache # Catch errors
else: except asyncpg.PostgresError as e:
self.bot.remove_modlog_channel(ctx.guild.id) print(f"PostGres Error: Guild Modlogs Could Not Be Deleted For {ctx.guild.id}", e)
# Release the connection back to the pool # Delete channel from cache
await pool.release(conn) else:
text = "**Modlogs System** successfully deleted!" \
f"\nDo **{ctx.prefix}help modlogs** to setup Modlogs again!"
await self.bot.generate_embed(ctx, desc=text)
text = "**Modlogs System** successfully deleted!" \ self.bot.remove_modlog_channel(ctx.guild.id)
f"\nDo **{ctx.prefix}help modlogs** to setup Modlogs again!"
await self.bot.generate_embed(ctx, desc=text)
@group(name="modmail", case_insensitive=True, usage="`<setup|update|delete>`") @group(name="modmail", case_insensitive=True, usage="`<setup|update|delete>`")
@bot_has_permissions(manage_channels=True, embed_links=True, add_reactions=True, manage_messages=True, @bot_has_permissions(manage_channels=True, embed_links=True, add_reactions=True, manage_messages=True,
@ -381,68 +404,47 @@ class Guild(Cog):
Second Argument: Input Channel(Mention or ID) where the members mail should be sent Second Argument: Input Channel(Mention or ID) where the members mail should be sent
""" """
# Setup up pool connection if await get_modmail_from_db(self, ctx, "setup"):
pool = self.bot.db
async with pool.acquire() as conn:
# Get the author's row from the members table # Set up embed to let the user how to start sending modmail
try: desc = "React to this message if you want to send a message to the Staff Team!" \
select_query = """SELECT * FROM moderatormail WHERE guild_id = $1""" "\n\n**React with ✅**" \
result = await conn.fetchrow(select_query, ctx.guild.id) "\n\nWe encourage all suggestions/thoughts and opinions on the server!" \
"\nAs long as it is **valid** criticism." \
"\n\n\n**Purely negative feedback will not be considered.**"
# Catch errors ModMail = Embed(title="**Welcome to Modmail!**",
except asyncpg.PostgresError as e: description=desc,
print("PostGres Error: ModeratorMail Record Could Not Be Retrieved For Modmail Setup", e) colour=self.bot.admin_colour,
timestamp=datetime.datetime.utcnow())
ModMail.set_thumbnail(url=self.bot.user.avatar_url)
# Throw error if the guild already exists # Send modmail embed to the specified channel and auto add the ✅ reaction
else: modmail_message = await modmail.send(embed=ModMail)
if result:
text = "**Modmail System** already set up!" \
f"\nDo **{ctx.prefix}help modmail** to find out more!"
await self.bot.generate_embed(ctx, desc=text)
return
# Set up embed to let the user how to start sending modmail
desc = "React to this message if you want to send a message to the Staff Team!" \
"\n\n**React with ✅**" \
"\n\nWe encourage all suggestions/thoughts and opinions on the server!" \
"\nAs long as it is **valid** criticism." \
"\n\n\n**Purely negative feedback will not be considered.**"
ModMail = Embed(title="**Welcome to Modmail!**",
description=desc,
colour=self.bot.admin_colour,
timestamp=datetime.datetime.utcnow())
ModMail.set_thumbnail(url=self.bot.user.avatar_url)
# Send modmail embed to the specified channel and auto add the ✅ reaction
modmail_message = await modmail.send(embed=ModMail)
try:
await modmail_message.add_reaction('') await modmail_message.add_reaction('')
except Exception as e:
print(e)
# Setup up pool connection
async with pool.acquire() as conn:
# Insert the information about the modmail system into database
try:
insert_query = """INSERT INTO moderatormail (guild_id, modmail_channel_id, message_id, modmail_logging_channel_id)
VALUES ($1, $2, $3, $4)"""
await conn.execute(insert_query, ctx.guild.id, modmail.id, modmail_message.id, modmail_logging.id)
# Catch errors
except asyncpg.PostgresError as e:
print(f"PostGres Error: Modmail System Record Could Not Be Inserted For Guild {ctx.guild.id}", e)
# Send confirmation message
else:
text = "**Modmail System** is successfully set up!" \
f"\nRefer to **{ctx.prefix}help modmail** for more information"
await self.bot.generate_embed(ctx, desc=text)
# Store into cache # Setup up pool connection
self.bot.cache_store_modmail(ctx.guild.id, modmail.id, modmail_message.id, modmail_logging.id) pool = self.bot.db
async with pool.acquire() as conn:
# Insert the information about the modmail system into database
try:
insert_query = """INSERT INTO moderatormail (guild_id, modmail_channel_id, message_id, modmail_logging_channel_id)
VALUES ($1, $2, $3, $4)"""
await conn.execute(insert_query, ctx.guild.id, modmail.id, modmail_message.id, modmail_logging.id)
# Catch errors
except asyncpg.PostgresError as e:
print(f"PostGres Error: Modmail System Record Could Not Be Inserted For Guild {ctx.guild.id}", e)
# Send confirmation message
else:
text = "**Modmail System** is successfully set up!" \
f"\nRefer to **{ctx.prefix}help modmail** for more information"
await self.bot.generate_embed(ctx, desc=text)
# Store into cache
self.bot.cache_store_modmail(ctx.guild.id, modmail.id, modmail_message.id, modmail_logging.id)
@mod_mail.command(name="update") @mod_mail.command(name="update")
async def mmupdate(self, ctx, modmail_logging_channel: TextChannel): async def mmupdate(self, ctx, modmail_logging_channel: TextChannel):
@ -451,244 +453,74 @@ class Guild(Cog):
You can Mention or use the Channel ID You can Mention or use the Channel ID
""" """
# Setup up pool connection if await get_modmail_from_db(self, ctx, "update"):
pool = self.bot.db
async with pool.acquire() as conn:
# Get the moderatormail record from the guilds table pool = self.bot.db
try: async with pool.acquire() as conn:
select_query = """SELECT * FROM moderatormail WHERE guild_id = $1""" # Update the modmail channel in the database
result = await conn.fetchrow(select_query, ctx.guild.id) try:
update_query = """UPDATE moderatormail SET modmail_logging_channel_id = $1 WHERE guild_id = $2"""
await conn.execute(update_query, modmail_logging_channel.id, ctx.guild.id)
# Catch errors # Catch errors
except asyncpg.PostgresError as e: except asyncpg.PostgresError as e:
print("PostGres Error: ModeratorMail Record Could Not Be Retrieved For Modmail Update", e) print(f"PostGres Error: Modmail System Record Could Not Be Updated For Guild {ctx.guild.id}", e)
# Throw error if the guild already exists # Send confirmation that the channel has been updated
else: else:
if not result: text = "**Channel Updated**" \
text = "**Modmail System** not set up!" \ f"\nNew Modmail will be sent to {modmail_logging_channel.mention}"
f"\nDo **{ctx.prefix}help modmail** to find out more!"
await self.bot.generate_embed(ctx, desc=text) await self.bot.generate_embed(ctx, desc=text)
return # Update cache
self.bot.update_modmail(ctx.guild.id, modmail_logging_channel.id)
# Setup up pool connection and cursor
async with pool.acquire() as conn:
# Update the modmail channel in the database
try:
update_query = """UPDATE moderatormail SET modmail_logging_channel_id = $1 WHERE guild_id = $2"""
await conn.execute(update_query, modmail_logging_channel.id, ctx.guild.id)
# Catch errors
except asyncpg.PostgresError as e:
print(f"PostGres Error: Modmail System Record Could Not Be Updated For Guild {ctx.guild.id}", e)
# Send confirmation that the channel has been updated
else:
text = "**Channel Updated**" \
f"\nNew Modmail will be sent to {modmail_logging_channel.mention}"
await self.bot.generate_embed(ctx, desc=text)
# Update cache
self.bot.update_modmail(ctx.guild.id, modmail_logging_channel.id)
@mod_mail.command(name="delete") @mod_mail.command(name="delete")
async def mmdelete(self, ctx): async def mmdelete(self, ctx):
"""Delete the entire modmail system from the guild""" """Delete the entire modmail system from the guild"""
# Setup up pool connection if await get_modmail_from_db(self, ctx, "delete"):
pool = self.bot.db
async with pool.acquire() as conn:
# Get the moderatormail record from the guilds table # Setup up pool connection
try: pool = self.bot.db
select_query = """SELECT * FROM moderatormail WHERE guild_id = $1""" async with pool.acquire() as conn:
result = await conn.fetchrow(select_query, ctx.guild.id)
# Catch errors # Remove the moderatormail record from the database
except asyncpg.PostgresError as e: try:
print("PostGres Error: ModeratorMail Record Could Not Be Retrieved For Modmail Delete", e) delete_query = """DELETE FROM moderatormail WHERE guild_id = $1"""
await conn.execute(delete_query, ctx.guild.id)
else: # Catch errors
# Throw error if modmail system does not exist already except asyncpg.PostgresError as e:
if not result: print(f"PostGres Error: ModeratorMail Record Could Not Be Deleted for Guild {ctx.guild.id}", e)
text = "**Modmail System** not set up!" \
# Sending confirmation message that the modmail system has been deleted
else:
text = "**Modmail System** successfully deleted!" \
f"\nDo **{ctx.prefix}help modmail** to find out more!" f"\nDo **{ctx.prefix}help modmail** to find out more!"
await self.bot.generate_embed(ctx, desc=text) await self.bot.generate_embed(ctx, desc=text)
return
# Setup up pool connection # Delete from cache
async with pool.acquire() as conn: self.bot.delete_modmail(ctx.guild.id)
# Remove the moderatormail record from the database
try:
delete_query = """DELETE FROM moderatormail WHERE guild_id = $1"""
await conn.execute(delete_query, ctx.guild.id)
# Catch errors
except asyncpg.PostgresError as e:
print(f"PostGres Error: ModeratorMail Record Could Not Be Deleted for Guild {ctx.guild.id}", e)
# Sending confirmation message that the modmail system has been deleted
else:
text = "**Modmail System** successfully deleted!" \
f"\nDo **{ctx.prefix}help modmail** to find out more!"
await self.bot.generate_embed(ctx, desc=text)
# Delete from cache
self.bot.delete_modmail(ctx.guild.id)
@Cog.listener() @Cog.listener()
async def on_raw_reaction_add(self, payload): async def on_raw_reaction_add(self, payload):
"""Listen for reactions for modmail channel""" """Listening for reactions relating to modmail/starboard"""
# Don't count reactions that are made by the bot
# Don't count other reactions other than ✅ and ❌
if payload.member.bot or str(payload.emoji) not in ['', '']:
return
# Get the modmail information from cache
modmail = self.bot.get_modmail(payload.guild_id)
if modmail:
channel_id = modmail["modmail_channel_id"]
message_id = modmail["message_id"]
modmail_channel_id = modmail["modmail_logging_channel_id"]
else:
return
# Bunch of checks to make sure it has the right guild, channel, message and reaction
if payload.channel_id == channel_id and payload.message_id == message_id and payload.emoji.name == "":
# Get the guild
guild = self.bot.get_guild(payload.guild_id)
# Get the member
member = guild.get_member(payload.user_id)
# Get the setup modmail channel
channel = guild.get_channel(payload.channel_id)
# Get the modmail logging channel
modmail_channel = guild.get_channel(modmail_channel_id)
# Fetch the message and remove the reaction
reaction = await channel.fetch_message(message_id)
await reaction.remove_reaction('', member)
# Setting up the channel permissions for the new channel that will be created
overwrites = {
guild.default_role: discord.PermissionOverwrite(read_messages=False, send_messages=False),
guild.me: discord.PermissionOverwrite(read_messages=True, send_messages=True, embed_links=True,
add_reactions=True, manage_messages=True),
member: discord.PermissionOverwrite(read_messages=True, send_messages=True)
}
# Saving this for later within when discord.py 1.4 comes out
# user_channel = await guild.create_category_channel("Member", overwrites=overwrites, position=7)
# Create the text channel
user_channel = await guild.create_text_channel("Member", overwrites=overwrites,
position=0)
# Mention the user to make sure that they get pinged
mention = await user_channel.send(member.mention)
await mention.delete()
try:
# Send the embed if they want to remain anonymous or not
Anon_or_Not = await user_channel.send(embed=anon_or_not(self, member))
# Add reactions to the message
await Anon_or_Not.add_reaction('')
await Anon_or_Not.add_reaction('')
# Checking if the user reacted with ✅ with response to sending staff a message
def emoji_check(reaction, user):
return user == member and str(reaction.emoji) in ['', '']
try:
# Wait for the user to add a reaction
reaction, user = await self.bot.wait_for('reaction_add', check=emoji_check, timeout=60.0)
# Delete channel if user does not react within 60 seconds await self.modmail.modmail(payload)
except asyncio.TimeoutError as ex: await self.starboard.send_starboard_and_update_db(payload, action="added")
print(ex)
await user_channel.delete()
else:
# Making sure that the reply is from the author
def check(m):
return m.author == payload.member and user_channel.id == instructions.channel.id
# Checking if user wants to be Anonymous or not
if str(reaction.emoji) == "":
self.anon = True
if str(reaction.emoji) == "":
self.anon = False
# Delete the old embed
await Anon_or_Not.delete()
# Tell the user to type their mail into the chat
instructions = await user_channel.send(embed=send_instructions(self, member))
# Wait for the message from the author
msg = await wait_for_msg(self, check, user_channel)
if not msg: return
# Making sure that the message is below 50 characters and the message was sent in the channel
while len(msg.content) <= 50 and msg.channel == user_channel:
await user_channel.send(embed=error_handling(self, member))
# Wait for the message from the author
msg = await wait_for_msg(self, check, user_channel)
if not msg: return
# As long as the message is above 50 characters and in the correct channel
if len(msg.content) > 50 and msg.channel == user_channel:
# Delete the previous embed
await instructions.delete()
# Store all text in the channel in a bytesio object @Cog.listener()
text = "" async def on_raw_reaction_remove(self, payload):
async for message in user_channel.history(limit=300): """Editing the message if a star reaction was removed"""
text += "".join(f"{message.created_at} : {message.content}\n")
text_bytes = str.encode(text)
file = io.BytesIO(text_bytes)
file_name = "Anon.txt" if self.anon else f"{member.name}.txt"
# Send the message to the modmail channel
await modmail_channel.send(embed=send_modmail(self, msg, member),
file=File(file, file_name))
# Make sure the user knows that their message has been sent
await user_channel.send(embed=message_sent_confirmation(self, member))
# Let the user read the message for 5 seconds
await asyncio.sleep(5)
# Delete the channel and then stop the function
await user_channel.delete()
# If the user types anywhere else, delete the channel
else:
await user_channel.delete()
except Exception as ex:
print(ex)
# Send out an error message if the user waited too long
await user_channel.send(
"Sorry! Something seems to have gone wrong and the modmail will be aborting."
"\nRemember to make sure it's under **1024** characters!!")
await asyncio.sleep(5) await self.starboard.send_starboard_and_update_db(payload, action="removed")
await user_channel.delete()
@mlsetup.error @mlsetup.error
@mlupdate.error @mlupdate.error
@mmsetup.error @mmsetup.error
@mmupdate.error @mmupdate.error
@sb_setup.error
@sb_update.error
async def mlsetup_command_error(self, ctx, exc): async def mlsetup_command_error(self, ctx, exc):
"""Catching error if channel is not recognised""" """Catching error if channel is not recognised"""

Loading…
Cancel
Save