Skip to content

Commit

Permalink
RPIcord 2.1
Browse files Browse the repository at this point in the history
- Added Starboard
- Added Regen Gmail Token feature
- Added on_member_join feature
- Fixed rolecolors feature.
- Fixed email_verification features.
  • Loading branch information
rohitp30 committed Jul 18, 2024
1 parent 0ac7086 commit 89b003f
Show file tree
Hide file tree
Showing 7 changed files with 215 additions and 33 deletions.
9 changes: 8 additions & 1 deletion core/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,12 @@ class FinalizedEmailVerification(BaseModel):
email = TextField()
class_year = TextField()

class StarboardMessage(BaseModel):
id = AutoField()
original_message_id = IntegerField(unique=True)
starboard_message_id = IntegerField()
star_count = IntegerField()

# Function to initialize the database
def initialize_db():
db.connect()
Expand Down Expand Up @@ -366,7 +372,8 @@ def _db_close(exc):
"ColorUser": ColorUser,
"ClassSchedule": ClassSchedule,
"EmailVerification": EmailVerification,
"FinalizedEmailVerification": FinalizedEmailVerification
"FinalizedEmailVerification": FinalizedEmailVerification,
"StarboardMessage": StarboardMessage
}

"""
Expand Down
74 changes: 45 additions & 29 deletions core/rolecolors.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
Classes:
RoleColorModal: A modal for users to input a hex code to change their role color.
RoleNameModal: A modal for users to input a new name for their role.
CustomizeView: A persistent view with buttons to trigger the role customization modals and manage a specific role.
CustomizeView: A persistent view with a dropdown to trigger the role customization modals and manage a specific role.
Only avaliable in the Guild: r(evolution)pi
"""

import traceback

import discord
from discord.ui import View, Modal, TextInput
from discord.ui import View, Modal, TextInput, Select, SelectOption

from core import database

Expand All @@ -28,6 +28,7 @@ async def on_submit(self, interaction: discord.Interaction):
return

user_record = database.ColorUser.select().where(database.ColorUser.user_id == interaction.user.id)
reference_role = interaction.guild.get_role(1216596310619328642)

if user_record.exists():
role = interaction.guild.get_role(user_record.get().role_id)
Expand All @@ -36,18 +37,18 @@ async def on_submit(self, interaction: discord.Interaction):
await interaction.response.send_message(f"Role {role.name} edited.", ephemeral=True)
else:
role_name = interaction.user.name + f"'s Role ({hex_code})"
role = await interaction.guild.create_role(name=role_name, colour=discord.Colour(int(hex_code[1:], 16)), reason=f"{interaction.user.name} requested color change to {hex_code}")
role = await interaction.guild.create_role(name=role_name, colour=discord.Colour(int(hex_code[1:], 16)), reason=f"{interaction.user.name} requested color change to {hex_code}", position=reference_role.position + 1)
database.update_user_role(interaction.user.id, role.id)
await interaction.response.send_message(f"Role {role.name} assigned.", ephemeral=True)
else:
role_name = interaction.user.name + f"'s Role ({hex_code})"
role = await interaction.guild.create_role(name=role_name, colour=discord.Colour(int(hex_code[1:], 16)), reason=f"{interaction.user.name} requested color change to {hex_code}")
role = await interaction.guild.create_role(name=role_name, colour=discord.Colour(int(hex_code[1:], 16)), reason=f"{interaction.user.name} requested color change to {hex_code}", position=reference_role.position + 1)
query = database.ColorUser.create(user_id=interaction.user.id, role_id=role.id)
query.save()
database.update_user_role(interaction.user.id, role.id)
await interaction.user.add_roles(role, reason=f"{interaction.user.name} requested color change to {hex_code}")
await interaction.response.send_message(f"Role {role.name} given!", ephemeral=True)

await interaction.user.add_roles(role, reason=f"{interaction.user.name} requested color change to {hex_code}")

async def on_error(self, interaction: discord.Interaction, error: Exception) -> None:
await interaction.response.send_message('Oops! Something went wrong. Contact rohit if this keeps happening :(.', ephemeral=True)
Expand All @@ -63,6 +64,7 @@ async def on_submit(self, interaction: discord.Interaction):
role_name = self.role_name.value

user_record = database.ColorUser.select().where(database.ColorUser.user_id == interaction.user.id)
reference_role = interaction.guild.get_role(1216596310619328642)

if user_record.exists():
role = interaction.guild.get_role(user_record.get().role_id)
Expand All @@ -72,20 +74,19 @@ async def on_submit(self, interaction: discord.Interaction):
else:
random_hex_code = discord.Color.random()
role_name = interaction.user.name + f"'s Role ({random_hex_code.value})"
role = await interaction.guild.create_role(name=role_name, colour=random_hex_code, reason=f"{interaction.user.name} requested name change to {role_name}")
role = await interaction.guild.create_role(name=role_name, colour=random_hex_code, reason=f"{interaction.user.name} requested name change to {role_name}", position=reference_role.position + 1)
database.update_user_role(interaction.user.id, role.id)
await interaction.response.send_message(f"Role {role.name} assigned.", ephemeral=True)
else:
random_hex_code = discord.Color.random()
role_name = interaction.user.name + f"'s Role ({random_hex_code.value})"
role = await interaction.guild.create_role(name=role_name, colour=random_hex_code, reason=f"{interaction.user.name} requested name change to {role_name}")

