-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Refactored to be just command interface * Added file to manage the command and subcommands * Added file to manage list subcommand * Added file to manage signup subcommand * Added file to manage pause subcommand * Added file to manage profile subcommand * Added file to manage resume subcommand * Added file to manage clear subcommand * Added file to manage domain subcommand * Refactored subcommand structures of interviewer command * Refactored clear subcommand of interviewer * Refactored domain subcommand of interviewer * Refactored list subcommand of interviewer * Refactored pause subcommand of interviewer * Refactored profile subcommand of interviewer * Refactored resume subcommand of interviewer * Refactored signup subcommand of interviewer * Made domain field of domain subcommand required * Fixed bug with list subcommand when database is empty * Fixed linting issues * Modified subcommand comments
- Loading branch information
1 parent
1813bd7
commit b3c9cd0
Showing
8 changed files
with
416 additions
and
207 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { container } from '@sapphire/framework'; | ||
import { clearProfile, getInterviewer } from '../../components/interviewer'; | ||
import { | ||
CodeyCommandDetails, | ||
SapphireMessageExecuteType, | ||
SapphireMessageResponse, | ||
getUserFromMessage, | ||
} from '../../codeyCommand'; | ||
|
||
const interviewerClearExecuteCommand: SapphireMessageExecuteType = async ( | ||
_client, | ||
messageFromUser, | ||
_args, | ||
): Promise<SapphireMessageResponse> => { | ||
const id = getUserFromMessage(messageFromUser).id; | ||
|
||
// Check if user signed up to be interviewer | ||
if (!(await getInterviewer(id))) { | ||
return `You don't seem to have signed up yet. Please sign up using \`${container.botPrefix}interviewer signup <calendarUrl>\`!`; | ||
} | ||
|
||
// Clear interviewer data | ||
await clearProfile(id); | ||
return 'Your interviewer profile has been cleared!'; | ||
}; | ||
|
||
export const interviewerClearCommandDetails: CodeyCommandDetails = { | ||
name: 'clear', | ||
aliases: ['clr'], | ||
description: 'Clear all your interviewer data', | ||
detailedDescription: `**Examples:** | ||
\`${container.botPrefix}interviewer clear\``, | ||
|
||
isCommandResponseEphemeral: false, | ||
messageWhenExecutingCommand: 'Clearing your interviewer profile...', | ||
executeCommand: interviewerClearExecuteCommand, | ||
messageIfFailure: 'Could not clear your interviewer profile', | ||
options: [], | ||
subcommandDetails: {}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { container } from '@sapphire/framework'; | ||
import { | ||
availableDomains, | ||
getAvailableDomainsString, | ||
getInterviewer, | ||
toggleDomain, | ||
} from '../../components/interviewer'; | ||
import { | ||
CodeyCommandDetails, | ||
CodeyCommandOptionType, | ||
SapphireMessageExecuteType, | ||
SapphireMessageResponse, | ||
getUserFromMessage, | ||
} from '../../codeyCommand'; | ||
|
||
const interviewerDomainExecuteCommand: SapphireMessageExecuteType = async ( | ||
_client, | ||
messageFromUser, | ||
args, | ||
): Promise<SapphireMessageResponse> => { | ||
const domain: string | undefined = <string>args['domain_name']; | ||
if (domain && !(domain.toLowerCase() in availableDomains)) { | ||
return `You entered an invalid domain. Please enter one of ${getAvailableDomainsString()}.`; | ||
} | ||
|
||
const id = getUserFromMessage(messageFromUser).id; | ||
// Check if user signed up to be interviewer | ||
if (!(await getInterviewer(id))) { | ||
return `You don't seem to have signed up yet. Please sign up using \`${container.botPrefix}interviewer signup <calendarUrl>\`!`; | ||
} | ||
|
||
// Add or remove domain to/from interviewer | ||
const inDomain = await toggleDomain(id, domain); | ||
return inDomain | ||
? `You have been successfully removed from ${availableDomains[domain]}` | ||
: `You have been successfully added to ${availableDomains[domain]}`; | ||
}; | ||
|
||
export const interviewerDomainCommandDetails: CodeyCommandDetails = { | ||
name: 'domain', | ||
aliases: ['domain'], | ||
description: 'Add/remove a domain of your choice', | ||
detailedDescription: `**Examples:** | ||
\`${container.botPrefix}interviewer domain frontend\``, | ||
|
||
isCommandResponseEphemeral: false, | ||
messageWhenExecutingCommand: 'Modifying domain data...', | ||
executeCommand: interviewerDomainExecuteCommand, | ||
messageIfFailure: 'Could not modify domain data', | ||
options: [ | ||
{ | ||
name: 'domain_name', | ||
description: 'A valid domain name', | ||
type: CodeyCommandOptionType.STRING, | ||
required: true, | ||
}, | ||
], | ||
subcommandDetails: {}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import { container } from '@sapphire/framework'; | ||
import { EmbedBuilder } from 'discord.js'; | ||
import _ from 'lodash'; | ||
import { | ||
availableDomains, | ||
getAvailableDomainsString, | ||
getInterviewerDomainsString, | ||
getInterviewers, | ||
Interviewer, | ||
} from '../../components/interviewer'; | ||
import { DEFAULT_EMBED_COLOUR } from '../../utils/embeds'; | ||
import { | ||
CodeyCommandDetails, | ||
CodeyCommandOptionType, | ||
SapphireMessageExecuteType, | ||
SapphireMessageResponse, | ||
} from '../../codeyCommand'; | ||
|
||
const RESULTS_PER_PAGE = 6; | ||
|
||
const getInterviewerDisplayInfo = async (interviewer: Interviewer): Promise<string> => { | ||
const { client } = container; | ||
const user = await client.users.fetch(interviewer['user_id']); | ||
const userDomainsAddIn = await getInterviewerDomainsString(interviewer['user_id']); | ||
if (userDomainsAddIn === '') { | ||
return `${user} | [Calendar](${interviewer['link']})\n\n`; | ||
} else { | ||
return `${user} | [Calendar](${interviewer['link']}) | ${userDomainsAddIn}\n\n`; | ||
} | ||
}; | ||
|
||
const interviewerListExecuteCommand: SapphireMessageExecuteType = async ( | ||
_client, | ||
_messageFromUser, | ||
args, | ||
): Promise<SapphireMessageResponse> => { | ||
const domain: string | undefined = <string>args['domain']; | ||
if (domain && !(domain.toLowerCase() in availableDomains)) { | ||
return `You entered an invalid domain. Please enter one of ${getAvailableDomainsString()}.`; | ||
} | ||
|
||
// Query interviewers | ||
const interviewers = await getInterviewers(domain); | ||
// Shuffles interviewers to load balance | ||
const shuffledInterviewers = _.shuffle(interviewers); | ||
// Only show up to page limit | ||
const interviewersToShow = shuffledInterviewers.slice(0, RESULTS_PER_PAGE); | ||
// Get information from each interviewer | ||
const interviewersInfo = await Promise.all( | ||
interviewersToShow.map((interviewer) => getInterviewerDisplayInfo(interviewer)), | ||
); | ||
|
||
// If there's no data, then interviewersInfo is an array of undefined, which messed things up | ||
// Thus need to display something else instead of interviewersInfo.join() | ||
const embedDescription = | ||
interviewersInfo[0] === undefined ? 'No data to display' : interviewersInfo.join(''); | ||
|
||
// Construct embed for display | ||
const title = domain | ||
? `Available Interviewers for ${availableDomains[domain]}` | ||
: 'Available Interviewers'; | ||
const outEmbed = new EmbedBuilder() | ||
.setColor(DEFAULT_EMBED_COLOUR) | ||
.setTitle(title) | ||
.setDescription(embedDescription); | ||
return { embeds: [outEmbed] }; | ||
}; | ||
|
||
export const interviewerListCommandDetails: CodeyCommandDetails = { | ||
name: 'list', | ||
aliases: ['ls'], | ||
description: 'List all interviewers or those under a specific domain', | ||
detailedDescription: `**Examples:** | ||
\`${container.botPrefix}interviewer list\` | ||
\`${container.botPrefix}interviewer list backend\``, | ||
|
||
isCommandResponseEphemeral: false, | ||
messageWhenExecutingCommand: 'Listing interviewers...', | ||
executeCommand: interviewerListExecuteCommand, | ||
messageIfFailure: 'Could not list interviewers', | ||
options: [ | ||
{ | ||
name: 'domain', | ||
description: 'The domain to be examined', | ||
type: CodeyCommandOptionType.STRING, | ||
required: false, | ||
}, | ||
], | ||
subcommandDetails: {}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { container } from '@sapphire/framework'; | ||
import { getInterviewer, pauseProfile } from '../../components/interviewer'; | ||
import { | ||
CodeyCommandDetails, | ||
SapphireMessageExecuteType, | ||
SapphireMessageResponse, | ||
getUserFromMessage, | ||
} from '../../codeyCommand'; | ||
|
||
const interviewerPauseExecuteCommand: SapphireMessageExecuteType = async ( | ||
_client, | ||
messageFromUser, | ||
_args, | ||
): Promise<SapphireMessageResponse> => { | ||
const id = getUserFromMessage(messageFromUser).id; | ||
|
||
// Check if user signed up to be interviewer | ||
if (!(await getInterviewer(id))) { | ||
return `You don't seem to have signed up yet, please sign up using \`${container.botPrefix}interviewer signup <calendarUrl>\`!`; | ||
} | ||
|
||
// Pause interviewer data | ||
await pauseProfile(id); | ||
return `Your interviewer profile has been paused! You will not appear in interviewer queries anymore, until you run \`${container.botPrefix}interviewer resume\`.`; | ||
}; | ||
|
||
export const interviewerPauseCommandDetails: CodeyCommandDetails = { | ||
name: 'pause', | ||
aliases: ['ps'], | ||
description: 'Put your interviewer profile on pause', | ||
detailedDescription: `**Examples:** | ||
\`${container.botPrefix}interviewer pause\``, | ||
|
||
isCommandResponseEphemeral: false, | ||
messageWhenExecutingCommand: 'Pausing profile...', | ||
executeCommand: interviewerPauseExecuteCommand, | ||
messageIfFailure: 'Could not pause profile', | ||
options: [], | ||
subcommandDetails: {}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { container } from '@sapphire/framework'; | ||
import { EmbedBuilder } from 'discord.js'; | ||
import _ from 'lodash'; | ||
import { getDomains, getDomainsString, getInterviewer } from '../../components/interviewer'; | ||
import { DEFAULT_EMBED_COLOUR } from '../../utils/embeds'; | ||
import { | ||
CodeyCommandDetails, | ||
SapphireMessageExecuteType, | ||
SapphireMessageResponse, | ||
getUserFromMessage, | ||
} from '../../codeyCommand'; | ||
|
||
const interviewerProfileExecuteCommand: SapphireMessageExecuteType = async ( | ||
_client, | ||
messageFromUser, | ||
_args, | ||
): Promise<SapphireMessageResponse> => { | ||
const id = getUserFromMessage(messageFromUser).id; | ||
|
||
// Check if user signed up to be interviewer | ||
const interviewer = await getInterviewer(id); | ||
if (!interviewer) { | ||
return `You don't seem to have signed up yet. Please sign up using \`${container.botPrefix}interviewer signup <calendarUrl>\`!`; | ||
} | ||
|
||
// Get domains | ||
const domains = await getDomains(id); | ||
|
||
// Build output embed | ||
const profileEmbed = new EmbedBuilder() | ||
.setColor(DEFAULT_EMBED_COLOUR) | ||
.setTitle('Interviewer Profile'); | ||
profileEmbed.addFields([ | ||
{ name: '**Link**', value: interviewer.link }, | ||
{ name: '**Domains**', value: _.isEmpty(domains) ? 'None' : getDomainsString(domains) }, | ||
]); | ||
|
||
return { embeds: [profileEmbed] }; | ||
}; | ||
|
||
export const interviewerProfileCommandDetails: CodeyCommandDetails = { | ||
name: 'profile', | ||
aliases: ['pf'], | ||
description: 'Display your interviewer profile data', | ||
detailedDescription: `**Examples:** | ||
\`${container.botPrefix}interviewer profile\``, | ||
|
||
isCommandResponseEphemeral: false, | ||
messageWhenExecutingCommand: 'Displaying profile...', | ||
executeCommand: interviewerProfileExecuteCommand, | ||
messageIfFailure: 'Could not display profile', | ||
options: [], | ||
subcommandDetails: {}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { container } from '@sapphire/framework'; | ||
import { getInterviewer, resumeProfile } from '../../components/interviewer'; | ||
import { | ||
CodeyCommandDetails, | ||
SapphireMessageExecuteType, | ||
SapphireMessageResponse, | ||
getUserFromMessage, | ||
} from '../../codeyCommand'; | ||
|
||
const interviewerResumeExecuteCommand: SapphireMessageExecuteType = async ( | ||
_client, | ||
messageFromUser, | ||
_args, | ||
): Promise<SapphireMessageResponse> => { | ||
const id = getUserFromMessage(messageFromUser).id; | ||
|
||
// Check if user signed up to be interviewer | ||
if (!(await getInterviewer(id))) { | ||
`You don't seem to have signed up yet. Please sign up using \`${container.botPrefix}interviewer signup <calendarUrl>\`!`; | ||
} | ||
|
||
// Resume interviewer data | ||
await resumeProfile(id); | ||
return 'Your interviewer profile has been resumed!'; | ||
}; | ||
|
||
export const interviewerResumeCommandDetails: CodeyCommandDetails = { | ||
name: 'resume', | ||
aliases: ['resume'], | ||
description: 'Resume your interviewer profile', | ||
detailedDescription: `**Examples:** | ||
\`${container.botPrefix}interviewer resume\``, | ||
|
||
isCommandResponseEphemeral: false, | ||
messageWhenExecutingCommand: 'Resuming profile...', | ||
executeCommand: interviewerResumeExecuteCommand, | ||
messageIfFailure: 'Could not resume profile', | ||
options: [], | ||
subcommandDetails: {}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import { container } from '@sapphire/framework'; | ||
import { getEmojiByName } from '../../components/emojis'; | ||
import { parseLink, upsertInterviewer } from '../../components/interviewer'; | ||
import { | ||
CodeyCommandDetails, | ||
CodeyCommandOptionType, | ||
SapphireMessageExecuteType, | ||
SapphireMessageResponse, | ||
getUserFromMessage, | ||
} from '../../codeyCommand'; | ||
|
||
const interviewerSignupExecuteCommand: SapphireMessageExecuteType = async ( | ||
_client, | ||
messageFromUser, | ||
args, | ||
): Promise<SapphireMessageResponse> => { | ||
const id = getUserFromMessage(messageFromUser).id; | ||
|
||
// Get calendar URL from the 1st capture group | ||
const calendarUrl = <string>args['calendar_url']; | ||
|
||
// Parse link and checks for validity | ||
const parsedUrl = parseLink(calendarUrl); | ||
if (!parsedUrl) { | ||
return `I don't seem to recognize your meeting link. Be sure to use calendly or x.ai.`; | ||
} | ||
|
||
// Add or update interviewer info | ||
await upsertInterviewer(id, parsedUrl); | ||
return `Your info has been updated. Thanks for helping out! ${getEmojiByName( | ||
'codey_love', | ||
)?.toString()}`; | ||
}; | ||
|
||
export const interviewerSignupCommandDetails: CodeyCommandDetails = { | ||
name: 'signup', | ||
aliases: ['signup'], | ||
description: 'Sign yourself up to be an interviewer!', | ||
detailedDescription: `**Examples:** | ||
\`${container.botPrefix}interviewer signup www.calendly.com\``, | ||
|
||
isCommandResponseEphemeral: false, | ||
messageWhenExecutingCommand: 'Signing up for a profile...', | ||
executeCommand: interviewerSignupExecuteCommand, | ||
messageIfFailure: 'Could not sign up for a profile', | ||
options: [ | ||
{ | ||
name: 'calendar_url', | ||
description: 'A valid calendly.com or x.ai calendar link', | ||
type: CodeyCommandOptionType.STRING, | ||
required: true, | ||
}, | ||
], | ||
subcommandDetails: {}, | ||
}; |
Oops, something went wrong.