DEV Community

Michael Olukoya
Michael Olukoya

Posted on • Originally published at mikey.dev

Sending Laravel Notifications To Discord Channels & Users

Introduction

Discord is a messaging platform that allows you to send messages to your friends, family and communities, it is a great alternative to the likes of slack with a less "enterprise" and more "community" focus.

In this tutorial, we will learn how to send notifications to Discord channels and Discord users using Laravel.

If you want to see some code, I have packaged the whole tutorial in this github repo:

GitHub logo MikeyBeLike / laravel-discord-notifications

Send Laravel notifications to Discord tutorial

There are many uses cases for this, but the most common use case is to send notifications to a Discord channel or a user when something independent of a discord interaction occur. A few examples:

  • a payment on your website/app occurs and you want to thank and notify the user who made the payment
  • a user has a new message on your website/app and you want to notify them via discord
  • a community related event occurs and you want to notify the users within your channel

Prerequisites

  • A Discord server + channel
  • A Discord bot account
  • Some experience with Laravel
  • A modern Laravel application setup (will be using Laravel 8 in the examples below)

Create a discord channel

First we should start by creating a new discord channel. In your existing discord server you can create a new channel, this should be a text channel.

You can do this by clicking the server name in the top left and then clicking the "Create a new channel" button in the sidebar.

Create Discord Channel

Click the "Text Channel" radio button, give your channel a name, (you can keep it public or private up to you) and then click the "Create Channel" button.
Create Discord Channel Step 2

Create your discord application/bot

Now that you have your discord channel created, you need to create a bot account.
Head over to the Discord Developer Portal and click the "New Application" button in the top right corner.

Enter the name of your application and click the "Create" button.

Then navigate to the "Bot" link in the left hand side navigation and click the "Bot" button.

Follow the steps listed to create your bot, feel free to update the bot name too.

Create Discord Bot

Congrats you've now created your discord bot! πŸŽ‰

Invite bot to your channel

Next thing to do is invite your bot to your server!

I won't go into too much detail on how to invite your bot to your channel as there are many guides online on how to do this, here's one that I used:

Invite your bot to your server

Once done you should now see the bot in your server and it should look something like this.

Bot in server

Awesome we have no created our discord bot and it now "lives" in our server!

Your Laravel application

This tutorial expects you have some experience of setting up and working with a Laravel application. If you don't yet have experience learning Laravel, their docs are a great way to start!

The examples below are using Laravel 8.

Create your Laravel controller

php artisan make:controller DiscordNotificationDemo
Enter fullscreen mode Exit fullscreen mode

This creates a file with some minimal boilerplate controller code.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class DiscordNotificationDemo extends Controller
{
    //
}

Enter fullscreen mode Exit fullscreen mode

Typically your controller would be called from an external web service/event/etc which would eventually trigger the notification to our discord channel, but for the sake of demo purposes this example would be triggered directly from the url.

Create a route for your controller.

Open up your routes/web.php file and add the following line:

use App\Http\Controllers\DiscordNotificationDemo;

// ...

Route::get('discord-notification', [DiscordNotificationDemo::class, 'index']);
Enter fullscreen mode Exit fullscreen mode

Setting up notifications

Laravel has a fluent API for working with sending notifications across a variety of delivery channels. You can find more information on the notifications docs.

By default Laravel comes with channels for sending notifications via email, server-client broadcasts, SMS & Slack. But also with the ability to send notifications to other third party services such as Discord and more.

Since Discord is not a first party notification channel, we need to use a third party library to send notifications via Discord. Luckily for us there is a github account that hosts a few different third party Laravel notification channels. We'll be using this open source package: https://github.com/laravel-notification-channels/discord.

Setup the package

We can now install the package using composer.

composer require laravel-notification-channels/discord
Enter fullscreen mode Exit fullscreen mode

Open your config/app.php file and load the service provider:

// config/app.php
'providers' => [
    // ...
    /*
     * Package Service Providers...
     */
    NotificationChannels\Discord\DiscordServiceProvider::class,
    // ...
],
Enter fullscreen mode Exit fullscreen mode