role = await interaction.guild.create_role(name=role_name, colour=random_hex_code, reason=f"{interaction.user.name} requested name change to {role_name}", position=reference_role.position + 1)
query = database.ColorUser.create(user_id=interaction.user.id, role_id=role.id)
query.save()
database.update_user_role(interaction.user.id, role.id)
await interaction.user.add_roles(role, reason=f"{interaction.user.name} requested name change to {role_name}")
await interaction.response.send_message(f"Role {role.name} given!", ephemeral=True)

await interaction.user.add_roles(role, reason=f"{interaction.user.name} requested name change to {role_name}")

async def on_error(self, interaction: discord.Interaction, error: Exception) -> None:
await interaction.response.send_message('Oops! Something went wrong. Contact rohit if this keeps happening :(.', ephemeral=True)
Expand All @@ -97,23 +98,38 @@ async def on_error(self, interaction: discord.Interaction, error: Exception) ->
class CustomizeView(View):
def __init__(self):
super().__init__(timeout=None) # Persistent view

@discord.ui.button(label="Customize Role Color", style=discord.ButtonStyle.primary, custom_id="customize_role_color")
async def customize_button_color(self, interaction: discord.Interaction, button: discord.ui.Button):
modal = RoleColorModal(title="Customize Your Role Color")
await interaction.response.send_modal(modal)

@discord.ui.button(label="Customize Role Name", style=discord.ButtonStyle.gray, custom_id="customize_role_name")
async def customize_button_name(self, interaction: discord.Interaction, button: discord.ui.Button):
modal = RoleNameModal(title="Customize Your Role Name")
await interaction.response.send_modal(modal)

@discord.ui.button(label="Get Roblox Role", style=discord.ButtonStyle.danger, custom_id="get_roblox_role")
async def get_roblox_role(self, interaction: discord.Interaction, button: discord.ui.Button):
roblox_role = discord.utils.get(interaction.guild.roles, id=1239657271143698564)
if roblox_role in interaction.user.roles:
await interaction.user.remove_roles(roblox_role, reason="User requested to remove Roblox role")
await interaction.response.send_message("Roblox role removed!", ephemeral=True)
else:
await interaction.user.add_roles(roblox_role, reason="User requested to add Roblox role")
await interaction.response.send_message("Roblox role added!", ephemeral=True)
options = [
SelectOption(label="Customize Role Color", value="customize_role_color", emoji="🎨"),
SelectOption(label="Customize Role Name", value="customize_role_name", emoji="📝"),
SelectOption(label="Get Roblox Role", value="get_roblox_role", emoji="🤖"),
SelectOption(label="Get Valorant Role", value="get_valorant_role", emoji="🔫")
]
self.add_item(CustomizeDropdown(options=options))

class CustomizeDropdown(Select):
def __init__(self, options):
super().__init__(placeholder="Choose an action...", min_values=1, max_values=1, options=options)

async def callback(self, interaction: discord.Interaction):
if self.values[0] == "customize_role_color":
modal = RoleColorModal(title="Customize Your Role Color")
await interaction.response.send_modal(modal)
elif self.values[0] == "customize_role_name":
modal = RoleNameModal(title="Customize Your Role Name")
await interaction.response.send_modal(modal)
elif self.values[0] == "get_roblox_role":
roblox_role = discord.utils.get(interaction.guild.roles, id=1239657271143698564)
if roblox_role in interaction.user.roles:
await interaction.user.remove_roles(roblox_role, reason="User requested to remove Roblox role")
await interaction.response.send_message("Roblox role removed!", ephemeral=True)
else:
await interaction.user.add_roles(roblox_role, reason="User requested to add Roblox role")
await interaction.response.send_message("Roblox role added!", ephemeral=True)
elif self.values[0] == "get_valorant_role":
valorant_role = discord.utils.get(interaction.guild.roles, id=1249529840034512946)
if valorant_role in interaction.user.roles:
await interaction.user.remove_roles(valorant_role, reason="User requested to remove Valorant role")
await interaction.response.send_message("Valorant role removed!", ephemeral=True)
else:
await interaction.user.add_roles(valorant_role, reason="User requested to add Valorant role")
await interaction.response.send_message("Valorant role added!", ephemeral=True)
11 changes: 9 additions & 2 deletions core/rpi/email_verification.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ def get_gmail_service():
creds = pickle.load(token)
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
try:
creds.refresh(Request())
except:
raise Exception("Error refreshing token") # Sentry needs to pick this up.
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
Expand Down Expand Up @@ -94,7 +97,11 @@ async def on_submit(self, interaction: discord.Interaction):
q = database.EmailVerification.create(discord_id=interaction.user.id, email=rpi_email, verification_code=verification_code, class_year=self.class_year.value)
q.save()

