> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mira.party/llms.txt
> Use this file to discover all available pages before exploring further.

# Scripting basics

> The template language behind welcome messages, embeds, tickets, level-ups and everything else you can customise.

Anywhere a command takes a `<script>` argument — welcome messages, autoresponders, ticket greetings, level-up announcements, sticky messages, starboard entries — you're writing in the same little template language. Learn it once and it applies everywhere.

A script is made of **nodes**. A node looks like `{name: value}`.

<CodeGroup>
  ```javascript Plain text theme={null}
  {content: hey {user.mention}, welcome in}
  ```

  ```javascript An embed theme={null}
  {title: Welcome!} {description: Glad you're here, {user.name}.} {color: #5cacec}
  ```

  ```javascript Both at once theme={null}
  {content: {user.mention}} {title: Welcome!} {description: You're member #{guild.members}.}
  ```
</CodeGroup>

That's the whole idea. Everything below is a list of which node names exist.

<Tip>
  You never have to write a script from scratch. `!copyembed <message>` (aliases `embedcode`, `ec`) takes any existing message — including one sent by another bot — and hands you back the script that would recreate it. Reply to a message with it, or pass a link.
</Tip>

## Testing as you go

`embed` renders a script immediately so you can iterate without committing it to a config:

```javascript theme={null}
!embed {title: test} {description: does this look right?} {color: dominant}
```

Aliases: `parse`, `script`, `ce`, `say`. Pass a channel first to send it somewhere else — `!embed #announcements {title: ...}`.

Most modules also have a preview: `!welcome view #general`, `!level message view`, `!jail message view`, `!counter preview <template>`.

## Message content

| Node             | Aliases                                                      | Notes                             |
| ---------------- | ------------------------------------------------------------ | --------------------------------- |
| `{content: ...}` | `message`, `msg`, `text`, `txt`, `response`, `reply`, `body` | The plain message above the embed |

If your script contains **no** recognised nodes at all, the whole thing is treated as plain content — so `!welcome add #general welcome {user.mention}` works fine without wrapping it in `{content:}`.

## Embeds

| Node                               | Aliases      | Example                                   |
| ---------------------------------- | ------------ | ----------------------------------------- |
| `{title: ...}`                     | —            | `{title: Server Rules}`                   |
| `{description: ...}`               | `desc`       | `{description: Read them.}`               |
| `{color: ...}`                     | `colour`     | `{color: #ff0000}` or `{color: dominant}` |
| `{url: ...}`                       | —            | Makes the title a link                    |
| `{thumbnail: ...}`                 | `thumb`      | Small image, top right                    |
| `{image: ...}`                     | `img`        | Large image at the bottom                 |
| `{author: name && icon && url}`    | —            | All three parts optional after the first  |
| `{footer: text && icon}`           | —            |                                           |
| `{field: name && value && inline}` | —            | Repeat for multiple fields                |
| `{timestamp: ...}`                 | `time`, `ts` |                                           |
| `{embed}`                          | `e`          | Starts a **new** embed — see below        |

Multi-part nodes are split on **`&&`**:

```javascript theme={null}
{author: {user.name} && {user.avatar} && https://mira.party}
{footer: Joined {guild.name} && {guild.icon}}
{field: Level && {user.level} && inline}
{field: Rank && #{user.rank} && inline}
```

Leave a part out to skip it. `{author: {user.name}}` is a name with no icon.

### Multiple embeds

`{embed}` acts as a divider. Everything after it belongs to a new embed:

```javascript theme={null}
{title: First} {description: one}
{embed}
{title: Second} {description: two}
```

### Dominant colour

`{color: dominant}` (or the shorthand `{dominant}`) pulls the accent colour from whatever image the embed already contains — author icon first, then thumbnail, then image, then footer icon. It's the easiest way to make an embed match an avatar.

<Info>
  Dominant colour is only computed for images hosted on Discord's own CDN — avatars, banners, icons, emojis and attachments. An arbitrary third-party image URL is left alone rather than being fetched.
</Info>

## Buttons

```javascript theme={null}
{button: label: "Rules" url: "https://discord.com/channels/..." style: "link"}
```

Button parts are `key: value` pairs. **Unlike embed nodes, they're separated by whitespace — not `&&`, and not `&`.** Quote any value containing spaces.

<Warning>
  Separating parts with `&` silently swallows the part before it, because `&` gets absorbed into the preceding value. Discord then rejects the message with something unhelpful:

  ```
  In components.0.components.3.accessory.label: This field is required
  ```

  ```javascript Wrong theme={null}
  {button: label: "Rules" & style: secondary}
  ```

  ```javascript Right theme={null}
  {button: label: "Rules" style: "secondary"}
  ```

  `&&` is only for the multi-part **embed** nodes above — `{author:}`, `{footer:}` and `{field:}`.
</Warning>

| Part       | Aliases                    | Values                                              |
| ---------- | -------------------------- | --------------------------------------------------- |
| `label`    | `text`                     | The visible text                                    |
| `url`      | —                          | Makes it a link button                              |
| `style`    | —                          | `primary`, `secondary`, `success`, `danger`, `link` |
| `emoji`    | —                          | Unicode or a custom emoji                           |
| `disabled` | —                          | `true` / `false`                                    |
| `message`  | `msg`, `response`, `reply` | An ephemeral reply shown when clicked               |

```javascript theme={null}
{button: label: "Get roles" emoji: "🎭" style: "success" message: "Head to #roles"}
```

A button with `message` responds privately to whoever clicked it — nobody else sees it. A button with `url` opens a link. A button with neither does nothing, which is occasionally what you want for decoration.

<Note>
  For buttons that actually **assign roles**, use [button roles](/setup/self-roles#button-roles) instead — `{button:}` in a script can't grant anything.
</Note>

## Stickers

```javascript theme={null}
{sticker: sticker name}
```

Matches a sticker available to the server by name.

## Escaping

To output a literal `{` without it being read as a node, escape it with a backslash: `\{not a node\}`.

## Where to go next

<CardGroup cols={2}>
  <Card title="Variables" icon="brackets-curly" href="/scripting/variables">
    `{user.name}`, `{guild.members}` and the rest of what you can interpolate.
  </Card>

  <Card title="Operators" icon="function" href="/scripting/operators">
    Conditionals, maths, random picks, text formatting.
  </Card>

  <Card title="Containers" icon="layer-group" href="/scripting/components">
    Discord's newer component layout — sections, separators, galleries.
  </Card>

  <Card title="Pagination" icon="book-open" href="/setup/auto-messages#paginated-messages">
    Turn a script into a multi-page message with navigation.
  </Card>
</CardGroup>
