Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Discord Notifier Laravel Package

symfony/discord-notifier

Symfony Notifier bridge for Discord. Configure via DISCORD_DSN for webhooks or a bot token, then send ChatMessage notifications. Supports rich embeds and options (username, title, fields, thumbnails, footers) to build interactive Discord messages.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package via Composer:
    composer require symfony/discord-notifier
    
  2. Configure the DSN in your .env file:
    DISCORD_DSN=discord://WEBHOOK_TOKEN@default?webhook_id=WEBHOOK_ID
    
    For a bot token:
    DISCORD_DSN=discord+bot://BOT_TOKEN@default
    
  3. Register the transport in your Laravel service provider (e.g., AppServiceProvider):
    use Symfony\Component\Notifier\Notifier;
    use Symfony\Component\Notifier\Bridge\Discord\DiscordTransportFactory;
    
    public function register()
    {
        $this->app->singleton(Notifier::class, function ($app) {
            return new Notifier([
                new DiscordTransportFactory(),
            ]);
        });
    }
    
  4. Send your first message:
    use Symfony\Component\Notifier\Message\ChatMessage;
    use Symfony\Component\Notifier\NotifierInterface;
    
    $notifier = app(NotifierInterface::class);
    $message = new ChatMessage('Hello from Laravel!');
    $notifier->send($message);
    

First Use Case: Deployment Alerts

Send a rich embed notification when a deployment completes:

$message = new ChatMessage('Deployment completed!');
$message->options((new DiscordOptions())
    ->addEmbed((new DiscordEmbed())
        ->title('Deployment Alert')
        ->description('New release deployed to production')
        ->color('green')
        ->addField((new DiscordFieldEmbedObject())
            ->name('Version')
            ->value('v1.2.3')
            ->inline(true)
        )
        ->addField((new DiscordFieldEmbedObject())
            ->name('Status')
            ->value('✅ Success')
            ->inline(true)
        )
        ->footer((new DiscordFooterEmbedObject())
            ->text('Deployed by CI/CD')
        )
    )
);
$notifier->send($message);

Implementation Patterns

Core Workflow: Building and Sending Messages

  1. Instantiate a ChatMessage with your content.
  2. Attach DiscordOptions to customize the message (e.g., embeds, username).
  3. Send via Notifier (Symfony’s unified notification system).

Example: Error Logging to Discord

use Symfony\Component\Notifier\Bridge\Discord\Embeds\DiscordCodeBlockEmbedObject;

try {
    // Risky operation
} catch (\Exception $e) {
    $message = new ChatMessage('Error in `UserService::create()`');
    $message->options((new DiscordOptions())
        ->username('Error Monitor')
        ->addEmbed((new DiscordEmbed())
            ->title('Critical Error')
            ->description($e->getMessage())
            ->color('red')
            ->addField((new DiscordFieldEmbedObject())
                ->name('File')
                ->value('app/Services/UserService.php')
            )
            ->addField((new DiscordFieldEmbedObject())
                ->name('Line')
                ->value('42')
            )
            ->addField((new DiscordFieldEmbedObject())
                ->name('Trace')
                ->value((new DiscordCodeBlockEmbedObject())
                    ->content($e->getTraceAsString())
                    ->language('php')
                )
            )
        )
    );
    $notifier->send($message);
}

Integration with Laravel

Option 1: Direct Symfony Notifier Usage

Leverage Laravel’s service container to resolve NotifierInterface:

use Symfony\Component\Notifier\NotifierInterface;

class DeploymentService {
    public function __construct(private NotifierInterface $notifier) {}

    public function deploy() {
        // ... deployment logic ...
        $this->notifier->send($this->buildDeploymentMessage());
    }
}

Option 2: Laravel Notification Channels Bridge

For Laravel’s Notification facade, use spatie/laravel-notification-channels-discord as a wrapper:

use App\Notifications\DeploymentNotification;
use Illuminate\Notifications\Notification;

class DeploymentNotification extends Notification {
    public function via($notifiable)
    {
        return ['discord'];
    }

