---
sidebar_label: Overview
---

# Overview of Interactions

Interactive features like commands and message components allows users to invoke an app natively within Discord. When a user engages with one of your app's interactive features, your app will receive an [interaction](/docs/interactions/receiving-and-responding#interaction-object).

This overview includes an overview of the main types of interactions, and steps for you to prepare your app to use and receive interactions. Reference documentation and details about handling interactions are in [Receiving and Responding](/docs/interactions/receiving-and-responding).

---

## Types of Interactions

There are different types of interactions in your app's toolbelt that can pick and choose to build engaging, interactive experiences in Discord.

### Commands

**[Application commands](/docs/interactions/application-commands)** provide users a native way to invoke an app in Discord. They often map to an app's core features or functionality.

![Command launcher in the Desktop client](images/overview-command-desktop.webp)

When an app creates a command it can choose the command's type, which determines where it appears in the Discord client and the metadata the app will receive when the command is invoked. There are three types for application commands:

- **Slash commands** are the most common type of command and are accessed by typing `/` in the chat input, or by opening the command picker.
- **Message commands** are commands related to a message or a message's content. They're accessed by clicking on the context menu (the three dots) at the top-right of a message (or right clicking on a message), then navigating to the "Apps" section.
- **User commands** are commands that related to a user in Discord. They're accessed by right clicking on a user profile, then navigating to the "Apps" section.
- **Entry Point commands** are commands used as the primary way to launch [Activities](/docs/activities/overview) from the App Launcher.

Details about creating commands and handling command interactions are in the [Application Commands](/docs/interactions/application-commands) documentation.

### Message Components

**[Message components](/docs/components/reference)** are interactive elements that can be included in the content of a message that your app sends in Discord. 

![Button message components in a message](images/overview-components.webp)

The main interactive components that apps can send in messages include:

