Sending Discord Messages with Simba

Learn how to use the discord.simba library to send messages, embeds, and files to Discord channels via webhooks.

Author: Loading...

Sending Discord Messages from Script

Integrating Discord notifications into your automation routines can be incredibly useful for monitoring progress, reporting errors, or simply staying updated on your program’s activities. This tutorial guides you through using the discord.simba library to send messages, rich embeds, and even files like screenshots directly to your Discord channels using webhooks.

Creating Your Own Discord Server

Before you can create a webhook, you need a Discord server where your notifications will be sent. If you don’t already have a server you want to use for this purpose, creating one is simple:

How to Create a Discord Server

Give your server a name, and you’re ready to proceed to setting up a webhook.

What is a Webhook?

Think of a Discord webhook as a dedicated URL that allows external applications (like your script) to send messages to a specific channel without needing a full discord bot user. You can create a webhook easily within your Discord server’s settings under “Integrations”.

Important: This webhook URL must be created on a Discord server that you control or have permissions to manage. It is for sending notifications to your own designated channels. This library cannot be used to send messages to the official WaspScripts Discord server or any other server for which you do not have a valid webhook URL.

Creating a Discord Webhook (Image Source: Discord Support)

Once created, copy the Webhook URL – you’ll need it!

Getting Started: Setting Up the Client

First, include the necessary WaspLib files and declare a TDiscordClient variable. The core setup involves creating the client and providing it with your webhook URL.

{$I WaspLib/osr.simba}
{$I Wasplib/optional/handlers/discord.simba}

var
  Discord: TDiscordClient;
  WebhookURL: String;
begin
  Discord.Setup();

  WebhookURL := 'https://discord.com/api/webhooks/your_webhook_id/your_webhook_token'; // <-- PASTE YOUR URL HERE

  if not Discord.SetWebhook(WebhookURL) then
  begin
    WriteLn('Failed to set webhook: ' + Discord.LastError);
    Exit;
  end;

  Discord.SetUsername('Simba Notifier');
  Discord.SetAvatar('https://raw.githubusercontent.com/Torwent/wasp-webapp/refs/heads/main/static/favicon.png');

  Discord.Free();
end.

The TDiscordClient.Setup procedure prepares the client. It can optionally load settings from a discord.json file in your script’s directory (more on that later).

The crucial step is TDiscordClient.SetWebhook. This function takes your webhook URL, validates its format, and attempts a quick check with Discord to ensure it’s a working webhook. If the validation fails (e.g., incorrect URL format, invalid token), it returns False, and you can check Discord.LastError for details. Always check the return value of SetWebhook.

You can also customize the name and avatar displayed in Discord using SetUsername and SetAvatar.

Sending Simple Text Messages

The most basic usage is sending plain text. Assign your message to Discord.Webhook.Content and call Discord.Send.

Discord.Webhook.Content := 'Hello from Simba!';

if Discord.Send() then
  WriteLn('Simple message sent successfully!')
else
  WriteLn('Failed to send message: ' + Discord.LastError);

The Send function returns True on success and False on failure. Failures might occur due to network issues, rate limits, or an invalid webhook (if validation was skipped or failed silently earlier). The library automatically retries a few times on transient errors.

Enhancing Messages with Embeds

Embeds allow for more structured and visually appealing messages. You can add titles, descriptions, colors, footers, and even images.

var
  EmbedIdx: Int32;

Discord.Webhook.Content := 'Here is a status update:';

EmbedIdx := Discord.Webhook.AddEmbed();

with Discord.Webhook.Embeds[EmbedIdx] do
begin
  Title := 'Bot Status';
  Description := ':robot: Everything is running smoothly.';
  Color := clGreen;
  Footer := 'Checked at ' + FormatDateTime('hh:nn:ss', Now);
end;

if Discord.Send() then
  WriteLn('Message with embed sent successfully!')
else
  WriteLn('Failed to send embed message: ' + Discord.LastError);

Mentioning Users

You can ping specific users by including a mention string in your message content.

How to Find User IDs

To get the necessary User ID for mentioning, you first need to enable Developer Mode in your Discord settings and then copy the specific user’s ID.

1. Enable Developer Mode

How to Enable Discord Developer Mode

  • Tap on the cogwheel (User Settings) in the bottom left corner of the desktop app.
  • Go to the “Advanced” section.
  • Toggle “Developer Mode” on. A checkmark indicates it’s enabled.

2. Copy the User ID

How to Copy a Discord User ID

  • Navigate to the server, group chat, or direct message where the user is.
  • Right-click on the user’s name or avatar.
  • Select “Copy User ID”.

Now you have the User ID ready to use in your script!

var
  AdminUserID: String;

AdminUserID := '123456789012345678'; // Replace with actual ID copied using the steps above

Discord.Webhook.Content := 'Alert! Need attention from ' + Discord.MentionUser(AdminUserID);

if Discord.Send() then
  WriteLn('Mention sent successfully!')
else
  WriteLn('Failed to send mention: ' + Discord.LastError);

Use TDiscordClient.MentionUser with the user’s Discord ID to create the correct mention format (<@UserID>).

Sending Files and Screenshots

The library makes it easy to upload files, particularly useful for sending logs or screenshots.

Sending an Existing File

var
  LogFilePath: String;

LogFilePath := ScriptPath + 'script_log.txt';

