laravel-discord-notifier maintained by arthurpar06
Laravel Discord Notifier
A strongly-typed way to send Discord messages through Laravel's notification system — over a webhook or a bot — without ever hand-writing the Discord API payload again.
use Arthurpar06\DiscordNotifier\Messages\DiscordMessage;
use Arthurpar06\DiscordNotifier\Embeds\DiscordEmbed;
use Arthurpar06\DiscordNotifier\Enums\DiscordColor;
DiscordMessage::make()
->content('Deployment finished')
->embed(
DiscordEmbed::make()
->title('Bonjour')
->description('Everything is green.')
->color(DiscordColor::Green)
->field('Environment', 'production', inline: true)
);
Your IDE and the type system remember the field names, the enums, and the limits — so you don't have to reopen the Discord docs every time.
Installation
composer require arthurpar06/laravel-discord-notifier
Publish the config file:
php artisan vendor:publish --tag="discord-notifier-config"
To deliver via a bot, set your bot token in .env:
DISCORD_BOT_TOKEN=your-bot-token
// config/discord-notifier.php
return [
'bot' => [
'token' => env('DISCORD_BOT_TOKEN'),
'api_base' => 'https://discord.com/api/v10',
],
];
There is no default route — every notification declares where it goes.
Building a message
DiscordMessage models the Create Message body. Everything is fluent and typed:
use Arthurpar06\DiscordNotifier\Messages\DiscordMessage;
use Arthurpar06\DiscordNotifier\Messages\AllowedMentions;
use Arthurpar06\DiscordNotifier\Embeds\DiscordEmbed;
use Arthurpar06\DiscordNotifier\Enums\AllowedMentionType;
use Arthurpar06\DiscordNotifier\Enums\MessageFlag;
DiscordMessage::make()
->content('Heads up <@123>')
->embeds([
DiscordEmbed::make()
->title('Report')
->footer('generated automatically')
->author('CI bot'),
])
->allowedMentions(AllowedMentions::make()->parse([AllowedMentionType::Users]))
->flags(MessageFlag::SuppressNotifications);
Only the fields you set are sent. Discord's limits (≤10 embeds, content ≤2000 chars, embed field caps, the IS_COMPONENTS_V2 mutual-exclusivity rule, …) are validated when the message is serialized, with an exception that names the offending field.
Sending notifications
In your notification, list discord in via() and return a DiscordMessage from toDiscord():
use Arthurpar06\DiscordNotifier\Messages\DiscordMessage;
use Illuminate\Notifications\Notification;
class DeploymentFinished extends Notification
{
public function via($notifiable): array
{
return ['discord'];
}
public function toDiscord($notifiable): DiscordMessage
{
return DiscordMessage::make()->content('Deployment finished ✅');
}
}
Route on demand
Pass a bot channel id (a guild channel or a user's DM channel) or an explicit route:
use Illuminate\Support\Facades\Notification;
use Arthurpar06\DiscordNotifier\Routing\DiscordRoute;
// bare channel id → delivered by the bot
Notification::route('discord', config('services.discord.admin_channel_id'))
->notify(new DeploymentFinished);
// explicit webhook
Notification::route('discord', DiscordRoute::webhook(config('services.discord.webhook')))
->notify(new DeploymentFinished);
Route from a model
Give the notifiable a routeNotificationForDiscord() returning its own channel id — e.g. a stored private DM channel:
class User extends Authenticatable
{
use Notifiable;
public function routeNotificationForDiscord(): string
{
return $this->discord_private_channel_id;
}
}
$user->notify(new DeploymentFinished);
How routing is resolved
The route value is resolved to a transport, unambiguously:
| Route value | Transport |
|---|---|
DiscordRoute::webhook($url) / DiscordRoute::channel($id) |
as declared |
a string starting with http |
webhook |
| a numeric snowflake string | bot channel (POST /channels/{id}/messages) |
A DM to a user and a message to a guild channel are the same bot call — store the channel id and send.
Testing
composer test
License
The MIT License (MIT). Please see License File for more information.