Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { Handler, MessageFilterCallback } from './handler';
- // Structure for all questions
- // `description` is the actual "question" that the user responds to
- // `property` is the object key that will be set
- // `fn` is the filter function that's called to check whether a given message is valid
- // `errorMessage` is the error message that is sent if the given message does not match filter
- // `toPropertyValue` is an optional function that returns the value that will be assigned to data[property]
- interface Question {
- description: string;
- property: string;
- fn: MessageFilterCallback;
- errorMessage: string;
- toPropertyValue?: (p: string) => string | number;
- }
- // Command group for the command
- const commands = new discord.command.CommandGroup({
- defaultPrefix: '..'
- });
- const handler = new Handler();
- // Regular expression for checking if input is a "color code" (e.g. #ff0000, #fff, ...)
- const COLOR_REGEX = new RegExp('^\\d+|#([A-F\\d]{3}|[A-F\\d]{6})$', 'i');
- function isColorCode(str: string) {
- return COLOR_REGEX.test(str);
- }
- // Turns a "color code" into a number ("#ff0000" -> 16711680)
- function formatColor(str: string) {
- return str.startsWith('#') ? parseInt(str.substr(1), 16) : Number(str);
- }
- // This array includes all "questions"
- // See comments above `Question` interface to see what each field is for
- const questions: ReadonlyArray<Question> = [
- // Question 1: embed title
- // `fn` makes sure that the title won't exceed 256 characters
- {
- description: 'Embed title (max 256 characters)',
- property: 'title',
- fn: (handler, msg) => msg.content.length < 256,
- errorMessage: 'Embed title must not be longer than 256 characters'
- },
- // Question 2: embed description
- // `fn` makes sure that the description won't exceed 1024 characters
- {
- description: 'Embed description (max 1024 characters)',
- property: 'description',
- fn: (handler, msg) => msg.content.length < 1024,
- errorMessage: 'Embed description must not be longer than 1024 character'
- },
- // Question 3: embed color
- // `fn` makes sure that the color is a valid color code:
- // #fff, #ffffff, 16777215
- {
- description: 'Embed color',
- property: 'color',
- fn: (handler, msg) => isColorCode(msg.content),
- toPropertyValue: formatColor,
- errorMessage:
- "That doesn't look like a valid color code. Examples: #ff0000, #fff, #ffff00, 16777215"
- }
- ];
- commands.raw('embed', async (message) => {
- // `question` will be the index used to get the current question
- let question = 0;
- // `data` is the embed data that is sent after the user has answered all questions
- // Using a null prototype object to keep it simple (won't inherit Object)
- const data = Object.create(null);
- // Initial message
- await message.reply(questions[question].description);
- await handler.createMessageHandler({
- message,
- async filter(handler, message) {
- const currentQuestion = questions[question];
- // Forward all parameters to the current filter function
- const result = await currentQuestion.fn(handler, message);
- // If the filter function returned false, respond with an error
- if (!result) {
- await message.reply(currentQuestion.errorMessage);
- return false;
- }
- // If everything is good, return true
- return true;
- },
- async onMatch(handler, msg) {
- // `onMatch` is called if the filter function returned true, which means that we can be sure that the given message is valid
- const currentQuestion = questions[question];
- // Assigns the formatted value to `property`, e.g. `data['title'] = msg.content` for the first question
- // If `toPropertyValue` does not exist for this question, it defaults to the message content
- data[currentQuestion.property] =
- currentQuestion.toPropertyValue?.(msg.content) ?? msg.content;
- // Check if this was the last question
- if (question >= questions.length - 1) {
- // End handler by calling `done` on it
- handler.done();
- // Finally respond with embed data
- // `data` is an object that has all properties that were assigned previously (see line 103-104)
- message.reply({ embed: data });
- return;
- }
- // Increment index (question) and send next question
- question++;
- await message.reply(questions[question].description);
- }
- });
- });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement