---
description: Wanna use good old message commands instead? We have you covered!
---

# Message Commands

{% hint style="warning" %}
Unless you have a good reason to continue using legacy message contents, you're strongly recommended to migrate to **Application Commands** (i.e. **slash commands**) instead. Refer to [registering-commands](../build-a-bot/registering-commands "mention") and [responding-to-commands](../build-a-bot/responding-to-commands "mention") to see how that's accomplished with DiscordKit.
{% endhint %}

## Intents

[**Gateway Intents**](https://discord.com/developers/docs/topics/gateway#gateway-intents) is Discord's method of filtering gateway events, such that applications only receive the events that are useful to them. Events or fields that might contain sensitive data are gated behind "privileged intents" and require approval to remain enabled if your bot is in more than 100 servers.

### Developer Portal

Due to a controversial change that was made some time ago, user-created content (including messages) is now gated behind a privileged intent and empty by default. You'll have to enable it in both your bot application and Discord's Developer Portal in order for those fields to be populated.

To do so, go to your application in Discord's **Developer Portal** and enable the **Message Content Intent** under the **Bot** page (you might have to scroll down a bit). Make sure to press **Save Changes** after making this change!

<figure><img src="https://1903821505-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWJuHiYLW9jKqPb7h8D7t%2Fuploads%2F0u6KerRPvAEUZDeq2MuB%2FScreenshot%202022-12-14%20at%207.39.00%20PM.png?alt=media&#x26;token=8399f21b-975f-4078-b1cb-5f4434440e35" alt=""><figcaption><p>Just with a flick of a switch...</p></figcaption></figure>

{% hint style="warning" %}
As stated under the option, you'll have to **request for Discord's approval** to continue using the privileged message content intent when your bot is in **more than 100 servers!**
{% endhint %}

### Client Parameters

You'll also have to make a change to the intents specified during the creation of your `Client` object. You might be instantiating the `Client` object like so:

```swift
Client(intents: .unprivileged)
```

To enable the message content intent, simply append `.messageContent` to the bitfield:

```swift
Client(intents: [.unprivileged, .messageContent])
```

That's all the changes you'll need to make in your code to receive message contents.

## Handling Message Events

Now that you're receiving message contents, you'll need to handle them. To do so, place the following example code before the call to `.login()` (assuming `bot` is an instance of `Client`):

{% code lineNumbers="true" %}
```swift
bot.messageCreate.listen { message in
    print("Received message with content '\(message.content)'")
}
```
{% endcode %}

Rerun your bot, and you should see something printed out to your console every time a message is sent in any server your bot is in!&#x20;

To reply to a message, you could add something like the following code in the event handler:

```swift
if message.content == "?ping" {
    print("Received ping command!")
    _ = try? await message.reply("Pong!")
}
```

The bot should now reply to every message with the content "?ping" with a "Pong!" message!&#x20;

![](https://1903821505-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWJuHiYLW9jKqPb7h8D7t%2Fuploads%2F8Ea7EYxu83aStJQFRXs0%2Fimage.png?alt=media\&token=0336f224-51ed-49f0-8c9d-5ee2a943695d)

However, the code doesn't scale as the number of commands increase. At this point, you could choose to handle commands in any way you wish, but an example is provided below if you'd like something to build off:

{% code lineNumbers="true" %}
```swift
bot.messageCreate.listen { message in
    if message.content.hasPrefix(Self.MSG_CMD_PREFIX) { // Check if the message has our prefix
        // Remove the prefix and split the text into individual args
        let args = message.content.trimmingPrefix(Self.MSG_CMD_PREFIX).components(separatedBy: .whitespaces)
        // Ensure there's at least one arg, which will be used as the command
        guard let command = args.first else { return }
        switch command {
        case "ping":
            _ = try? await message.reply("Pong!")
        default:
            _ = try? await message.reply("I don't recognise that command :(")
        }
    }
}
```
{% endcode %}

Add the following static property in the struct that's annotated with `@main`:

```swift
/// The prefix we're using for commands
///
/// This reads from the `MESSAGE_COMMAND_PREFIX` environment variable and defaults
/// to "?" as the prefix if the variable isn't found.
static let MSG_CMD_PREFIX = ProcessInfo.processInfo.environment["MESSAGE_COMMAND_PREFIX"] ?? "?"
```

And you're all set! Go build something wonderful with message commands (or use slash commands as a better alternative instead)!