service = get_gmail_service()
try:
service = get_gmail_service()
except:
await interaction.response.send_message("Looks like the Gmail API is down. Please try again later. (Contact <@409152798609899530> if this keeps happening.)", ephemeral=True)
return
message = create_message(rpi_email, f' RPIcord Verification Code: {verification_code}', f'Use the code {verification_code} to verify your email address for the RPI Class of 2028 Discord Server.\n\nIf you did not request this, please ignore this email.')
send_message(service, 'me', message)
await interaction.response.send_message(f'Verification email sent to {rpi_email}. Please check your *(junk)* inbox and use the code to verify.\n\n> **Use /verification verify_code to finalize verification!**', ephemeral=True)
Expand Down
31 changes: 31 additions & 0 deletions core/rpi/regen_gmail_token.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import os
import pickle
from google.auth.transport.requests import Request
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build

# If modifying these SCOPES, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/gmail.send']

def get_gmail_service():
creds = None
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid: # Still gotta fix the not creds.valid check.
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)

with open('token.pickle', 'wb') as token:
pickle.dump(creds, token)
service = build('gmail', 'v1', credentials=creds)
return service

if __name__ == '__main__':
service = get_gmail_service()
print("Token.pickle file generated successfully.")
73 changes: 73 additions & 0 deletions core/rpi/starboard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import discord
from discord.ext import commands
from core.database import StarboardMessage

class Starboard(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.starboard_channel_id = 123456789012345678 # Default starboard channel ID
self.star_threshold = 5 # Default number of stars required to post to starboard

@commands.Cog.listener()
async def on_raw_reaction_add(self, payload):
if payload.emoji.name == '⭐': # Check if the reaction is a star
await self.handle_star_reaction(payload)

@commands.Cog.listener()
async def on_raw_reaction_remove(self, payload):
if payload.emoji.name == '⭐': # Check if the reaction is a star
await self.handle_star_reaction(payload)

async def handle_star_reaction(self, payload):
channel = self.bot.get_channel(payload.channel_id)
message = await channel.fetch_message(payload.message_id)
star_count = sum(1 for reaction in message.reactions if reaction.emoji == '⭐')

starboard_channel = self.bot.get_channel(self.starboard_channel_id)
starboard_message = StarboardMessage.get_or_none(StarboardMessage.original_message_id == message.id)

if star_count >= self.star_threshold:
embed = discord.Embed(
description=message.content,
color=discord.Color.gold()
)
embed.set_author(name=message.author.display_name, icon_url=message.author.avatar.url)
embed.add_field(name="Jump to message", value=f"[Click Here]({message.jump_url})")
embed.set_footer(text=f"⭐ {star_count} | {message.channel.name}")

if starboard_message:
starboard_msg = await starboard_channel.fetch_message(starboard_message.starboard_message_id)
await starboard_msg.edit(embed=embed)
starboard_message.star_count = star_count
starboard_message.save()
else:
starboard_msg = await starboard_channel.send(embed=embed)
StarboardMessage.create(
original_message_id=message.id,
starboard_message_id=starboard_msg.id,
star_count=star_count
)
elif starboard_message:
starboard_msg = await starboard_channel.fetch_message(starboard_message.starboard_message_id)
await starboard_msg.delete_instance()

@commands.group(name="starboard", invoke_without_command=True)
async def starboard(self, ctx):
await ctx.send("Available subcommands: setchannel, setthreshold")

@starboard.command(name="setchannel")
@commands.has_permissions(administrator=True)
async def set_channel(self, ctx, channel: discord.TextChannel):
"""Set the starboard channel."""
self.starboard_channel_id = channel.id
await ctx.send(f"Starboard channel set to {channel.mention}")

@starboard.command(name="setthreshold")
@commands.has_permissions(administrator=True)
async def set_threshold(self, ctx, threshold: int):
"""Set the star count threshold."""
self.star_threshold = threshold
await ctx.send(f"Star count threshold set to {threshold}")

async def setup(bot):
await bot.add_cog(Starboard(bot))
8 changes: 7 additions & 1 deletion main.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,12 @@ async def on_message(self, message: discord.Message):

await self.process_commands(message)

async def on_member_join(self, member: discord.Member):
if member.guild.id == 1216429016760717322 and not member.bot:
welcome_channel = await self.bot.fetch_channel(1216429018744885321)

await welcome_channel.send(f"hi loser, {member.mention}. im just here to tell you that if you want a custom role, go to <#1219037652414894310>. bye. also keira sucks lol")

async def is_owner(self, user: discord.User):
"""
Checks if the user is the owner of the bot.
Expand Down Expand Up @@ -201,4 +207,4 @@ def start_time(self):
)

if __name__ == "__main__":
bot.run(os.getenv("TOKEN"))
bot.run(os.getenv("TOKEN"))
Loading

0 comments on commit 89b003f

Please sign in to comment.