Discord.Webhook.Content := 'Here is the latest log file:';

if Discord.SendFile(LogFilePath) then
  WriteLn('File sent successfully!')
else
  WriteLn('Failed to send file: ' + Discord.LastError + ' (' + LogFilePath + ')');

Use TDiscordClient.SendFile, providing the full path to the file you want to upload. The library attempts to determine the correct MIME type based on the file extension for common types like .png, .jpg, and .gif.

Sending a Screenshot

A common use case is sending a screenshot of the game client.

Discord.Webhook.Content := 'Current game state:';

if Discord.SendScreenshot(True) then
  WriteLn('Screenshot sent successfully!')
else
  WriteLn('Failed to send screenshot: ' + Discord.LastError);

TDiscordClient.SendScreenshot captures the client area, optionally anonymizes it by blacking out potentially identifying information (like chat, username, XP bar when Anonymous is True), saves it as a temporary PNG file, uploads it using SendFile, and then deletes the temporary file.

Remember, like all messages sent using your webhook, these screenshots will only appear in the specific Discord channel you configured the webhook for on your server.

You might set Anonymous to True if you plan on bragging about your progress in certain ahem less reputable Discord servers where hiding your details is wise. Set it to False when sharing with your actual friends or clanmates, who might wonder why your chatbox is mysteriously blacked out!

Using a Configuration File (discord.json)

To avoid having to provide your webhook URL, username, or avatar every time your program runs, the discord.simba library automatically saves these settings to a discord.json file in your program’s directory whenever you successfully use SetWebhook, SetUsername, or SetAvatar.

On subsequent runs, TDiscordClient.Setup will automatically load these saved settings from the discord.json file if it exists. This means you typically only need to configure the webhook details once via the script functions; afterwards, Setup will handle loading them.

Example discord.json (automatically created/updated):

{
  "webhook_url": "https://discord.com/api/webhooks/your_webhook_id/your_webhook_token",
  "webhook_username": "My Default Bot Name",
  "webhook_avatar": "https://example.com/default_avatar.png"
}

If these settings are present in the JSON file, you might not need to call SetWebhook, SetUsername, or SetAvatar in your program, unless you want to override the JSON values. However, it’s still recommended to call SetWebhook if you load the URL from JSON, as this performs the crucial validation step.

var
  LoadedURL: String;
begin
  Discord.Setup(); // Loads from discord.json

  LoadedURL := Discord.Config.GetString('webhook_url');
  if (LoadedURL = '') or (not Discord.SetWebhook(LoadedURL)) then
  begin
    WriteLn('Webhook URL missing in config or invalid: ' + Discord.LastError);
    Exit;
  end;
  // ... rest of your script using the validated webhook
end;

Complete Example Script

Here’s a script demonstrating several features together:

{$I WaspLib/osr.simba}
{$I Wasplib/optional/handlers/discord.simba}

var
  Discord: TDiscordClient;
  WebhookURL: String;
  EmbedIdx: Int32;
  ErrorMsg: String;
  AdminUserID: String;

begin
  Discord.Setup();

  WebhookURL := 'https://discord.com/api/webhooks/your_webhook_id/your_webhook_token'; // <-- PASTE YOUR URL HERE
  if not Discord.SetWebhook(WebhookURL) then
  begin
    WriteLn('Failed to configure Discord webhook: ' + Discord.LastError);
    Exit;
  end;
  Discord.SetUsername('Script Reporter');

  try
    Discord.Webhook.Content := 'Script started!';
    if not Discord.Send() then
      WriteLn('Failed to send startup message: ' + Discord.LastError);
    Wait(1000);

    Discord.Webhook.Content := 'Status Update';
    EmbedIdx := Discord.Webhook.AddEmbed();
    with Discord.Webhook.Embeds[EmbedIdx] do
    begin
      Title := 'Progress Report';
      Description := 'Task A completed successfully.';
      Color := clGreen;
      Footer := FormatDateTime('hh:nn:ss', Now);
    end;
    if not Discord.Send() then
      WriteLn('Failed to send embed message: ' + Discord.LastError);
    Wait(1000);

    Discord.Webhook.Content := 'Current view:';
    if not Discord.SendScreenshot(True) then
       WriteLn('Failed to send screenshot: ' + Discord.LastError);
    Wait(1000);

    ErrorMsg := 'Critical error: Target not found.';
    AdminUserID := '123456789012345678'; // Replace with actual ID copied using the steps above
    Discord.Webhook.Content := 'Error! ' + Discord.MentionUser(AdminUserID);
    EmbedIdx := Discord.Webhook.AddEmbed();
     with Discord.Webhook.Embeds[EmbedIdx] do
    begin
      Title := ':warning: Alert';
      Description := ErrorMsg;
      Color := clRed;
    end;
     if not Discord.Send() then
       WriteLn('Failed to send error message: ' + Discord.LastError);
    Wait(1000);

    Discord.Webhook.Content := 'Script finished.';
    if not Discord.Send() then
       WriteLn('Failed to send final report: ' + Discord.LastError);

  finally
    Discord.Free();
    WriteLn('Discord client resources released.');
  end;
end.

Remember to replace placeholder values like the webhook URL and User ID with your actual data. With this library, you can keep yourself informed about your program’s status directly within Discord. Happy coding!