2023-07-14 19:47:41 +00:00
# db - msg_id, user_id, guild_id
2023-08-01 21:52:03 +00:00
import asyncio
2023-07-14 19:47:41 +00:00
import discord
import os
import json
2023-08-19 21:09:51 +00:00
import pickle
2023-07-14 19:47:41 +00:00
from dotenv import load_dotenv
from discord . ui import Modal , InputText
2023-07-14 20:57:01 +00:00
from discord . utils import get
2023-08-09 20:54:38 +00:00
from discord . ext import commands
2023-08-08 15:34:51 +00:00
from dbutil import MessageDB
2023-08-12 11:32:25 +00:00
from dbutil import StartButtonDB
2023-08-10 20:29:21 +00:00
from dbutil import GuildAppDB
2023-07-14 19:47:41 +00:00
2023-08-19 21:09:51 +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 ( ) )
2023-07-18 14:02:42 +00:00
bot . add_view ( ApplicationStartButtonView ( ) )
2023-08-09 22:08:45 +00:00
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 )
2023-08-10 20:29:21 +00:00
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
2023-08-09 22:08:45 +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 )
2023-08-10 20:29:21 +00:00
GuildAppDB . create_guild ( str ( guild . id ) , guild . name )
print ( f " Joined guild { guild . name } : { guild . id } " )
2023-08-09 22:08:45 +00:00
@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 )
2023-08-10 20:29:21 +00:00
print ( f " Removed from guild { guild . name } : { guild . id } " )
2023-08-09 22:08:45 +00:00
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 ) :
2023-08-12 11:32:25 +00:00
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 " )
2023-08-12 11:32:25 +00:00
@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 \n Don ' 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 )
2023-08-12 11:32:25 +00:00
@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
2023-08-12 11:32:25 +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
2023-08-12 11:32:25 +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 )
2023-08-19 21:09:51 +00:00
@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 )
2023-08-12 11:32:25 +00:00
@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 )
2023-08-12 11:32:25 +00:00
bot . add_application_command ( application ) # add application group commands
2023-08-11 20:23:43 +00:00
2023-08-12 11:32:25 +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
2023-08-12 11:32:25 +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
2023-08-12 11:32:25 +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 )
2023-08-12 11:32:25 +00:00
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 )
2023-08-19 21:09:51 +00:00
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 ) )
2023-08-19 21:09:51 +00:00
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 ) )
2023-08-19 21:09:51 +00:00
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 )
2023-08-19 21:09:51 +00:00
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 ) :
2023-08-12 11:32:25 +00:00
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
2023-08-12 11:32:25 +00:00
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 )
2023-08-12 11:32:25 +00:00
channel = bot . get_channel ( int ( response_channel ) )
2023-08-15 17:03:10 +00:00
embed = discord . Embed ( title = f " Application: { app_name } \n User: { 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
2023-07-14 20:57:01 +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)
2023-07-15 21:32:28 +00:00
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 ] )
2023-08-04 13:40:40 +00:00
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 " )
2023-07-15 21:32:28 +00:00
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 ] )
2023-08-04 13:40:40 +00:00
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-07-17 10:26:28 +00:00
2023-08-10 22:24:03 +00:00
# end
2023-07-14 19:47:41 +00:00
bot . run ( TOKEN )