    public function toDiscord($notifiable)
    {
        return (new ChatMessage('Deployment Alert'))
            ->options((new DiscordOptions())
                ->addEmbed($this->buildEmbed())
            );
    }
}

Dynamic Content and Templates

Reuse embed configurations with helper methods:

class DiscordEmbedHelper {
    public static function errorEmbed(string $title, string $message, \Exception $e): DiscordEmbed
    {
        return (new DiscordEmbed())
            ->title($title)
            ->description($message)
            ->color('red')
            ->addField((new DiscordFieldEmbedObject())
                ->name('Exception')
                ->value(get_class($e))
            )
            ->addField((new DiscordFieldEmbedObject())
                ->name('Trace')
                ->value((new DiscordCodeBlockEmbedObject())
                    ->content($e->getTraceAsString())
                    ->language('php')
                )
            );
    }
}

Batch Notifications

Send multiple messages in a loop (e.g., for bulk alerts):

$users = User::where('last_login_at', '<', now()->subDays(30))->get();
foreach ($users as $user) {
    $message = new ChatMessage("User {$user->name} inactive for 30+ days");
    $message->options((new DiscordOptions())
        ->addEmbed((new DiscordEmbed())
            ->title('Inactive User Alert')
            ->description("User hasn’t logged in since {$user->last_login_at->format('Y-m-d')}")
            ->color('yellow')
            ->addField((new DiscordFieldEmbedObject())
                ->name('Email')
                ->value($user->email)
            )
        )
    );
    $notifier->send($message);
}

Gotchas and Tips

Configuration Pitfalls

  1. DSN Format:

    • Webhook: discord://TOKEN@default?webhook_id=ID
      • TOKEN is the webhook URL token (not the full URL).
      • webhook_id is optional if the DSN is discord://TOKEN@default (uses the token as ID).
    • Bot Token: discord+bot://BOT_TOKEN@default
      • Requires a Discord bot account with permissions to send messages.
  2. Environment Variables:

    • Store tokens in .env never in code or version control.
    • Use Laravel’s config('services.discord') for structured access:
      DISCORD_WEBHOOK_TOKEN=your_token_here
      DISCORD_WEBHOOK_ID=your_webhook_id
      
      config(['services.discord' => [
          'token' => env('DISCORD_WEBHOOK_TOKEN'),
          'id'    => env('DISCORD_WEBHOOK_ID'),
      ]]);
      

Debugging

  1. Failed Messages:

    • Symfony Notifier throws TransportException on failures. Catch and log:
      try {
          $notifier->send($message);
      } catch (\Symfony\Component\Notifier\Exception\TransportException $e) {
          Log::error('Discord notification failed', ['error' => $e->getMessage()]);
      }
      
    • Common causes:
      • Invalid DSN (check token/ID).
      • Rate limits (Discord throttles webhooks; implement retries).
      • Missing permissions (bot/webhook lacks Send Messages scope).
  2. Embed Validation:

    • Discord enforces limits:
      • Title: 256 chars.
      • Description: 2048 chars.
      • Fields: Max 25, each 1024 chars (name + value).
      • Footer: 2048 chars.
    • Use DiscordOptions::validate() to catch issues early:
      $options = (new DiscordOptions())->addEmbed($embed);
      if (!$options->validate()) {
          throw new \InvalidArgumentException('Invalid Discord embed');
      }
      

Performance Tips

  1. Avoid Large Attachments:

    • Discord embeds support images/videos, but large media may fail or slow down messages.
    • Use direct links to hosted assets (e.g., S3) instead of base64-encoded data.
  2. Batch Processing:

    • For high-volume alerts (e.g., logs), batch messages to avoid rate limits:
      $batch = [];
      foreach ($logs as $log) {
          $batch[] = new ChatMessage($log->message)
              ->options($this->buildLogEmbed($log));
      }
      foreach ($batch as $message) {
          $notifier->send($message);
          sleep(1); // Throttle to avoid rate limits
      }
      

Extension Points

  1. Custom Transports:
    • Extend DiscordTransport to add features like message editing:
      class CustomDiscordTransport extends DiscordTransport {
          public function editMessage(string $messageId, ChatMessage $message): void {
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor
spatie/laravel-javascript-views