Include your Discord bot API token

  • Head back to the Discord Developer Portal and click the "Bot" link in the left hand side navigation.
  • Copy the token value under the "Build-A-Bot" section. Copy bot token
  • Open your .env file and add this line - replacing YOUR_TOKEN_VALUE with the copied token value.
DISCORD_API_TOKEN=YOUR_TOKEN_VALUE
Enter fullscreen mode Exit fullscreen mode
  • Open your config/services.php file and add the following to the existing array:
// ...
'discord' => [
    'token' => env('DISCORD_API_TOKEN'),
],
Enter fullscreen mode Exit fullscreen mode
  • The bot already exists in your server but Discord requires us to connect via websocket connection and identify atleast once before we can send requests to the API over HTTP. Running the following command will connect the bot to the server and identify it:
php artisan discord:setup
Enter fullscreen mode Exit fullscreen mode

Hopefully that should have all run well and we can now proceed to setting up our Laravel notifications.

Setup the notification channel

In this example we'll be creating a notification to simply alert a channel that a user has made a donation towards our site. Laravel allows us to create a notification class by simply running the following command:

php artisan make:notification NewDonation
Enter fullscreen mode Exit fullscreen mode

This gives us a new notification class that we can use to send notifications to our discord channel.

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class NewDonation extends Notification
{
    use Queueable;

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['mail'];
    }

    /**
     * Get the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        return (new MailMessage)
                    ->line('The introduction to the notification.')
                    ->action('Notification Action', url('/'))
                    ->line('Thank you for using our application!');
    }

    /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            //
        ];
    }
}
Enter fullscreen mode Exit fullscreen mode

I've edited the default class created to only send a notification to our discord channel.

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use NotificationChannels\Discord\DiscordChannel; // <-- Notice this line
use NotificationChannels\Discord\DiscordMessage; // <-- Notice this line

class NewDonation extends Notification
{
    use Queueable;

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return [DiscordChannel::class];
    }

    public function toDiscord($notifiable)
    {
        return DiscordMessage::create($this->getMessage());
    }

    private function getMessage() {
        return 'A new donation has been made!';
    }
}

Enter fullscreen mode Exit fullscreen mode

Setup the notifiable model

Ideally you should have tables and models setup that store information about the discord guild and also the channel ID you want to send the notification to.

You can get a channel's ID right clicking the channel name and clicking "Copy ID".

Assuming you have already have a table setup to store information about the guild and channel ID you want to post notification messages to, you should make sure your Guild model has the notifiable trait. e.g

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;

class Guild extends Model
{
    use HasFactory, Notifiable;

    public function routeNotificationForDiscord()
    {
        return $this->message_channel_id;
    }
}
Enter fullscreen mode Exit fullscreen mode

$this->message_channel_id here would refer to the column in your guilds table where the channel ID is stored.

Sending the notification

Now that we have our notification class created and our notifiable model setup, we can send the notification to our discord channel through the guild model.

Going back to our DiscordNotificationDemo controller. We can modify it like so:

<?php

namespace App\Http\Controllers;

use App\Models\Guild;
use App\Notifications\NewDonation;
use Illuminate\Http\Request;

class DiscordNotificationDemo extends Controller
{
    public function index()
    {
        $guild = Guild::findOrFail(1);
        $guild->notify(new NewDonation());
    }
}
Enter fullscreen mode Exit fullscreen mode

Now go to your your laravel project root and follow the endpoint you defined above /discord-notification and you should see a message sent to your discord channel!
Discord message sent

Mentioning roles or user(s)

The example above sends a very basic notification to the channel. However, you can also send a notification which mentions a specific user or role if you know the user's ID or the role ID.

We'll modify our NewDonation notification class to mention a specific user or role:

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use NotificationChannels\Discord\DiscordChannel; // <-- Notice this line
use NotificationChannels\Discord\DiscordMessage; // <-- Notice this line

class NewDonation extends Notification
{
    use Queueable;

    public $discordUserId;
    public $discordRoleId;

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct($discordUserId, $discordRoleId)
    {
        $this->discordUserId = $discordUserId;
        $this->discordRoleId = $discordRoleId;
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return [DiscordChannel::class];
    }

    public function toDiscord($notifiable)
    {
        return DiscordMessage::create($this->getMessage());
    }

    private function getMessage()
    {
        return "A new donation has been made by <@$this->discordUserId>! cc: <@&$this->discordRoleId>";
    }
}

Enter fullscreen mode Exit fullscreen mode

To quickly explain this, we've added a $discordUserId and $discordRoleId public property to our notification class and included them in our constructor so that we can dynamically specify the user/role we want to mention. We've used these properties in our getMessage() method to update our message. We'll use these properties to mention a specific user or role in our notification.

To mention a specific user the syntax is <@DISCORD_USER_ID> and to mention a role the syntax is <@&DISCORD_ROLE_ID>.

And then we need to update our controller to send the notification with the new params we added to our notification's class constructor:

/// ...
$guild->notify(new NewDonation(DISCORD_USER_ID, DISCORD_ROLE_ID));
Enter fullscreen mode Exit fullscreen mode

And then we can see the message sent to the discord channel!

Discord message sent with mentions

As you can see the interaction is no different than a regular mention (highlighted in yellow) in discord.

Sending the notification in a DM to a user.

Sending notifications to a user(s) is very similar to sending notifications to a channel as Discord considers a private conversation between multiple users to also be a "channel".

The main differences are:

  • Instead of copying a channel ID, we have to "generate" a DM channel between the user and the bot.
  • We also would need to make sure we are storing the user's Discord ID in a "discord user's" table.
  • Ensure the Discord user model has the notifiable trait.
  • We would need to add a routeNotificationForDiscord() method to the Discord user model.

Generating a DM channel

To generate a DM channel between a user and the bot, we can use the getPrivateChannel() method on the Discord client. This is an action that we should most likely do when a user logs in to our Laravel application via discord and we have access to their Discord ID. We can then use this ID to generate a DM channel with the bot.

Assuming we have the user's Discord ID in a variable $userId stored in a database. We could do:

use NotificationChannels\Discord\Discord;
use App\Models\DiscordUser;
// ...
$channelId = app(Discord::class)->getPrivateChannel($userId);

DiscordUser::update([
    'discord_user_id' => $userId,
    'discord_private_channel_id' => $channelId,
]);
Enter fullscreen mode Exit fullscreen mode

Which will store the user's Discord ID and the generated DM channel ID in the discord_user table.

Updating the user's model

Similar to the Guild model, we should update our DiscordUser model as so:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\SoftDeletes;

class DiscordUser extends Authenticatable
{
    use HasFactory, SoftDeletes, Notifiable;

    protected $guarded = ['id'];

    public function routeNotificationForDiscord()
    {
        return $this->discord_private_channel_id;
    }
}
Enter fullscreen mode Exit fullscreen mode

Sliding into the DMs as a bot 😏

Now that we have our user model updated, we can send a notification to the user's DM channel.

Let's create a new notification class

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class SlideIntoDm extends Notification
{
    use Queueable;

    public $discordUserId;

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct($discordUserId)
    {
        $this->discordUserId = $discordUserId;
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return [DiscordChannel::class];
    }

    public function toDiscord($notifiable)
    {
        return DiscordMessage::create($this->getMessage());
    }

    private function getMessage()
    {
        return "Hey <@$this->discordUserId> πŸ‘‹πŸΎ I'm a bot, sliding into your DMs 😏";
    }
}
Enter fullscreen mode Exit fullscreen mode

Update our controller.

use App\Notifications\SlideIntoDm;
use App\Models\DiscordUser;

// ...
public function slide_into_dm()
{
    $discordUser = DiscordUser::find(1);
    $discordUser->notify(new SlideIntoDm(DISCORD_USER_ID));
}
Enter fullscreen mode Exit fullscreen mode

Add the route:

/// ...
Route::get('slide-into-dm', [DiscordNotificationDemo::class, 'slide_into_dm']);
Enter fullscreen mode Exit fullscreen mode

Conclusion

We've learnt how to send Discord notifications to a channel, a user, or both using Laravel. The examples above are very straight forward for demo purposes. But ideally you should use notifications to react to events in your application and then send a message to the channel or user.

If you have any questions feel free to drop a comment here or even hit me up on my socials or even send me a message on Discord - MikeyBeLike#6718

I hope this helps!

Top comments (0)