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
import sqlite3
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-07-14 19:47:41 +00:00
load_dotenv ( )
TOKEN = os . getenv ( " TOKEN " )
SERVER_NAME = os . getenv ( " SERVER_NAME " )
2023-07-15 21:32:28 +00:00
CHANNEL_ID = os . getenv ( " CHANNEL_ID " )
2023-07-14 19:47:41 +00:00
bot = discord . Bot ( intents = discord . Intents . all ( ) )
2023-07-15 21:32:28 +00:00
channel_id = int ( CHANNEL_ID )
2023-07-14 19:47:41 +00:00
questions = {
1 : " What is your Minecraft username? " ,
2 : " How did you learn about CraftTopia? (If it was from a friend or a website we would like to know either who or where just to know where credit is due) " ,
3 : " Have you been a part of a minecraft community before, if so, let us know what your experience was with that community. " ,
4 : " How old are you? " ,
5 : " Do you have a good microphone for proximity chat? " ,
6 : " Do you plan on spending at least 2-3 hours a week on the server (our current definition of active) " ,
7 : " What will you be able to do to help us grow and build our community? " ,
8 : " Any other questions or concerns? "
}
max_questions = len ( questions )
@bot.event
async def on_ready ( ) :
bot . add_view ( ApplicationButtonsView ( ) )
2023-07-18 14:02:42 +00:00
bot . add_view ( ApplicationStartButtonView ( ) )
2023-07-14 19:47:41 +00:00
print ( f " Logged in as { bot . user } " )
2023-07-15 21:32:28 +00:00
@bot.slash_command ( description = " Command used to apply " )
2023-07-14 19:47:41 +00:00
async def apply ( ctx ) :
await ctx . response . send_message ( content = " Application started " , ephemeral = True )
user = await ctx . author . create_dm ( )
await user . send ( " Hey! Your application has started. You have 300 seconds to complete it. " )
application = { ' userId ' : ctx . author . id }
for i in range ( 1 , max_questions + 1 ) :
embed = discord . Embed ( title = f ' Question [ { i } / { max_questions } ] ' , description = questions [ i ] )
await user . send ( embed = embed )
response = await bot . wait_for ( ' message ' , check = lambda m : m . author == ctx . author and m . channel == user , timeout = 300 )
application [ f ' question { i } ' ] = response . content
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 ( channel_id )
embed = discord . Embed ( title = ' Application: ' + ctx . author . display_name )
for i in range ( 1 , max_questions + 1 ) :
2023-07-16 08:53:39 +00:00
embed . add_field ( name = f ' { questions [ i ] } ' , value = application [ f ' question { i } ' ] , inline = False )
2023-07-14 19:47:41 +00:00
embed . set_footer ( text = f " Applicant ID: { ctx . author . id } " )
appView = ApplicationButtonsView ( )
msg = await channel . send ( embed = embed , view = appView )
print ( msg . id )
data = ( msg . id , ctx . author . id , ctx . guild . id )
con = sqlite3 . connect ( " applications.db " )
cur = con . cursor ( )
cur . execute ( f " INSERT INTO app_msg_db VALUES (?, ?, ?) " , data )
con . commit ( )
await user . send ( ' Thank you for applying! ' )
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 ) :
self . disable_all_items ( )
print ( interaction . message . id )
msg_id = str ( interaction . message . id )
con = sqlite3 . connect ( " applications.db " )
cur = con . cursor ( )
cur . execute ( f " SELECT user_id, guild_id FROM app_msg_db WHERE msg_id= { msg_id } " )
user_id , guild_id = cur . fetchone ( )
#await interaction.response.send_message(f"Accepted {user_id}, guild {guild_id}", ephemeral=True)
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 )
await interaction . followup . edit_message ( message_id = interaction . message . id , view = self )
@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 ) :
self . disable_all_items ( )
print ( interaction . message . id )
msg_id = str ( interaction . message . id )
con = sqlite3 . connect ( " applications.db " )
cur = con . cursor ( )
cur . execute ( f " SELECT user_id, guild_id FROM app_msg_db WHERE msg_id= { msg_id } " )
user_id , guild_id = cur . fetchone ( )
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 )
await interaction . followup . edit_message ( message_id = interaction . message . id , view = self )
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 )
con = sqlite3 . connect ( " applications.db " )
cur = con . cursor ( )
cur . execute ( f " SELECT user_id, guild_id FROM app_msg_db WHERE msg_id= { msg_id } " )
user_id , guild_id = cur . fetchone ( )
if self . action == " acc " :
user = await bot . get_user ( user_id ) . create_dm ( )
await user . send ( f " You have been accepted to the CreatTopia Minecraft server! " )
await user . send ( f " Reason: { reason } " )
await interaction . response . send_message ( content = " Application accepted " , ephemeral = True )
2023-07-14 20:57:01 +00:00
role = get ( interaction . message . guild . roles , name = " CreatTopian " )
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-07-14 19:47:41 +00:00
if self . action == " dec " :
user = await bot . get_user ( user_id ) . create_dm ( )
await user . send ( f " You have been declined access to the CreatTopia Minecraft server. " )
await user . send ( f " Reason: { reason } " )
await interaction . response . send_message ( content = " Application declined " , ephemeral = True )
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-07-14 19:47:41 +00:00
2023-07-17 10:26:28 +00:00
@bot.slash_command ( description = " Command used to set up the application prompt " )
async def setup ( ctx ) :
embed = discord . Embed ( title = " **Start your application!** " )
embed . add_field ( name = " Click the button below to start your application " , value = " " , inline = False )
appStartView = ApplicationStartButtonView ( )
await ctx . response . send_message ( " Message set up " , ephemeral = True )
await ctx . channel . send ( embeds = [ embed ] , view = appStartView )
class ApplicationStartButtonView ( discord . ui . View ) :
def __init__ ( self ) :
super ( ) . __init__ ( timeout = None )
@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 ) :
user = await interaction . user . create_dm ( )
2023-07-18 14:02:42 +00:00
embedd = discord . Embed ( title = f ' CreaTopia Application ' , description = " Hey! Your application has started. You have 300 seconds to complete it. " )
embedd . add_field ( value = f ' You can cancel the application by answering " cancel " to any of the questions ' , name = " " , inline = False )
2023-08-01 20:35:23 +00:00
try :
await user . send ( embed = embedd )
except discord . Forbidden :
2023-08-01 21:52:03 +00:00
await interaction . response . send_message ( content = " Can ' t start application. Please allow direct messages from server members in your privacy settings. " , ephemeral = True )
2023-08-01 20:35:23 +00:00
return
await interaction . response . send_message ( content = " Application started " , ephemeral = True )
2023-07-17 10:26:28 +00:00
application = { ' userId ' : interaction . user . id }
for i in range ( 1 , max_questions + 1 ) :
2023-08-01 20:42:18 +00:00
try :
embed = discord . Embed ( title = f ' Question [ { i } / { 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
2023-08-01 21:52:03 +00:00
except asyncio . TimeoutError :
await user . send ( content = " As you haven ' t replied in 300 seconds, your application has been cancelled " )
return
2023-07-17 10:26:28 +00:00
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 ( channel_id )
embed = discord . Embed ( title = ' Application: ' + interaction . user . display_name )
for i in range ( 1 , max_questions + 1 ) :
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 )
print ( msg . id )
data = ( msg . id , interaction . user . id , interaction . guild . id )
con = sqlite3 . connect ( " applications.db " )
cur = con . cursor ( )
cur . execute ( f " INSERT INTO app_msg_db VALUES (?, ?, ?) " , data )
con . commit ( )
await user . send ( ' Thank you for applying! ' )
2023-07-14 19:47:41 +00:00
bot . run ( TOKEN )