DiscordApplicationBot/bot.py

702 lines
32 KiB
Python
Raw Permalink Normal View History

2023-07-14 19:47:41 +00:00
# db - msg_id, user_id, guild_id
import asyncio
2023-07-14 19:47:41 +00:00
import discord
import os
import json
import pickle
2023-07-14 19:47:41 +00:00
from dotenv import load_dotenv
from discord.ui import Modal, InputText
from discord.utils import get
from discord.ext import commands
2023-08-08 15:34:51 +00:00
from dbutil import MessageDB
from dbutil import StartButtonDB
from dbutil import GuildAppDB
2023-07-14 19:47:41 +00:00
from action import Action, ActionInteraction, actions
usable_actions = actions
2023-08-17 21:28:55 +00:00
2023-07-14 19:47:41 +00:00
load_dotenv()
TOKEN = os.getenv("TOKEN")
bot = discord.Bot(intents=discord.Intents.all())
@bot.event
async def on_ready():
bot.add_view(ApplicationButtonsView())
bot.add_view(ApplicationStartButtonView())
activity = discord.Activity(name=f"{len(bot.guilds)} guilds", type=discord.ActivityType.listening)
await bot.change_presence(activity=activity, status = discord.Status.online)
2023-07-14 19:47:41 +00:00
print(f"Logged in as {bot.user}")
2023-08-11 20:23:43 +00:00
await bot.sync_commands(force=True)
for i in bot.guilds:
if str(i.id) not in GuildAppDB.get_all_guilds():
GuildAppDB.create_guild(str(i.id), i.name)
2023-08-15 17:03:10 +00:00
print(f"Entry for {i.id} created")
2023-07-14 19:47:41 +00:00
@bot.event
async def on_guild_join(guild):
activity = discord.Activity(name=f"{len(bot.guilds)} guilds", type=discord.ActivityType.listening)
await bot.change_presence(activity=activity, status = discord.Status.online)
GuildAppDB.create_guild(str(guild.id), guild.name)
print(f"Joined guild {guild.name}: {guild.id}")
@bot.event
async def on_guild_remove(guild):
activity = discord.Activity(name=f"{len(bot.guilds)} guilds", type=discord.ActivityType.listening)
await bot.change_presence(activity=activity, status = discord.Status.online)
print(f"Removed from guild {guild.name}: {guild.id}")
2023-08-10 22:24:03 +00:00
@commands.has_permissions(administrator=True)
@bot.slash_command(description = "Command used to set up the application prompt")
async def start_button(ctx):
view = discord.ui.View()
options = SelectApplicationStartButton(max_values=1, placeholder="Select application")
for i in GuildAppDB.get_applications(str(ctx.guild.id)):
options.add_option(label=i, value=i)
view.add_item(options)
await ctx.response.send_message(view=view, ephemeral=True)
2023-07-14 19:47:41 +00:00
2023-08-10 22:24:03 +00:00
@start_button.error
async def on_application_command_error(ctx, error):
if isinstance(error, commands.MissingPermissions):
await ctx.respond("You need Administrator permissions to use this command", ephemeral=True)
else:
raise error
2023-07-14 19:47:41 +00:00
2023-08-11 20:23:43 +00:00
application = discord.SlashCommandGroup("application", "The main command to manage applications")
@commands.has_permissions(administrator=True)
2023-08-11 20:23:43 +00:00
@application.command(description="Create application")
async def create(ctx, application):
if len(application) < 40:
result = GuildAppDB.add_application_entry(str(ctx.guild.id), application)
if result == "success":
2023-08-15 17:03:10 +00:00
await ctx.response.send_message(f"Successfully created application: {application}\n\nDon't forget to set the response channel!", ephemeral=True) # create a new application, modal with name ask
2023-08-11 20:23:43 +00:00
else:
await ctx.response.send_message(f"please choose shorter name", ephemeral=True)
@commands.has_permissions(administrator=True)
2023-08-11 20:23:43 +00:00
@application.command(description="Remove application")
async def remove(ctx, application):
result = GuildAppDB.remove_application_entry(str(ctx.guild.id), application)
if result == "success":
await ctx.response.send_message(f"Successfully removed application: {application}", ephemeral=True)
else:
2023-08-15 17:03:10 +00:00
await ctx.response.send_message(f"Application {application} not found", ephemeral=True)
2023-08-11 20:23:43 +00:00
@commands.has_permissions(administrator=True)
2023-08-11 20:23:43 +00:00
@application.command(description="List all applications")
async def list(ctx):
applications = GuildAppDB.get_applications(str(ctx.guild.id))
2023-08-15 17:03:10 +00:00
embed = discord.Embed(title="**List of applications**")
embed.set_footer(text="Made by @anorak01", icon_url="https://cdn.discordapp.com/avatars/269164865480949760/a1af9962da20d5ddaa136043cf45d015?size=1024")
for i, app in enumerate(applications):
embed.add_field(value=f"**{i+1}. {app}**", name="", inline=False)
await ctx.response.send_message(embed=embed, ephemeral=True)
2023-08-11 20:23:43 +00:00
@commands.has_permissions(administrator=True)
2023-08-11 20:23:43 +00:00
@application.command(description="Opens editor for selected application")
async def editor(ctx):
view = discord.ui.View()
options = SelectApplicationOptionsEditor(max_values=1, placeholder="Select application")
for i in GuildAppDB.get_applications(str(ctx.guild.id)):
options.add_option(label=i, value=i)
view.add_item(options)
await ctx.response.send_message(view=view, ephemeral=True)
@commands.has_permissions(administrator=True)
@application.command(description="Opens Actions™ editor")
async def actions(ctx):
view = discord.ui.View()
options = SelectActionOptionsEditor(max_values=1, placeholder="Select application")
for i in GuildAppDB.get_applications(str(ctx.guild.id)):
options.add_option(label=i, value=i)
view.add_item(options)
await ctx.response.send_message(view=view, ephemeral=True)
@commands.has_permissions(administrator=True)
2023-08-11 20:23:43 +00:00
@application.command(description="Select response channel for application")
async def response_channel(ctx):
view = discord.ui.View()
options = SelectApplicationOptionsRespChannel(max_values=1, placeholder="Select application")
for i in GuildAppDB.get_applications(str(ctx.guild.id)):
options.add_option(label=i, value=i)
view.add_item(options)
await ctx.response.send_message(view=view, ephemeral=True)
bot.add_application_command(application) # add application group commands
2023-08-11 20:23:43 +00:00
def get_questions_embed(guild_id, application) -> discord.Embed:
embed = discord.Embed(title=f"Application: {application}")
questions, length = GuildAppDB.get_questions(str(guild_id), application)
for i, que in enumerate(questions):
embed.add_field(value=f"**{i+1}. {que}**", name="", inline=False)
embed.set_footer(text="Made by @anorak01", icon_url="https://cdn.discordapp.com/avatars/269164865480949760/a1af9962da20d5ddaa136043cf45d015?size=1024")
return embed
2023-08-11 20:23:43 +00:00
class SelectApplicationStartButton(discord.ui.Select):
async def callback(self, interaction: discord.Interaction):
self.disabled = True
2023-08-11 20:23:43 +00:00
embed = discord.Embed(title="**Start your application!**")
embed.add_field(name=f"Click the button below to start your application for: {self.values[0]}", value="", inline=False)
embed.set_footer(text="Made by @anorak01", icon_url="https://cdn.discordapp.com/avatars/269164865480949760/a1af9962da20d5ddaa136043cf45d015?size=1024")
appStartView = ApplicationStartButtonView()
await interaction.response.edit_message(embed=None, content="Application button created", view=None)
message = await interaction.channel.send(embed = embed, view=appStartView)
StartButtonDB.add_start_msg(str(message.id), str(self.values[0]), str(interaction.guild.id))
2023-08-11 20:23:43 +00:00
class SelectResponseChannelView(discord.ui.View):
@discord.ui.select(
select_type=discord.ComponentType.channel_select,
channel_types=[discord.ChannelType.text],
max_values=1
)
async def select_callback(self, select, interaction: discord.Interaction):
self.disable_all_items()
GuildAppDB.set_response_channel(interaction.guild.id, )
await interaction.response.edit_message(content=f"Selected channel: {select.values[0].mention}", view=None)
class SelectApplicationOptionsEditor(discord.ui.Select):
async def callback(self, interaction: discord.Interaction):
self.disabled = True
editor = ApplicationEditorView(str(interaction.guild.id), self.values[0])
embed = get_questions_embed(str(interaction.guild.id), self.values[0])
await interaction.response.edit_message(embed = embed, view=editor)
class SelectApplicationOptionsRespChannel(discord.ui.Select):
async def callback(self, interaction: discord.Interaction):
self.disabled = True
view = discord.ui.View()
2023-08-15 17:03:10 +00:00
options = SelectResponseChannel(select_type=discord.ComponentType.channel_select, channel_types=[discord.ChannelType.text], max_values=1, placeholder="Select channel")
2023-08-11 20:23:43 +00:00
options.set_app_name(self.values[0])
view.add_item(options)
await interaction.response.edit_message(view=view)
class SelectResponseChannel(discord.ui.Select):
def set_app_name(self, app_name):
self.app_name = app_name
async def callback(self, interaction: discord.Interaction):
self.disabled = True
GuildAppDB.set_response_channel(str(interaction.guild.id), self.app_name, str(self.values[0].id))
await interaction.response.edit_message(content=f"Selected channel: {self.values[0].mention} for application: {self.app_name}", view=None)
2023-08-11 20:23:43 +00:00
class ApplicationEditorView(discord.ui.View):
def __init__(self, guild_id, application_name):
super().__init__(timeout=180)
self.guild_id = guild_id
self.application_name = application_name
@discord.ui.button(
label="New",
style=discord.ButtonStyle.green,
custom_id="editor:add",
row=0
)
async def add_question(self, button: discord.ui.Button, interaction: discord.Interaction):
modal = AddQuestionModal(self.application_name)
await interaction.response.send_modal(modal)
@discord.ui.button(
label="Remove",
style=discord.ButtonStyle.red,
custom_id="editor:remove",
row=0
)
async def remove_question(self, button, interaction: discord.Interaction):
view = ApplicationEditorView(str(interaction.guild.id), self.application_name)
options = RemoveQuestionSelect(max_values=1, placeholder="Select question to remove")
options.set_app_name(self.application_name)
questions, length = GuildAppDB.get_questions(str(interaction.guild.id), self.application_name)
for i, que in enumerate(questions):
options.add_option(label=f"{str(i+1)}. {que}", value=str(i))
view.add_item(options)
await interaction.response.edit_message(view=view)
@discord.ui.button(
label="Edit",
style=discord.ButtonStyle.primary,
custom_id="editor:edit",
row=0
)
async def edit_question(self, button, interaction: discord.Interaction):
view = ApplicationEditorView(str(interaction.guild.id), self.application_name)
options = EditQuestionSelect(max_values=1, placeholder="Select question to edit")
options.set_app_name(self.application_name)
questions, length = GuildAppDB.get_questions(str(interaction.guild.id), self.application_name)
for i, que in enumerate(questions):
options.add_option(label=f"{str(i+1)}. {que}", value=str(i))
view.add_item(options)
await interaction.response.edit_message(view=view)
@discord.ui.button(
label="Move",
style=discord.ButtonStyle.gray,
custom_id="editor:move",
row=0
)
async def move_question(self, button, interaction: discord.Interaction):
view = ApplicationEditorView(str(interaction.guild.id), self.application_name)
options = MoveQuestionSelect(max_values=1, placeholder="Select question to move")
options.set_app_name(self.application_name)
questions, length = GuildAppDB.get_questions(str(interaction.guild.id), self.application_name)
for i, que in enumerate(questions):
options.add_option(label=f"{str(i+1)}. {que}", value=str(i))
view.add_item(options)
await interaction.response.edit_message(view=view)
class AddQuestionModal(discord.ui.Modal):
def __init__(self, app_name):
self.app_name = app_name
super().__init__(discord.ui.InputText(label=f"New Question: "), title = "")
async def callback(self, interaction: discord.Interaction):
question = self.children[0].value
GuildAppDB.add_question(str(interaction.guild.id), self.app_name, question)
embed = get_questions_embed(str(interaction.guild.id), self.app_name)
await interaction.response.edit_message(embed=embed)
class RemoveQuestionSelect(discord.ui.Select):
def set_app_name(self, app_name):
self.app_name = app_name
async def callback(self, interaction: discord.Interaction):
self.disabled = True
GuildAppDB.remove_question(str(interaction.guild.id), self.app_name, int(self.values[0])+1)
editor = ApplicationEditorView(str(interaction.guild.id), self.app_name)
embed = get_questions_embed(str(interaction.guild.id), self.app_name)
await interaction.response.edit_message(embed = embed, view = editor)
class EditQuestionSelect(discord.ui.Select):
def set_app_name(self, app_name):
self.app_name = app_name
async def callback(self, interaction: discord.Interaction):
self.disabled = True
editor = ApplicationEditorView(str(interaction.guild.id), self.app_name)
modal = EditQuestionModal(self.app_name, int(self.values[0])+1)
await interaction.response.send_modal(modal)
await interaction.followup.edit_message(view = editor, message_id=interaction.message.id)
class EditQuestionModal(discord.ui.Modal):
def __init__(self, app_name, question_index):
self.app_name = app_name
self.question_index = question_index
super().__init__(discord.ui.InputText(label=f"Edited Question: "), title = "")
async def callback(self, interaction: discord.Interaction):
question = self.children[0].value
GuildAppDB.edit_question(str(interaction.guild.id), self.app_name, self.question_index, question)
embed = get_questions_embed(str(interaction.guild.id), self.app_name)
await interaction.response.edit_message(embed=embed)
class MoveQuestionSelect(discord.ui.Select):
def set_app_name(self, app_name):
self.app_name = app_name
async def callback(self, interaction: discord.Interaction):
self.disabled = True
view = ApplicationEditorView(str(interaction.guild.id), self.app_name)
options = MoveQuestionSelectNum(max_values=1, placeholder="Select place for move")
options.set_app_name(self.app_name)
options.set_init_index(int(self.values[0])+1)
questions, length = GuildAppDB.get_questions(str(interaction.guild.id), self.app_name)
for i in range(length):
options.add_option(label=str(i+1), value=str(i+1))
view.add_item(options)
await interaction.response.edit_message(view = view)
class MoveQuestionSelectNum(discord.ui.Select):
def set_app_name(self, app_name):
self.app_name = app_name
def set_init_index(self, init_index: int):
self.init_index = init_index
async def callback(self, interaction: discord.Interaction):
self.disabled = True
editor = ApplicationEditorView(str(interaction.guild.id), self.app_name)
GuildAppDB.move_question(str(interaction.guild.id), self.app_name, int(self.init_index), int(self.values[0]))
embed = get_questions_embed(str(interaction.guild.id), self.app_name)
await interaction.response.edit_message(view = editor, embed=embed)
def get_actions_embed(guild_id, application, action_type: ActionInteraction) -> discord.Embed:
embed = discord.Embed(title=f"Application: {application}", description=f"Actions happening on: {action_type.value}")
actions = GuildAppDB.get_actions(str(guild_id), application, action_type)
for i, que in enumerate(actions):
if que["action_type"] == "add_role":
role = bot.get_guild(int(guild_id)).get_role(que["data"]["role_id"]).name
embed.add_field(value=f"**{i+1}. {que['display_type']}: {role}**", name="", inline=False)
else:
embed.add_field(value=f"**{i+1}. {que['display_type']}**", name="", inline=False)
embed.set_footer(text="Made by @anorak01", icon_url="https://cdn.discordapp.com/avatars/269164865480949760/a1af9962da20d5ddaa136043cf45d015?size=1024")
return embed
class ActionAcceptEditorView(discord.ui.View):
def __init__(self, guild_id, application_name):
super().__init__(timeout=180)
self.guild_id = guild_id
self.application_name = application_name
@discord.ui.button(
label="New",
style=discord.ButtonStyle.green,
custom_id="action_accept_editor:add",
row=0
)
async def add_action(self, button: discord.ui.Button, interaction: discord.Interaction):
view = ActionAcceptEditorView(str(interaction.guild.id), self.application_name)
options = AddActionSelect(max_values=1, placeholder="Select action to add")
options.set_app_name(self.application_name)
options.set_action_type(ActionInteraction.ACCEPT)
for i, que in enumerate(usable_actions):
options.add_option(label=f"{str(i+1)}. {que}", value=str(usable_actions[que]))
view.add_item(options)
await interaction.response.edit_message(view=view)
@discord.ui.button(
label="Remove",
style=discord.ButtonStyle.red,
custom_id="action_accept_editor:remove",
row=0
)
async def remove_action(self, button, interaction: discord.Interaction):
view = ActionAcceptEditorView(str(interaction.guild.id), self.application_name)
options = RemoveActionSelect(max_values=1, placeholder="Select action to remove")
options.set_app_name(self.application_name)
actions = GuildAppDB.get_actions(str(interaction.guild.id), self.application_name, action_type=ActionInteraction.ACCEPT)
options.set_action_type(ActionInteraction.ACCEPT)
for i, que in enumerate(actions):
2023-08-20 10:56:34 +00:00
if que["action_type"] == "add_role":
role = interaction.guild.get_role(que["data"]["role_id"]).name
options.add_option(label=f"{str(i+1)}. {que['display_type']}: {role}", value=str(i))
else:
options.add_option(label=f"{str(i+1)}. {que['display_type']}", value=str(i))
view.add_item(options)
await interaction.response.edit_message(view=view)
class ActionDeclineEditorView(discord.ui.View):
def __init__(self, guild_id, application_name):
super().__init__(timeout=180)
self.guild_id = guild_id
self.application_name = application_name
@discord.ui.button(
label="New",
style=discord.ButtonStyle.green,
custom_id="action_decline_editor:add",
row=0
)
async def add_action(self, button: discord.ui.Button, interaction: discord.Interaction):
view = ActionDeclineEditorView(str(interaction.guild.id), self.application_name)
options = AddActionSelect(max_values=1, placeholder="Select action to add")
options.set_app_name(self.application_name)
options.set_action_type(ActionInteraction.DECLINE)
for i, que in enumerate(usable_actions):
options.add_option(label=f"{str(i+1)}. {que}", value=str(usable_actions[que]))
view.add_item(options)
await interaction.response.edit_message(view=view)
@discord.ui.button(
label="Remove",
style=discord.ButtonStyle.red,
custom_id="action_decline_editor:remove",
row=0
)
async def remove_action(self, button, interaction: discord.Interaction):
view = ActionDeclineEditorView(str(interaction.guild.id), self.application_name)
options = RemoveActionSelect(max_values=1, placeholder="Select action to remove")
options.set_app_name(self.application_name)
actions = GuildAppDB.get_actions(str(interaction.guild.id), self.application_name, action_type=ActionInteraction.DECLINE)
options.set_action_type(ActionInteraction.DECLINE)
for i, que in enumerate(actions):
2023-08-20 10:56:34 +00:00
if que["action_type"] == "add_role":
role = interaction.guild.get_role(que["data"]["role_id"]).name
options.add_option(label=f"{str(i+1)}. {que['display_type']}: {role}", value=str(i))
else:
options.add_option(label=f"{str(i+1)}. {que['display_type']}", value=str(i))
view.add_item(options)
await interaction.response.edit_message(view=view)
class AddActionSelect(discord.ui.Select):
def set_app_name(self, app_name):
self.app_name = app_name
def set_action_type(self, action_type):
self.action_type = action_type
async def callback(self, interaction: discord.Interaction):
self.disabled = True
action = self.values[0]
if action == "add_role":
view = discord.ui.View()
options = SelectRoleToAdd(select_type=discord.ComponentType.role_select, max_values=1, placeholder="Select role to add")
options.set_app_name(self.app_name)
options.set_action_type(self.action_type)
view.add_item(options)
await interaction.response.edit_message(view=view)
class SelectRoleToAdd(discord.ui.Select):
def set_app_name(self, app_name):
self.app_name = app_name
def set_action_type(self, action_type):
self.action_type = action_type
async def callback(self, interaction: discord.Interaction):
self.disabled = True
role = self.values[0]
action = {"result": self.action_type, "action_type": "add_role", "display_type": "Add Role", "data": {"role_id": role.id}}
GuildAppDB.add_action(str(interaction.guild.id), self.app_name, action)
if self.action_type == ActionInteraction.ACCEPT:
editor = ActionAcceptEditorView(str(interaction.guild.id), self.app_name)
embed = get_actions_embed(str(interaction.guild.id), self.app_name, ActionInteraction.ACCEPT)
if self.action_type == ActionInteraction.DECLINE:
editor = ActionDeclineEditorView(str(interaction.guild.id), self.app_name)
embed = get_actions_embed(str(interaction.guild.id), self.app_name, ActionInteraction.DECLINE)
await interaction.response.edit_message(embed = embed, view = editor)
class RemoveActionSelect(discord.ui.Select):
def set_app_name(self, app_name):
self.app_name = app_name
def set_action_type(self, action_type: ActionInteraction):
self.action_type = action_type
async def callback(self, interaction: discord.Interaction):
self.disabled = True
2023-08-20 10:56:34 +00:00
GuildAppDB.remove_action(str(interaction.guild.id), self.app_name, self.action_type, int(self.values[0])+1)
if self.action_type == ActionInteraction.ACCEPT:
editor = ActionAcceptEditorView(str(interaction.guild.id), self.app_name)
embed = get_actions_embed(str(interaction.guild.id), self.app_name, ActionInteraction.ACCEPT)
if self.action_type == ActionInteraction.DECLINE:
editor = ActionDeclineEditorView(str(interaction.guild.id), self.app_name)
embed = get_actions_embed(str(interaction.guild.id), self.app_name, ActionInteraction.DECLINE)
await interaction.response.edit_message(embed = embed, view = editor)
class SelectActionOptionsEditor(discord.ui.Select):
async def callback(self, interaction: discord.Interaction):
self.disabled = True
view = discord.ui.View()
options = SelectActionType(max_values=1, placeholder="Select Action™ type")
options.add_option(label="Accept", value="accept")
options.add_option(label="Decline", value="decline")
options.set_app_name(self.values[0])
view.add_item(options)
await interaction.response.edit_message(view=view)
class SelectActionType(discord.ui.Select):
def set_app_name(self, app_name):
self.app_name = app_name
async def callback(self, interaction: discord.Interaction):
self.disabled = True
if self.values[0] == "accept":
editor = ActionAcceptEditorView(str(interaction.guild.id), self.app_name)
embed = get_actions_embed(str(interaction.guild.id), self.app_name, ActionInteraction.ACCEPT)
if self.values[0] == "decline":
editor = ActionDeclineEditorView(str(interaction.guild.id), self.app_name)
embed = get_actions_embed(str(interaction.guild.id), self.app_name, ActionInteraction.DECLINE)
await interaction.response.edit_message(embed = embed, view=editor)
2023-08-10 22:24:03 +00:00
# View with button that starts the application process
class ApplicationStartButtonView(discord.ui.View):
def __init__(self):
super().__init__(timeout=None)
2023-07-14 19:47:41 +00:00
2023-08-10 22:24:03 +00:00
@discord.ui.button(
label="Start application!",
style=discord.ButtonStyle.green,
custom_id=f"persistent:start_application",
)
async def start_app(self, button: discord.ui.Button, interaction: discord.Interaction):
app_name, guild_id = StartButtonDB.get_start_msg(interaction.message.id)
questions, max_questions=GuildAppDB.get_questions(guild_id, app_name)
2023-08-15 17:03:10 +00:00
if questions == "error on get questions: application not found":
await interaction.response.send_message(content="Application no longer exists", ephemeral=True)
return
response_channel = GuildAppDB.get_response_channel(guild_id, app_name)
2023-07-14 19:47:41 +00:00
2023-08-10 22:24:03 +00:00
user = await interaction.user.create_dm()
2023-08-15 17:03:10 +00:00
embedd = discord.Embed(title=f'{interaction.guild.name} application: {app_name}', description="Hey! Your application has started. You have 300 seconds to complete it.")
2023-08-10 22:24:03 +00:00
embedd.add_field(value=f'You can cancel the application by answering "cancel" to any of the questions', name="", inline=False)
embedd.set_footer(text="Made by @anorak01", icon_url="https://cdn.discordapp.com/avatars/269164865480949760/a1af9962da20d5ddaa136043cf45d015?size=1024")
2023-07-14 19:47:41 +00:00
2023-08-10 22:24:03 +00:00
try:
await user.send(embed=embedd)
except discord.Forbidden:
await interaction.response.send_message(content="Can't start application. Please allow direct messages from server members in your privacy settings.", ephemeral=True)
return
2023-07-14 19:47:41 +00:00
2023-08-10 22:24:03 +00:00
await interaction.response.send_message(content="Application started", ephemeral=True)
2023-07-14 19:47:41 +00:00
2023-08-10 22:24:03 +00:00
application = {'userId': interaction.user.id}
2023-07-14 19:47:41 +00:00
2023-08-10 22:24:03 +00:00
for i in range(0, max_questions):
try:
embed = discord.Embed(title=f'Question [{i+1}/{max_questions}]', description=questions[i])
await user.send(embed=embed)
response = await bot.wait_for('message', check=lambda m: m.author == interaction.user and m.channel == user, timeout=300)
if response.content.startswith("cancel"):
await user.send("Your application has been cancelled")
return
else:
application[f'question{i}'] = response.content
except asyncio.TimeoutError:
await user.send(content="As you haven't replied in 300 seconds, your application has been cancelled")
return
try:
with open('applications.json', 'r') as f:
data = json.load(f)
except (FileNotFoundError, json.JSONDecodeError):
data = []
data.append(application)
with open('applications.json', 'w') as f:
json.dump(data, f)
channel = bot.get_channel(int(response_channel))
2023-08-15 17:03:10 +00:00
embed = discord.Embed(title=f"Application: {app_name}\nUser: {interaction.user.display_name}")
2023-08-10 22:24:03 +00:00
for i in range(0, max_questions):
embed.add_field(name=f'{questions[i]}', value=application[f'question{i}'], inline=False)
embed.set_footer(text=f"Applicant ID: {interaction.user.id}")
appView = ApplicationButtonsView()
msg = await channel.send(embed=embed, view=appView)
2023-07-14 19:47:41 +00:00
2023-08-20 10:56:34 +00:00
MessageDB.add_application_msg(msg.id, interaction.user.id, interaction.guild.id, app_name)
2023-07-14 19:47:41 +00:00
2023-08-10 22:24:03 +00:00
await user.send('Thank you for applying!')
2023-07-14 19:47:41 +00:00
2023-08-10 22:24:03 +00:00
# View containing accept and decline buttons for each application
2023-07-14 19:47:41 +00:00
class ApplicationButtonsView(discord.ui.View):
def __init__(self):
super().__init__(timeout=None)
@discord.ui.button(
label="Accept",
style=discord.ButtonStyle.green,
custom_id=f"persistent:accept",
)
async def accept(self, button: discord.ui.Button, interaction: discord.Interaction):
msg_id = str(interaction.message.id)
2023-08-08 15:34:51 +00:00
2023-08-20 10:56:34 +00:00
user_id, guild_id, app_name = MessageDB.get_application_msg(msg_id)
2023-08-01 21:54:41 +00:00
2023-07-14 19:47:41 +00:00
modal = ApplicationModal(title=f"Accepting: {bot.get_user(user_id).display_name}")
modal.set_action("acc")
modal.add_item(discord.ui.InputText(label=f"Reason: "))
await interaction.response.send_modal(modal)
@discord.ui.button(
label="Decline",
style=discord.ButtonStyle.red,
custom_id=f"persistent:decline",
)
async def decline(self, button: discord.ui.Button, interaction: discord.Interaction):
msg_id = str(interaction.message.id)
2023-08-08 15:34:51 +00:00
2023-08-20 10:56:34 +00:00
user_id, guild_id, app_name = MessageDB.get_application_msg(msg_id)
2023-08-01 21:54:07 +00:00
2023-07-14 19:47:41 +00:00
modal = ApplicationModal(title=f"Declining: {bot.get_user(user_id).display_name}")
modal.set_action("dec")
modal.add_item(discord.ui.InputText(label=f"Reason: "))
await interaction.response.send_modal(modal)
2023-08-10 22:24:03 +00:00
# Modal functioning as a callback for Accepting/Declining application
2023-07-14 19:47:41 +00:00
class ApplicationModal(discord.ui.Modal):
def set_action(self, action):
self.action = action
async def callback(self, interaction: discord.Interaction):
reason = self.children[0].value
msg_id = str(interaction.message.id)
2023-08-20 10:56:34 +00:00
user_id, guild_id, app_name = MessageDB.get_application_msg(msg_id)
2023-07-14 19:47:41 +00:00
if self.action == "acc":
user = await bot.get_user(user_id).create_dm()
2023-08-15 17:03:10 +00:00
await user.send(f"Your application has been accepted!")
2023-07-14 19:47:41 +00:00
await user.send(f"Reason: {reason}")
await interaction.response.send_message(content="Application accepted", ephemeral=True)
2023-08-20 10:56:34 +00:00
role = get(interaction.message.guild.roles, name="CreatTopian")
2023-08-20 10:56:34 +00:00
actions = GuildAppDB.get_actions(str(guild_id), app_name, ActionInteraction.ACCEPT)
for i in actions:
if i["action_type"] == "add_role":
role = interaction.message.guild.get_role(int(i["data"]["role_id"]))
user = interaction.message.guild.get_member(int(user_id))
await user.add_roles(role)
else:
print("unknown action")
2023-08-15 17:03:10 +00:00
#await discord.utils.get(interaction.message.guild.members, id=int(user_id)).add_roles(role)
emb = interaction.message.embeds[0]
emb.colour = discord.Colour.green()
2023-07-16 09:10:19 +00:00
embed = discord.Embed(title='Accepted')
embed.add_field(name=f'Reason:', value=reason, inline=False)
embed.colour = discord.Colour.green()
await interaction.followup.edit_message(message_id = interaction.message.id, embeds=[emb, embed])
view = discord.ui.View.from_message(interaction.message)
view.disable_all_items()
await interaction.followup.edit_message(message_id = interaction.message.id, view = view)
2023-08-20 10:56:34 +00:00
2023-07-14 19:47:41 +00:00
if self.action == "dec":
user = await bot.get_user(user_id).create_dm()
2023-08-15 17:03:10 +00:00
await user.send(f"Your application has been declined.")
2023-07-14 19:47:41 +00:00
await user.send(f"Reason: {reason}")
await interaction.response.send_message(content="Application declined", ephemeral=True)
2023-08-20 10:56:34 +00:00
actions = GuildAppDB.get_actions(str(guild_id), app_name, ActionInteraction.DECLINE)
for i in actions:
if i["action_type"] == "add_role":
role = interaction.message.guild.get_role(int(i["data"]["role_id"]))
user = interaction.message.guild.get_member(int(user_id))
await user.add_roles(role)
else:
print("unknown action")
emb = interaction.message.embeds[0]
emb.colour = discord.Colour.red()
2023-07-16 09:10:19 +00:00
embed = discord.Embed(title='Declined')
embed.add_field(name=f'Reason:', value=reason, inline=False)
embed.colour = discord.Colour.red()
await interaction.followup.edit_message(message_id = interaction.message.id, embeds=[emb, embed])
view = discord.ui.View.from_message(interaction.message)
view.disable_all_items()
await interaction.followup.edit_message(message_id = interaction.message.id, view = view)
2023-07-14 19:47:41 +00:00
2023-08-10 22:24:03 +00:00
# end
2023-07-14 19:47:41 +00:00
bot.run(TOKEN)