revolution / discord-manager
Discord Manager
Fund package maintenance!
invokable
Requires
- php: ^8.2
- discord/interactions: ^2.2
- guzzlehttp/guzzle: ^7.5
- illuminate/support: ^11.0||^12.0
- simplito/elliptic-php: ^1.0
Requires (Dev)
- laravel/pint: ^1.22
- orchestra/testbench: ^9.0||^10.0
- dev-main
- 5.2.1
- 5.2.0
- 5.1.1
- 5.1.0
- 5.0.1
- 5.0.0
- 4.x-dev
- 4.3.0
- 4.2.0
- 4.1.4
- 4.1.3
- 4.1.2
- 4.1.1
- 4.1.0
- 4.0.0
- 3.x-dev
- 3.0.0
- 2.x-dev
- 2.2.1
- 2.2.0
- 2.1.0
- 2.0.1
- 2.0.0
- 1.x-dev
- 1.6.0
- 1.5.1
- 1.5.0
- 1.4.2
- 1.4.1
- 1.4.0
- 1.3.1
- 1.3.0
- 1.2.1
- 1.2.0
- 1.1.5
- 1.1.4
- 1.1.3
- 1.1.2
- 1.1.1
- 1.1.0
- 1.0.9
- 1.0.8
- 1.0.7
- 1.0.6
- 1.0.5
- 1.0.4
- 1.0.3
- 1.0.2
- 1.0.1
- 1.0.0
- dev-copilot/fix-f1db23d6-ef9d-437f-89a7-a8eec7c4d81f
- dev-devin/1749528062-enhance-readme-documentation
- dev-master
This package is auto-updated.
Last update: 2025-06-12 03:35:09 UTC
README
Note As of v5, only the Interactions command is provided, which is webhook based and therefore easy to use with Laravel. All features using WebSockets have been removed.
Overview
Discord Manager is a Laravel package that provides seamless integration with Discord's Interactions API using webhook-based architecture. This package allows you to create and manage Discord slash commands, handle user interactions, and respond to Discord events directly from your Laravel application.
Key Features
- Webhook-based Architecture: Secure and efficient handling of Discord interactions through webhooks
- Slash Commands Support: Create and register both guild-specific and global Discord slash commands
- Laravel Integration: Native Laravel service provider with configuration publishing and Artisan commands
- Automatic Command Discovery: Automatically loads and registers interaction commands from your application
- Flexible Response System: Support for immediate responses, deferred responses, and followup messages
- Component Support: Built-in support for Discord UI components like buttons, select menus, and modals
- Event-driven: Integrates with Laravel's event system for handling Discord interactions
How It Works
The package operates by receiving webhook requests from Discord when users interact with your bot's commands. These requests are validated, processed through middleware, and dispatched to your custom command handlers. The workflow ensures secure communication with Discord while providing a familiar Laravel development experience.
See also
Requirements
- PHP >= 8.2
- Laravel >= 11.0
Installation
Step 1: Install the Package
composer require revolution/discord-manager
Step 2: Discord Application Setup
Before configuring the package, you need to create a Discord application and bot:
- Go to the Discord Developer Portal
- Click "New Application" and give it a name
- Navigate to the "Bot" section and click "Add Bot"
- Copy the bot token for
DISCORD_BOT_TOKEN
- Go to "General Information" and copy the Application ID for
DISCORD_BOT
- Copy the Public Key for
DISCORD_PUBLIC_KEY
- For guild-specific commands, copy your Discord server's Guild ID for
DISCORD_GUILD
Step 3: Environment Configuration
Add the following variables to your .env
file:
# Bot token from Discord Developer Portal > Bot section DISCORD_BOT_TOKEN=your_bot_token_here # Application ID from Discord Developer Portal > General Information DISCORD_BOT=your_application_id_here # Public Key from Discord Developer Portal > General Information DISCORD_PUBLIC_KEY=your_public_key_here # Guild ID (Server ID) for guild-specific commands (optional) DISCORD_GUILD=your_guild_id_here # Optional: Discord API version (defaults to 10) DISCORD_API_VERSION=10
Step 4: Publish Configuration
php artisan vendor:publish --tag=discord-interactions-config
This creates config/discord_interactions.php
where you can define your commands and customize settings.
Uninstall
composer remove revolution/discord-manager
- Delete
config/discord_interactions.php
- Delete
app/Discord/
and other files. - Delete
DISCORD_*
in.env
Configuration
Command Configuration
Edit config/discord_interactions.php
to define your Discord commands:
return [ // Guild-specific commands (only available in specified servers) 'guild' => [ [ 'name' => 'hello', 'description' => 'Say hello to a user', 'type' => CommandType::CHAT_INPUT, 'guild_id' => env('DISCORD_GUILD'), 'options' => [ [ 'name' => 'user', 'description' => 'User to greet', 'type' => CommandOptionType::USER, 'required' => true, ], ], ], ], // Global commands (available in all servers) 'global' => [ [ 'name' => 'ping', 'description' => 'Check if the bot is responding', 'type' => CommandType::CHAT_INPUT, ], ], // Other configuration options 'commands' => app_path('Discord/Interactions'), // Path to command classes 'token' => env('DISCORD_BOT_TOKEN'), 'bot' => env('DISCORD_BOT'), 'public_key' => env('DISCORD_PUBLIC_KEY'), 'path' => 'discord/webhook', // Webhook endpoint path 'route' => 'discord.webhook', // Route name 'middleware' => 'throttle', // Additional middleware ];
Discord Developer Portal Setup
Set the Interactions Endpoint URL in your Discord application:
- Go to Discord Developer Portal
- Select your application
- Navigate to "General Information"
- Set the Interactions Endpoint URL to:
https://yourdomain.com/discord/webhook
Usage
Quick Start
Here's a complete example to get you started:
1. Create a Command
php artisan discord:make:interaction HelloCommand
This creates app/Discord/Interactions/HelloCommand.php
:
<?php namespace App\Discord\Interactions; use Illuminate\Http\Request; use Revolution\DiscordManager\Concerns\WithInteraction; class HelloCommand { use WithInteraction; public string $command = 'hello'; public function __invoke(Request $request): void { $user = $request->json('member.user.id', $request->json('user.id')); $data = [ 'content' => "<@$user> Hello from Laravel!", 'allowed_mentions' => ['parse' => ['users']], ]; $response = $this->followup(token: $request->json('token'), data: $data); } }
2. Add Command to Configuration
The command you created can be used as either a guild-specific or global command. You need to add it to your config/discord_interactions.php
file to specify where it should be registered.
Edit config/discord_interactions.php
and add your command to either the guild
or global
array:
return [ // For guild-specific commands (only available in specified servers) 'guild' => [ [ 'name' => 'hello', 'description' => 'Say hello from Laravel', 'type' => CommandType::CHAT_INPUT, 'guild_id' => env('DISCORD_GUILD'), ], // Add more guild commands here... ], // For global commands (available in all servers where your bot is installed) 'global' => [ [ 'name' => 'hello', 'description' => 'Say hello from Laravel', 'type' => CommandType::CHAT_INPUT, ], // Add more global commands here... ], // ... rest of configuration ];
Choose guild
for testing and development, or global
for production deployment to all servers.
3. Register Commands
php artisan discord:interactions:register
4. Create Event Listener
The Discord Manager package uses Laravel's event system to handle incoming webhook requests. When Discord sends a webhook request to your application, the package dispatches an InteractionsWebhook
event. You need to create a listener to handle this event and process the Discord interaction.
php artisan make:listener InteractionsListener
Update app/Listeners/InteractionsListener.php
:
<?php namespace App\Listeners; use Revolution\DiscordManager\Events\InteractionsWebhook; use Revolution\DiscordManager\Facades\DiscordManager; class InteractionsListener { public function handle(InteractionsWebhook $event): void { DiscordManager::interaction($event->request); } }
This listener receives the webhook request from Discord and passes it to the DiscordManager, which then routes it to the appropriate command class based on the interaction data.
Advanced Usage
Commands with Options
<?php namespace App\Discord\Interactions; use Illuminate\Http\Request; use Revolution\DiscordManager\Concerns\WithInteraction; class GreetCommand { use WithInteraction; public string $command = 'greet'; public function __invoke(Request $request): void { $targetUser = $request->json('data.options.0.value'); $message = $request->json('data.options.1.value', 'Hello!'); $user = $request->json('member.user.id', $request->json('user.id')); $data = [ 'content' => "<@$targetUser> $message (from <@$user>)", 'allowed_mentions' => ['parse' => ['users']], ]; $this->followup(token: $request->json('token'), data: $data); } }
Interactive Components
<?php namespace App\Discord\Interactions; use Illuminate\Http\Request; use Revolution\DiscordManager\Concerns\WithInteraction; use Revolution\DiscordManager\Support\ComponentType; use Revolution\DiscordManager\Support\ButtonStyle; class ButtonCommand { use WithInteraction; public string $command = 'button-demo'; public function __invoke(Request $request): void { $data = [ 'content' => 'Click a button below:', 'components' => [ [ 'type' => ComponentType::ACTION_ROW->value, 'components' => [ [ 'type' => ComponentType::BUTTON->value, 'style' => ButtonStyle::PRIMARY->value, 'label' => 'Primary', 'custom_id' => 'primary_button', ], [ 'type' => ComponentType::BUTTON->value, 'style' => ButtonStyle::SUCCESS->value, 'label' => 'Success', 'custom_id' => 'success_button', ], ], ], ], ]; $this->followup(token: $request->json('token'), data: $data); } }
Handling Button Interactions
<?php namespace App\Discord\Interactions; use Illuminate\Http\Request; use Revolution\DiscordManager\Concerns\WithInteraction; class PrimaryButtonCommand { use WithInteraction; public string $command = 'primary_button'; public function __invoke(Request $request): void { $user = $request->json('member.user.id', $request->json('user.id')); $data = [ 'content' => "<@$user> You clicked the primary button!", 'allowed_mentions' => ['parse' => ['users']], ]; $this->followup(token: $request->json('token'), data: $data); } }
Command Registration
After creating or modifying commands, always register them with Discord:
# Register all commands defined in config
php artisan discord:interactions:register
Troubleshooting
Common Issues
- Webhook URL not accessible: Ensure your application is publicly accessible and the webhook URL is correct
- Invalid signature: Verify your
DISCORD_PUBLIC_KEY
is correct - Commands not appearing: Check that commands are properly registered and the bot has necessary permissions
- Permission errors: Ensure your bot has the necessary permissions in the Discord server
Testing Webhook Locally
For local development, we recommend using expose to expose your local server. Expose is a popular choice among Laravel/PHP developers for creating secure tunnels to localhost.
First, install expose globally:
composer global require exposedev/expose
Next, create an expose account and set your authentication token:
expose token YOUR_TOKEN
For more information on authentication, see the expose documentation.
To use expose, start your Laravel local server first, then run the expose share
command:
php artisan serve
expose share http://127.0.0.1:8000
If you are not using php artisan serve
, please adjust it to suit your environment.
Use the generated expose URL as your webhook endpoint in Discord Developer Portal.
How It Works
The Discord Manager package follows a secure webhook-based workflow to handle Discord interactions:
Request Flow
- Discord Webhook: Discord sends a POST request to
https://yourdomain.com/discord/webhook
when users interact with your bot - Signature Validation: ValidateSignature middleware verifies the request authenticity using your public key
- Controller Processing: InteractionsWebhookController receives and processes the interaction
- Deferred Response: DeferredResponse immediately acknowledges Discord to prevent timeout
- Event Dispatch: DispatchInteractionsEvent terminable middleware dispatches the interaction event
- Event Handling: InteractionsWebhook event is fired and handled by your listener
- Command Execution: Your
InteractionsListener
callsDiscordManager::interaction()
which invokes the appropriate command class - Response Delivery: Commands use the
followup()
method to send responses back to Discord
Security
- All requests are cryptographically verified using Ed25519 signatures
- Invalid signatures are automatically rejected
- Webhook endpoints are protected against unauthorized access
Performance
- Deferred responses prevent Discord timeouts (3-second limit)
- Terminable middleware allows background processing
- Automatic command discovery and caching
Examples and Resources
Sample Application
For a complete working example, see: https://github.com/kawax/discord-interactions
Command Types
The package supports various Discord command and component types:
- Slash Commands: Traditional
/command
interactions - User Commands: Right-click context menu on users
- Message Commands: Right-click context menu on messages
- Button Components: Interactive buttons in messages
- Select Menus: Dropdown selection components
- Modal Forms: Pop-up forms for user input
Response Types
- Immediate Response: Direct reply to the interaction
- Deferred Response: Acknowledge first, respond later (recommended)
- Followup Messages: Additional messages after the initial response
Best Practices
- Use Deferred Responses: Always use
followup()
for responses that take time to process - Handle Errors Gracefully: Implement proper error handling in your command classes
- Validate Input: Always validate user input from command options
- Use Guild Commands for Development: Guild commands are scoped to specific servers for testing
- Implement Logging: Use Laravel's logging to track interactions and debug issues
LICENSE
MIT