### Install Dependencies for Discord.js and Eris Examples Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/examples/README.md Installs the necessary npm packages for running the Discord.js and Eris examples. This includes discord.js, eris, and the discord-conversation-wizard library. ```bash # For Discord.js examples npm install discord.js # For Eris examples npm install eris # Install the wizard library npm install discord-conversation-wizard ``` -------------------------------- ### Run Registration Bot using ts-node Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/examples/README.md Executes the registration bot example using ts-node, which allows running TypeScript files directly without prior compilation. Assumes dependencies are installed and bot token is configured. ```bash npx ts-node examples/registration-bot.ts ``` -------------------------------- ### Compile and Run Registration Bot Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/examples/README.md Compiles the TypeScript registration bot example into JavaScript and then runs the compiled file. This is an alternative to using ts-node for execution. Assumes TypeScript compiler (tsc) is installed. ```bash tsc examples/registration-bot.ts node examples/registration-bot.js ``` -------------------------------- ### Install, Build, Lint, and Format Project Dependencies Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/CONTRIBUTING.md This snippet shows the npm commands to install project dependencies, build the project, run the linter to check code quality, and format the code according to project standards. These commands are essential for setting up the development environment. ```bash npm install npm run build npm run lint npm run format ``` -------------------------------- ### Survey Bot using Eris Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/examples/README.md A simple customer satisfaction survey bot using the Eris library. It demonstrates basic wizard setup, select menus, text input, confirmation buttons, event handling, and data storage. Requires Eris and discord-conversation-wizard. ```bash Commands: - !survey - Start survey ``` -------------------------------- ### Create and Manage Multi-Step Conversations with Wizard Class (TypeScript) Source: https://context7.com/jersuxsss/discord-conversation-wizard/llms.txt Demonstrates how to initialize and start a multi-step conversation wizard using the Wizard class and DiscordJSAdapter. It outlines setting up steps with validation, handling completion and cancellation events, and starting the wizard with user, channel, and guild IDs. Requires discord.js and the discord-conversation-wizard library. ```typescript import { Client, GatewayIntentBits } from 'discord.js'; import { Wizard, DiscordJSAdapter, StepType } from 'discord-conversation-wizard'; const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent] }); client.on('messageCreate', async (message) => { if (message.content === '!survey') { const adapter = new DiscordJSAdapter(client); const wizard = new Wizard(adapter, { steps: [ { id: 'name', type: StepType.TEXT, prompt: 'What is your name?', validate: (response) => { if (response.length < 2) return 'Name must be at least 2 characters'; return true; } }, { id: 'age', type: StepType.NUMBER, prompt: 'How old are you?', minValue: 13, maxValue: 120 } ], allowBack: true, allowCancel: true, timeout: 60 }); wizard.on('complete', (responses) => { message.channel.send(`Thanks ${responses.name}, age ${responses.age}!`); }); wizard.on('cancel', () => { message.channel.send('Survey cancelled.'); }); await wizard.start({ userId: message.author.id, channelId: message.channel.id, guildId: message.guild?.id }); } }); client.login('YOUR_BOT_TOKEN'); ``` -------------------------------- ### Minimal Discord Conversation Wizard Bot Template Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/examples/README.md A basic template for creating a Discord bot using discord-conversation-wizard with Discord.js. It sets up a client, handles message events, and initiates a simple text-based wizard step. Requires discord.js and discord-conversation-wizard. ```typescript import { Client, GatewayIntentBits } from 'discord.js'; import { Wizard, DiscordJSAdapter, StepType } from 'discord-conversation-wizard'; const client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent, ], }); client.on('messageCreate', async (message) => { if (message.content === '!start') { const adapter = new DiscordJSAdapter(client); const wizard = new Wizard(adapter, { steps: [ { id: 'step1', type: StepType.TEXT, prompt: 'Your question here', }, ], }); wizard.on('complete', (responses) => { message.reply(`Completed! Response: ${responses.step1}`); }); await wizard.start({ userId: message.author.id, channelId: message.channel.id, }); } }); client.login('YOUR_BOT_TOKEN'); ``` -------------------------------- ### Eris Bot Survey Wizard Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/README.md This example demonstrates creating a feedback survey wizard for an Eris bot. It utilizes the ErisAdapter to handle interactions, offering text and select menu steps. The wizard collects user feedback and their rating of the service. ```typescript import Eris from 'eris'; import { Wizard, ErisAdapter, StepType } from 'discord-conversation-wizard'; const bot = new Eris('YOUR_BOT_TOKEN'); bot.on('messageCreate', async (message) => { if (message.content === '!survey') { const adapter = new ErisAdapter(bot); const wizard = new Wizard(adapter, { steps: [ { id: 'feedback', type: StepType.TEXT, prompt: '💬 What do you think about our service?', maxLength: 500, }, { id: 'rating', type: StepType.SELECT_MENU, prompt: '⭐ Rate your experience:', options: [ { label: '⭐⭐⭐⭐⭐ Excellent', value: '5' }, { label: '⭐⭐⭐⭐ Good', value: '4' }, { label: '⭐⭐⭐ Average', value: '3' }, { label: '⭐⭐ Poor', value: '2' }, { label: '⭐ Terrible', value: '1' }, ], }, ], }); wizard.on('complete', (responses) => { bot.createMessage(message.channel.id, `Thank you for your feedback! Rating: ${responses.rating}/5`); }); await wizard.start({ userId: message.author.id, channelId: message.channel.id, }); } }); bot.connect(); ``` -------------------------------- ### Registration Bot using Discord.js Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/examples/README.md A comprehensive user registration wizard implemented with Discord.js. It supports various step types, validation, data transformation, conditional logic, multi-select, middleware, navigation controls, retry limits, and a profile viewing system. Requires Discord.js and discord-conversation-wizard. ```bash Commands: - !register - Start registration wizard - !profile - View your profile ``` -------------------------------- ### Implement Middleware Hooks in Discord Wizard Source: https://context7.com/jersuxsss/discord-conversation-wizard/llms.txt Middleware hooks allow custom logic execution before and after wizard steps, error handling, and managing completion or cancellation. This example demonstrates setting up `beforeStep`, `afterStep`, `onError`, `onComplete`, and `onCancel` handlers. ```typescript import { Wizard, WizardMiddleware } from 'discord-conversation-wizard'; const middleware: WizardMiddleware = { beforeStep: async (step, context) => { console.log(`Starting step: ${step.id}`); await logToDatabase('step_started', { stepId: step.id, userId: context.wizardContext.userId }); }, afterStep: async (step, response, context) => { console.log(`Completed step ${step.id} with response:`, response); await savePartialProgress(context.wizardContext.userId, context.responses); }, onError: async (error, step, context) => { console.error(`Error in step ${step.id}:`, error.message); await sendErrorToMonitoring({ error, step, userId: context.wizardContext.userId }); }, onComplete: async (responses, context) => { console.log('Wizard completed successfully'); await saveToDatabase(context.userId, responses); await sendConfirmationEmail(responses.email); }, onCancel: async (context) => { console.log(`User cancelled at step: ${context.stepId}`); await logCancellation(context.wizardContext.userId, context.stepId); } }; const wizard = new Wizard(adapter, { steps: [/* ... */], middleware: middleware }); // Simulated helper functions async function logToDatabase(event, data) { /* ... */ } async function savePartialProgress(userId, responses) { /* ... */ } async function sendErrorToMonitoring(errorData) { /* ... */ } async function saveToDatabase(userId, responses) { /* ... */ } async function sendConfirmationEmail(email) { /* ... */ } async function logCancellation(userId, stepId) { /* ... */ } await wizard.start({ userId: '123', channelId: '456' }); ``` -------------------------------- ### Pull Request Description Template Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/CONTRIBUTING.md A template for pull request descriptions, guiding contributors to provide essential information about their changes. It includes sections for a brief description, the type of change, testing methods, and a checklist to ensure adherence to project standards. ```markdown ## Description Brief description of what this PR does ## Type of Change - [ ] Bug fix - [ ] New feature - [ ] Breaking change - [ ] Documentation update ## Testing How did you test this change? ## Checklist - [ ] Code follows project style guidelines - [ ] Self-review completed - [ ] Comments added for complex code - [ ] Documentation updated - [ ] No new warnings generated - [ ] Works with discord.js - [ ] Works with Eris ``` -------------------------------- ### Pull Request Title Formats Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/CONTRIBUTING.md Examples of conventional commit formats for pull request titles. These formats help categorize changes (features, fixes, docs, refactors, tests) and provide a clear, concise summary of the PR's purpose. This aids in automated changelog generation and project management. ```markdown feat: Add multi-select support for buttons fix: Correct timeout handling in ErisAdapter docs: Update README with new examples refactor: Simplify validation logic test: Add tests for step navigation ``` -------------------------------- ### TypeScript Email Validation Example Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/CONTRIBUTING.md An example of a TypeScript function that validates an email address using a regular expression. It returns true if the email is valid, or an error message string if it's not. This demonstrates the project's preference for strong typing and clear function definitions. ```typescript /** * Validates an email address * @param email - The email to validate * @returns True if valid, error message if invalid */ export function validateEmail(email: string): boolean | string { const emailRegex = /^[^s@]+@[^s@]+\.[^s@]+$/; return emailRegex.test(email) || 'Invalid email address'; } ``` -------------------------------- ### Transform User Input for Email Validation in TypeScript Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/README.md Pre-process user input before validation. This example converts the input to lowercase and trims whitespace for consistent email formatting. ```typescript { id: 'email', type: StepType.TEXT, prompt: '📧 Enter your email address:', transform: (response) => response.toLowerCase().trim(), validate: (email) => { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email) || 'Please enter a valid email address'; }, } ``` -------------------------------- ### Validate File Attachments in TypeScript Wizard Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/README.md Define criteria for accepting file uploads, such as content type and file size. This example validates image files. ```typescript { id: 'avatar', type: StepType.ATTACHMENT, prompt: '📎 Upload your profile picture:', validate: (attachment) => { const validTypes = ['image/png', 'image/jpeg', 'image/gif']; if (!validTypes.includes(attachment.contentType)) { return 'Please upload a PNG, JPEG, or GIF image'; } if (attachment.size > 5 * 1024 * 1024) { return 'Image must be smaller than 5MB'; } return true; }, } ``` -------------------------------- ### Set Retry Limits for Validation Failures in TypeScript Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/README.md Configure the maximum number of attempts a user has to provide valid input before the wizard moves on or fails. This example limits input to 3 attempts. ```typescript { id: 'code', type: StepType.TEXT, prompt: 'Enter the verification code:', retry: 3, // Maximum 3 attempts validate: (code) => { return code === 'SECRET123' || 'Invalid verification code'; }, } ``` -------------------------------- ### Wizard Event System (TypeScript) Source: https://context7.com/jersuxsss/discord-conversation-wizard/llms.txt Monitors and responds to various state changes within the wizard lifecycle, including start, step changes, skips, completion, cancellation, errors, session saving/resuming, and maximum retries. Uses event listeners attached to the wizard instance. Requires the 'discord-conversation-wizard' library. ```typescript import { Wizard, StepType } from 'discord-conversation-wizard'; const wizard = new Wizard(adapter, { steps: [/* ... */] }); // Wizard lifecycle events wizard.on('start', (context) => { console.log(`Wizard started for user ${context.userId} in channel ${context.channelId}`); }); wizard.on('step', (step, index) => { console.log(`Now on step ${index + 1}: ${step.id}`); }); wizard.on('skip', (step, context) => { console.log(`Step ${step.id} was skipped by user ${context.wizardContext.userId}`); }); wizard.on('complete', (responses) => { console.log('Wizard completed successfully!'); console.log('All responses:', responses); }); wizard.on('cancel', (context) => { console.log(`Wizard cancelled at step ${context.stepId}`); console.log(`Partial responses:`, context.responses); }); wizard.on('error', (error, step, context) => { console.error(`Error occurred in step ${step.id}:`, error.message); console.error('Context:', context); }); wizard.on('sessionSaved', (session) => { console.log(`Session ${session.sessionId} saved at step ${session.currentStepIndex}`); console.log(`Last activity: ${new Date(session.lastActivityAt).toISOString()}`); }); wizard.on('resume', (session) => { console.log(`Resuming session ${session.sessionId} from step ${session.currentStepIndex}`); }); wizard.on('maxRetriesReached', (step, context) => { console.log(`Max retries reached for step ${step.id}`); console.log(`User ${context.wizardContext.userId} failed validation ${context.retryCount} times`); }); await wizard.start({ userId: '123', channelId: '456' }); ``` -------------------------------- ### WizardOptions Interface Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/README.md Defines the configuration options available when initializing a new `Wizard` instance. ```APIDOC ## `WizardOptions` Interface Configuration options for the wizard. ### Properties - `steps: WizardStep[]`: An array defining the sequence and configuration of each step in the wizard. - `title?: string`: An optional title for the wizard, displayed at the beginning. - `timeout?: number`: The maximum time in seconds allowed for a user's response to a step. - `middleware?: WizardMiddleware`: Allows for custom middleware functions to be applied to the wizard flow. - `allowBack?: boolean`: Enables or disables the ability for users to go back to previous steps (defaults to true). - `allowSkip?: boolean`: Enables or disables the ability for users to skip steps (defaults to true). - `allowCancel?: boolean`: Enables or disables the ability for users to cancel the wizard (defaults to true). - `sessionId?: string`: An optional session ID to resume a specific wizard session. - `persistSession?: boolean`: If true, enables session persistence (e.g., saving to a database). ``` -------------------------------- ### Configure Progress Indicators in TypeScript Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/README.md Shows how to enable and customize progress indicators for a wizard conversation. By setting `showProgress` to `true` and optionally providing a `progressFormat` string, users receive visual feedback on their current step within the total number of steps. The format string supports placeholders like {current}, {total}, and {percent}. ```typescript const wizard = new Wizard(adapter, { steps: [...], showProgress: true, progressFormat: '📊 Step {current}/{total}', // or '{percent}%' }); ``` -------------------------------- ### Configure Step Navigation Controls in TypeScript Wizard Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/README.md Enable built-in navigation commands like 'back', 'skip', and 'cancel'. Allows for programmatic navigation using methods like `goBack`, `skip`, `jumpToStep`, and `cancel`. ```typescript const wizard = new Wizard(adapter, { steps: [...], allowBack: true, // User can type "back" to go to previous step allowSkip: true, // User can type "skip" to skip optional steps allowCancel: true, // User can type "cancel" to abort the wizard }); // Programmatic navigation await wizard.goBack(); await wizard.skip(); await wizard.jumpToStep('stepId'); wizard.cancel(); ``` -------------------------------- ### Wizard Class Constructor in TypeScript Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/README.md Defines the constructor for the main `Wizard` class used to manage conversational flows. It takes an `adapter` for handling communication and `options` of type `WizardOptions` for configuration. This is the entry point for creating and initializing a new wizard instance. ```typescript new Wizard(adapter: AdapterInterface, options: WizardOptions) ``` -------------------------------- ### Bug Report Template Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/CONTRIBUTING.md A template for reporting bugs, ensuring all necessary details are provided for effective issue tracking and resolution. It includes fields for describing the bug, steps to reproduce it, expected behavior, environment details, and additional context. ```markdown **Describe the bug** A clear description of what the bug is. **To Reproduce** Steps to reproduce the behavior: 1. Initialize wizard with... 2. Call method... 3. See error **Expected behavior** What you expected to happen **Environment:** - Library version: - Discord library (discord.js/Eris): - Discord library version: - Node.js version: **Additional context** Add any other context about the problem here. ``` -------------------------------- ### Select Menu Step - Interactive Dropdown Choices in TypeScript Source: https://context7.com/jersuxsss/discord-conversation-wizard/llms.txt Shows how to implement select menu steps for dropdown choices, supporting single and multiple selections. This is ideal for users choosing roles or interests from a predefined list. ```typescript import { Wizard, StepType } from 'discord-conversation-wizard'; const wizard = new Wizard(adapter, { steps: [ { id: 'role', type: StepType.SELECT_MENU, prompt: 'Select your preferred role:', options: [ { label: 'Developer', value: 'dev', emoji: '💻', description: 'Write code' }, { label: 'Designer', value: 'design', emoji: '🎨', description: 'Create designs' }, { label: 'Manager', value: 'manager', emoji: '📊', description: 'Lead teams' } ] }, { id: 'interests', type: StepType.SELECT_MENU, prompt: 'Select your interests (multiple allowed):', allowMultiple: true, options: [ { label: 'Gaming', value: 'gaming', emoji: '🎮' }, { label: 'Programming', value: 'programming', emoji: '💻' }, { label: 'Music', value: 'music', emoji: '🎵' }, { label: 'Sports', value: 'sports', emoji: '⚽' } ], validate: (interests) => { if (interests.length === 0) return 'Select at least one interest'; if (interests.length > 3) return 'Select at most 3 interests'; return true; } } ] }); wizard.on('complete', (responses) => { console.log(`Role: ${responses.role}`); console.log(`Interests: ${responses.interests.join(', ')}`); }); await wizard.start({ userId: '123', channelId: '456' }); ``` -------------------------------- ### Wizard Navigation Controls (TypeScript) Source: https://context7.com/jersuxsss/discord-conversation-wizard/llms.txt Enables users to navigate through wizard steps using commands like 'back', 'skip', and 'jump'. Supports programmatic control for going back, skipping, jumping to specific steps, and cancelling the wizard. Requires the 'discord-conversation-wizard' library. ```typescript import { Wizard, StepType } from 'discord-conversation-wizard'; const wizard = new Wizard(adapter, { steps: [ { id: 'name', type: StepType.TEXT, prompt: 'What is your name?' }, { id: 'age', type: StepType.NUMBER, prompt: 'How old are you?', minValue: 13 }, { id: 'phone', type: StepType.TEXT, prompt: 'Phone number (optional - type "skip" to skip):', required: false, onSkip: (context) => { console.log(`User ${context.wizardContext.userId} skipped phone step`); } }, { id: 'email', type: StepType.TEXT, prompt: 'Email address?' } ], // Enable navigation controls allowBack: true, // Users can type "back" allowSkip: true, // Users can type "skip" allowCancel: true // Users can type "cancel" }); wizard.on('skip', (step, context) => { console.log(`Step ${step.id} was skipped`); }); // Programmatic navigation client.on('messageCreate', async (message) => { if (message.content === '!wizard') { await wizard.start({ userId: message.author.id, channelId: message.channel.id }); } // Admin controls if (message.content === '!wizard-back' && wizard.isActive()) { const success = await wizard.goBack(); if (success) message.reply('Went back one step'); } if (message.content === '!wizard-skip' && wizard.isActive()) { const success = await wizard.skip(); if (success) message.reply('Skipped current step'); } if (message.content === '!wizard-jump-email' && wizard.isActive()) { const success = await wizard.jumpToStep('email'); if (success) message.reply('Jumped to email step'); } if (message.content === '!wizard-cancel' && wizard.isActive()) { wizard.cancel(); } }); ``` -------------------------------- ### Configure Progress Indicators and Timeout Warnings for Wizards Source: https://context7.com/jersuxsss/discord-conversation-wizard/llms.txt This code snippet configures progress indicators and timeout warnings for a Discord conversation wizard. It enables showing the user's progress through the steps and provides customizable warning messages before a step times out. Dependencies: discord-conversation-wizard. ```typescript import { Wizard, StepType } from 'discord-conversation-wizard'; const wizard = new Wizard(adapter, { steps: [ { id: 'step1', type: StepType.TEXT, prompt: 'Question 1?' }, { id: 'step2', type: StepType.TEXT, prompt: 'Question 2?' }, { id: 'step3', type: StepType.TEXT, prompt: 'Question 3?' }, { id: 'step4', type: StepType.TEXT, prompt: 'Question 4?' }, { id: 'step5', type: StepType.TEXT, prompt: 'Question 5?' } ], // Progress indicator configuration showProgress: true, progressFormat: '📊 Progress: {current}/{total} ({percent}%)', // Timeout configuration timeout: 60, // 60 seconds per step timeoutWarning: true, // Warns 15 seconds before timeout timeoutWarningMessage: '⏰ Hurry! You have 15 seconds left to respond!', // Alternative: custom warning time // timeoutWarning: 20, // Warns 20 seconds before timeout allowBack: true, allowCancel: true }); wizard.on('step', (step, index) => { console.log(`User is on step ${index + 1} of ${wizard['steps'].length}`); }); await wizard.start({ userId: '123', channelId: '456' }); ``` -------------------------------- ### WizardOptions Interface in TypeScript Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/README.md Defines the structure for configuration options when initializing a `Wizard` instance. This interface includes properties for defining the conversation steps, optional titles, timeouts, middleware, navigation controls (back, skip, cancel), session management, and more. ```typescript interface WizardOptions { steps: WizardStep[]; title?: string; timeout?: number; middleware?: WizardMiddleware; allowBack?: boolean; allowSkip?: boolean; allowCancel?: boolean; sessionId?: string; persistSession?: boolean; } ``` -------------------------------- ### Collect Free-Form Text Responses with Text Input Step (TypeScript) Source: https://context7.com/jersuxsss/discord-conversation-wizard/llms.txt Illustrates configuring a text input step within the Wizard class for collecting user-provided text. It showcases options like setting minimum and maximum lengths, transforming input (e.g., trimming and lowercasing), applying custom validation with regex, and defining retry limits. This snippet assumes an existing adapter and wizard instance. ```typescript import { Wizard, DiscordJSAdapter, StepType } from 'discord-conversation-wizard'; const wizard = new Wizard(adapter, { steps: [ { id: 'username', type: StepType.TEXT, prompt: 'Enter your desired username:', minLength: 3, maxLength: 20, transform: (response) => response.trim().toLowerCase(), validate: (username) => { if (!/^[a-zA-Z0-9_]+$/.test(username)) { return 'Username can only contain letters, numbers, and underscores'; } return true; }, retry: 3 }, { id: 'bio', type: StepType.TEXT, prompt: 'Write a short bio (50-500 characters):', minLength: 50, maxLength: 500, validate: (bio) => { if (bio.length < 50) return `Bio too short (${bio.length}/50)`; if (bio.length > 500) return `Bio too long (${bio.length}/500)`; return true; } } ] }); await wizard.start({ userId: '123', channelId: '456' }); ``` -------------------------------- ### Discord.js Bot Registration Wizard Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/README.md This snippet shows how to create a registration wizard for a Discord.js bot. It uses the DiscordJSAdapter to interact with Discord, defining text, number, and select menu steps for collecting user information. The wizard supports going back and cancelling. ```typescript import { Client, GatewayIntentBits } from 'discord.js'; import { Wizard, DiscordJSAdapter, StepType } from 'discord-conversation-wizard'; const client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent, ], }); client.on('messageCreate', async (message) => { if (message.content === '!register') { const adapter = new DiscordJSAdapter(client); const wizard = new Wizard(adapter, { steps: [ { id: 'name', type: StepType.TEXT, prompt: '👋 What is your name?', validate: (response) => { if (response.length < 2) return 'Name must be at least 2 characters'; if (response.length > 32) return 'Name must be less than 32 characters'; return true; }, }, { id: 'age', type: StepType.NUMBER, prompt: '🎂 How old are you?', minValue: 13, maxValue: 120, }, { id: 'role', type: StepType.SELECT_MENU, prompt: '🎭 Select your preferred role:', options: [ { label: 'Developer', value: 'dev', emoji: '💻' }, { label: 'Designer', value: 'design', emoji: '🎨' }, { label: 'Manager', value: 'manager', emoji: '📊' }, ], }, ], allowBack: true, allowCancel: true, }); wizard.on('complete', (responses) => { message.channel.send( `✅ Registration complete!\n` + `**Name:** ${responses.name}\n` + `**Age:** ${responses.age}\n` + `**Role:** ${responses.role}` ); }); wizard.on('cancel', () => { message.channel.send('❌ Registration cancelled.'); }); await wizard.start({ userId: message.author.id, channelId: message.channel.id, guildId: message.guild?.id, }); } }); client.login('YOUR_BOT_TOKEN'); ``` -------------------------------- ### Validate File Uploads with Discord Attachment Steps (TypeScript) Source: https://context7.com/jersuxsss/discord-conversation-wizard/llms.txt Demonstrates how to use the ATTACHMENT step type to allow users to upload files. Includes validation for file content types and size limits. Requires 'discord-conversation-wizard' package. ```typescript import { Wizard, StepType } from 'discord-conversation-wizard'; const wizard = new Wizard(adapter, { steps: [ { id: 'avatar', type: StepType.ATTACHMENT, prompt: 'Upload your profile picture:', validate: (attachment) => { const validTypes = ['image/png', 'image/jpeg', 'image/gif']; if (!validTypes.includes(attachment.contentType)) { return 'Please upload a PNG, JPEG, or GIF image'; } const maxSize = 5 * 1024 * 1024; // 5MB if (attachment.size > maxSize) { return 'Image must be smaller than 5MB'; } return true; }, retry: 2 }, { id: 'document', type: StepType.ATTACHMENT, prompt: 'Upload your resume (PDF only):', validate: (attachment) => { if (attachment.contentType !== 'application/pdf') { return 'Please upload a PDF file'; } if (attachment.size > 10 * 1024 * 1024) { return 'PDF must be smaller than 10MB'; } return true; } } ] }); wizard.on('complete', (responses) => { console.log(`Avatar URL: ${responses.avatar.url}`); console.log(`Document URL: ${responses.document.url}`); }); await wizard.start({ userId: '123', channelId: '456' }); ``` -------------------------------- ### Confirmation Step - Yes/No Button Prompts in TypeScript Source: https://context7.com/jersuxsss/discord-conversation-wizard/llms.txt Illustrates the use of confirmation steps, which present users with 'Confirm'/'Cancel' buttons for binary decisions. This is suitable for actions requiring explicit user agreement, like accepting terms. ```typescript import { Wizard, StepType } from 'discord-conversation-wizard'; const wizard = new Wizard(adapter, { steps: [ { id: 'acceptTerms', type: StepType.CONFIRMATION, prompt: 'Do you accept the terms and conditions?', validate: (response) => { if (response === 'wizard_cancel_acceptTerms') { return 'You must accept the terms to continue'; } return true; } }, { id: 'subscribeNewsletter', type: StepType.CONFIRMATION, prompt: 'Would you like to subscribe to our newsletter?' } ] }); wizard.on('complete', (responses) => { const acceptedTerms = responses.acceptTerms === 'wizard_confirm_acceptTerms'; const subscribedNewsletter = responses.subscribeNewsletter === 'wizard_confirm_subscribeNewsletter'; console.log(`Terms accepted: ${acceptedTerms}, Newsletter: ${subscribedNewsletter}`); }); await wizard.start({ userId: '123', channelId: '456' }); ``` -------------------------------- ### Create Multi-Select Menu for User Interests in TypeScript Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/README.md Allow users to select multiple options from a predefined list. This is useful for gathering preferences or multiple choices. ```typescript { id: 'interests', type: StepType.SELECT_MENU, prompt: '🎯 Select your interests (you can choose multiple):', allowMultiple: true, options: [ { label: 'Gaming', value: 'gaming', emoji: '🎮' }, { label: 'Music', value: 'music', emoji: '🎵' }, { label: 'Sports', value: 'sports', emoji: '⚽' }, { label: 'Art', value: 'art', emoji: '🎨' }, { label: 'Technology', value: 'tech', emoji: '💻' }, ], } ``` -------------------------------- ### Progress Indicators Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/README.md Enhance user experience by displaying visual progress throughout the wizard conversation. ```APIDOC ## Progress Indicators Show visual progress throughout the wizard conversation to keep users informed. ### Configuration: - `showProgress: true` (boolean): Enables the display of progress indicators. - `progressFormat: '📊 Step {current}/{total}'` (string): Customizes the format of the progress indicator. Supports placeholders: - `{current}`: The current step number (1-indexed). - `{total}`: The total number of steps in the wizard. - `{percent}`: The progress percentage (0-100). **Default format:** `📊 Step {current}/{total}` ### Example Usage: ```typescript const wizard = new Wizard(adapter, { steps: [...], showProgress: true, progressFormat: '📊 Step {current}/{total}', // or '{percent}%' }); ``` ``` -------------------------------- ### Implement Dynamic Conversation Flows with Conditional Steps (TypeScript) Source: https://context7.com/jersuxsss/discord-conversation-wizard/llms.txt Shows how to use the 'condition' property on steps to dynamically show or hide them based on previous user responses. Supports various step types like CONFIRMATION, NUMBER, and TEXT. Requires 'discord-conversation-wizard'. ```typescript import { Wizard, StepType } from 'discord-conversation-wizard'; const wizard = new Wizard(adapter, { steps: [ { id: 'hasExperience', type: StepType.CONFIRMATION, prompt: 'Do you have previous work experience?' }, { id: 'yearsOfExperience', type: StepType.NUMBER, prompt: 'How many years of experience?', minValue: 0, maxValue: 50, condition: (responses) => responses.hasExperience === 'wizard_confirm_hasExperience' }, { id: 'previousCompany', type: StepType.TEXT, prompt: 'What was your previous company?', condition: (responses) => responses.hasExperience === 'wizard_confirm_hasExperience' }, { id: 'age', type: StepType.NUMBER, prompt: 'How old are you?', minValue: 18, maxValue: 100 }, { id: 'email', type: StepType.TEXT, prompt: 'Enter your email address:', condition: (responses) => responses.age >= 18, transform: (email) => email.toLowerCase().trim() } ] }); await wizard.start({ userId: '123', channelId: '456' }); ``` -------------------------------- ### Wizard Class Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/README.md The main `Wizard` class orchestrates the conversation flow, managing steps, user input, and state. ```APIDOC ## `Wizard` Class Main wizard class for managing conversation flow. ### Constructor ```typescript new Wizard(adapter: AdapterInterface, options: WizardOptions) ``` ### Methods - `start(context: WizardContext): Promise`: Initiates the wizard conversation. - `resume(sessionId: string): Promise`: Resumes a previously saved wizard session. - `cancel(): void`: Aborts the current wizard conversation. - `goBack(): Promise`: Navigates the user to the previous step in the wizard. - `skip(): Promise`: Allows the user to skip the current step if allowed. - `jumpToStep(stepId: string): Promise`: Directly navigates to a step identified by its `stepId`. - `getResponses(): Record`: Retrieves all the responses collected throughout the wizard. - `getCurrentStepIndex(): number`: Returns the index of the currently active step. - `isActive(): boolean`: Checks if the wizard is currently running or active. - `getSessionId(): string`: Retrieves the unique identifier for the current wizard session. ### Events - `start`: Emitted when the wizard conversation begins. - `step`: Emitted when a new step in the wizard is started. - `skip`: Emitted when a step is skipped by the user. - `complete`: Emitted when the wizard conversation finishes successfully. - `cancel`: Emitted when the wizard conversation is cancelled. - `error`: Emitted when an error occurs during the wizard's execution. - `sessionSaved`: Emitted after a wizard session has been successfully saved. - `resume`: Emitted when a wizard session is resumed. - `maxRetriesReached`: Emitted when the maximum number of retries for a step is reached. ``` -------------------------------- ### Built-in Validators Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/README.md The library provides a set of pre-built validators for common input patterns like emails, URLs, phone numbers, and custom regex. ```APIDOC ## Built-in Validators Use pre-built validators for common validation patterns within wizard steps. ### Available Validators: - `validators.email()`: Validates for a valid email address format. - `validators.url({ requireProtocol: false })`: Validates for a valid URL, with an option to require a protocol. - `validators.phone()`: Validates for international phone number formats. - `validators.regex(/^[a-zA-Z0-9_]{3,16}$/, { message: '...' })`: Validates against a custom regular expression pattern. - `validators.length({ min: 10, max: 500 })`: Validates that a string's length is within a specified range. - `validators.range({ min: 13, max: 120 })`: Validates that a number falls within a specified range. - `validators.combine([...])`: Combines multiple validators using AND logic. - `validators.oneOf([...])`: Validates that the input value is present in a provided list. ### Example Usage: ```typescript import { validators } from 'discord-conversation-wizard'; const wizard = new Wizard(adapter, { steps: [ { id: 'email', type: StepType.TEXT, prompt: '📧 Enter your email:', validate: validators.email(), }, { id: 'age', type: StepType.NUMBER, prompt: '🎂 Enter your age:', validate: validators.range({ min: 13, max: 120 }), }, { id: 'password', type: StepType.TEXT, prompt: '🔒 Create a password:', validate: validators.combine([ validators.length({ min: 8, max: 128 }), validators.regex(/[A-Z]/, { message: 'Must contain uppercase' }), ]), }, ], }); ``` ``` -------------------------------- ### Wizard with Conditional Steps Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/README.md This snippet illustrates how to implement conditional steps within a conversation wizard. A step is only shown if a specific condition, based on previous responses, is met. This allows for dynamic wizard flows tailored to user input. ```typescript const wizard = new Wizard(adapter, { steps: [ { id: 'hasExperience', type: StepType.CONFIRMATION, prompt: 'Do you have previous experience?', }, { id: 'yearsOfExperience', type: StepType.NUMBER, prompt: 'How many years of experience do you have?', minValue: 0, maxValue: 50, condition: (responses) => responses.hasExperience === 'wizard_confirm_hasExperience', }, ], }); ``` -------------------------------- ### Set Up Timeout Warnings in TypeScript Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/README.md Illustrates how to configure timeout warnings for wizard interactions. Users are alerted before the response timeout expires, preventing accidental session termination. The `timeoutWarning` option can be set to `true` for a default warning time or to a specific number of seconds before the timeout. A custom warning message can also be provided using `timeoutWarningMessage`. ```typescript const wizard = new Wizard(adapter, { steps: [...], timeout: 60, // seconds timeoutWarning: true, // warns 15 seconds before by default // OR timeoutWarning: 20, // warns 20 seconds before timeout timeoutWarningMessage: '⏰ Hurry! Time is running out!', }); ``` -------------------------------- ### Define WizardStep Interface in TypeScript Source: https://github.com/jersuxsss/discord-conversation-wizard/blob/main/README.md Defines the structure for a single step within a conversation wizard. It includes properties for step identification, user prompts, validation logic, data transformation, and various constraints like timeouts, minimum/maximum lengths, and conditional logic. ```typescript interface WizardStep { id: string; prompt: string; type: StepType; options?: StepOption[]; validate?: (response: any, context: WizardStepContext) => boolean | string | Promise; transform?: (response: any, context: WizardStepContext) => any | Promise; timeout?: number; minLength?: number; maxLength?: number; minValue?: number; maxValue?: number; required?: boolean; allowMultiple?: boolean; condition?: (responses: Record, context: WizardContext) => boolean | Promise; onSkip?: (context: WizardStepContext) => void | Promise; retry?: number; } ``` -------------------------------- ### Implement Session Persistence for Wizards Source: https://context7.com/jersuxsss/discord-conversation-wizard/llms.txt This snippet demonstrates how to implement session persistence for Discord conversation wizards. It includes a custom session store using a Map, saving, loading, and deleting wizard sessions. This allows for long-running workflows that can be resumed later. Dependencies: discord-conversation-wizard. ```typescript import { Wizard, SessionStore, WizardSession } from 'discord-conversation-wizard'; // Implement custom session store (could use Redis, MongoDB, etc.) class DatabaseSessionStore implements SessionStore { private db: Map = new Map(); async save(session: WizardSession): Promise { this.db.set(session.sessionId, session); console.log(`Session ${session.sessionId} saved`); } async load(sessionId: string): Promise { return this.db.get(sessionId) || null; } async delete(sessionId: string): Promise { this.db.delete(sessionId); console.log(`Session ${sessionId} deleted`); } } const sessionStore = new DatabaseSessionStore(); const wizard = new Wizard(adapter, { steps: [/* ... */], persistSession: true, sessionId: `user_${userId}_registration`, sessionStore: sessionStore }); wizard.on('sessionSaved', (session) => { console.log(`Session saved: ${session.sessionId} at step ${session.currentStepIndex}`); }); // Start a new wizard await wizard.start({ userId: '123', channelId: '456' }); // Later, resume the session const sessionId = `user_123_registration`; const resumed = await wizard.resume(sessionId); if (resumed) { console.log('Wizard resumed successfully'); } else { console.log('No session found'); } ``` -------------------------------- ### Integrate Discord Wizards with Eris Bot Source: https://context7.com/jersuxsss/discord-conversation-wizard/llms.txt This code shows how to integrate the discord-conversation-wizard with an Eris-based Discord bot. It uses the ErisAdapter to handle messages and initiate a feedback wizard when a specific command is received. Dependencies: discord-conversation-wizard, eris. ```typescript import Eris from 'eris'; import { Wizard, ErisAdapter, StepType } from 'discord-conversation-wizard'; const bot = new Eris('YOUR_BOT_TOKEN'); bot.on('messageCreate', async (message) => { if (message.author.bot) return; if (message.content === '!feedback') { const adapter = new ErisAdapter(bot); const wizard = new Wizard(adapter, { steps: [ { id: 'feedback', type: StepType.TEXT, prompt: 'What feedback do you have for us?', maxLength: 500 }, { id: 'rating', type: StepType.SELECT_MENU, prompt: 'Rate your experience:', options: [ { label: '⭐⭐⭐⭐⭐ Excellent', value: '5' }, { label: '⭐⭐⭐⭐ Good', value: '4' }, { label: '⭐⭐⭐ Average', value: '3' }, { label: '⭐⭐ Poor', value: '2' }, { label: '⭐ Terrible', value: '1' } ] }, { id: 'recommend', type: StepType.CONFIRMATION, prompt: 'Would you recommend us to others?' } ], allowBack: true, timeout: 120 }); wizard.on('complete', (responses) => { bot.createMessage(message.channel.id, `Thank you for your feedback! Rating: ${responses.rating}/5`); }); wizard.on('cancel', () => { bot.createMessage(message.channel.id, 'Feedback cancelled.'); }); await wizard.start({ userId: message.author.id, channelId: message.channel.id }); } }); bot.on('ready', () => { console.log(`Bot ready as ${bot.user.username}`); }); bot.connect(); ```