- [Buttons](/docs/components/reference#button) are clickable components that can be customized with different styles, texts, and emoji.
- [Static select menus](/docs/components/reference#string-select) are components that a user can open to see a list of developer-defined select options with custom labels and descriptions.
- [Auto-populated select menus](/docs/components/reference#string-select) are a set of four different select components that are populated with contextual Discord resources, like a list of users or channels in a server.

A list of all message components and details on sending and receiving component interactions is in the [Message Components](/docs/components/reference) documentation.

### Modals

**[Modals](/docs/interactions/receiving-and-responding#interaction-response-object-modal)** are single-user pop-up interfaces that allow apps to collect form-like data. Modals can only be opened in response to a user invoking one of your app's commands or message components.

![Modals in the Discord client](images/overview-modals.webp)

The components that modals can contain are found in the [component reference](/docs/components/reference). The data received after a modal is submitted can be found in [each component's interaction response structure](/docs/interactions/receiving-and-responding#interaction-response-object-modal).

Details about creating and using modals is in the [Receiving and Responding](/docs/interactions/receiving-and-responding#interaction-response-object-modal) documentation.

---

## Preparing for Interactions

When a user interacts with your app, you have the option for your app to receive interactions in two mutually-exclusive ways:
- WebSocket-based Gateway connection
- HTTP via outgoing webhooks

By default your app will receive interactions via a Gateway connection, but you can opt-in to HTTP-based interactions by adding a **Interactions Endpoint URL** to your app's settings. Technical details about handling interactions is in the [Receiving and Responding](/docs/interactions/receiving-and-responding) documentation.

### Configuring an Interactions Endpoint URL

A **Interactions Endpoint URL** is a public endpoint for your app where Discord can send your app HTTP-based interactions. If your app is using [Gateway](/docs/events/gateway)-based interactions, you don't need to configure an Interactions Endpoint URL.

#### Setting Up an Endpoint

Before you can add your Interactions Endpoint URL to your app, your endpoint must be prepared for two things ahead of time:

1. Acknowledging `PING` requests from Discord
2. Validate security-related request headers (`X-Signature-Ed25519` and `X-Signature-Timestamp`)

If either of these are not complete, your Interactions Endpoint URL will not be validated. Details on acknowledging PING requests and validating security-related headers are in the sections below.

###### Acknowledging PING requests

When adding your Interactions Endpoint URL, Discord will send a `POST` request with a `PING` payload with a `type: 1` to your endpoint. Your app is expected to acknowledge the request by returning a `200` response with a `PONG` payload (which has the same `type: 1`). Details about interaction responses are in the [Receiving and Responding documentation](/docs/interactions/receiving-and-responding).

:::info
You must provide a valid `Content-Type` when responding to `PING`s. See [here](/docs/reference#http-api) for further information.
:::

<Collapsible title="Responding to PING Requests" description="Code example for acknowledging PING interactions" icon="code">
To properly acknowledge a `PING` payload, return a `200` response with a payload of `type: 1`:

```py
@app.route('/', methods=['POST'])
def my_command():
    if request.json["type"] == 1:
        return jsonify({
            "type": 1
        })
```
</Collapsible> 

###### Validating Security Request Headers

The internet is a scary place, especially for people hosting public, unauthenticated endpoints. To receive interactions via HTTP, there are some security steps you **must** take before your app is eligible to receive requests.

Each interaction is sent with the following headers:

-   `X-Signature-Ed25519` as a signature
-   `X-Signature-Timestamp` as a timestamp

Using your favorite security library, you **must validate the request each time you receive an [interaction](/docs/interactions/receiving-and-responding#interaction-object)**. If the signature fails validation, your app should respond with a `401` error code.

<Collapsible title="Validating Security Headers" description="Code example for validating security-related request headers" icon="code">
Below are some code examples that show how to validate the headers sent in interactions requests.

**JavaScript**

```js
const nacl = require("tweetnacl");

// Your public key can be found on your application in the Developer Portal
const PUBLIC_KEY = "APPLICATION_PUBLIC_KEY";

const signature = req.get("X-Signature-Ed25519");
const timestamp = req.get("X-Signature-Timestamp");
const body = req.rawBody; // rawBody is expected to be a string, not raw bytes

const isVerified = nacl.sign.detached.verify(
    Buffer.from(timestamp + body),
    Buffer.from(signature, "hex"),
    Buffer.from(PUBLIC_KEY, "hex")
);

if (!isVerified) {
    return res.status(401).end("invalid request signature");
}
```

**Python**

```py
from nacl.signing import VerifyKey
from nacl.exceptions import BadSignatureError

# Your public key can be found on your application in the Developer Portal
PUBLIC_KEY = 'APPLICATION_PUBLIC_KEY'

verify_key = VerifyKey(bytes.fromhex(PUBLIC_KEY))

signature = request.headers["X-Signature-Ed25519"]
timestamp = request.headers["X-Signature-Timestamp"]
body = request.data.decode("utf-8")

try:
    verify_key.verify(f'{timestamp}{body}'.encode(), bytes.fromhex(signature))
except BadSignatureError:
    abort(401, 'invalid request signature')
```
</Collapsible> 

In addition to ensuring your app validates security-related request headers at the time of saving your endpoint, Discord will also perform automated, routine security checks against your endpoint, including purposefully sending you invalid signatures. If you fail the validation, we will remove your interactions URL and alert you via email and System DM.

We highly recommend checking out our [Community Resources](/docs/developer-tools/community-resources#interactions) and the libraries found there. They not only provide typing for Interactions data models, but also include decorators for API frameworks like Flask and Express to make validation easy.

#### Adding an Interactions Endpoint URL

After you have a public endpoint to use as your app's Interactions Endpoint URL, you can add it to your app by going to your [app's settings](https://discord.com/developers/applications).

On the **General Overview** page, look for the **Interactive Endpoint URL** field. Paste your public URL that is set up to acknowledge `PING` messages and correctly handles security-related signature headers.

---

## Handling Interactions

Once your app is prepared for interactions, you can explore the [Receiving and Responding](/docs/interactions/receiving-and-responding) documentation which goes into the technical details of handling interactions requests in your app.