# Embeds

> Build embeds in code, load the embeds you saved on the dashboard, and send files.

An **embed** is the box Discord draws around a message, with a colored edge, a title, fields and images.

You can make embeds in two ways:

- **On the dashboard.** Open **Embeds**, design it, save it. Then load it in code with `load_embed`.
- **In code.** Build one with `Message(...)`.

A built embed goes anywhere a message goes: `set_embed`, `send_message(message=...)`, `send_dm(message=...)` and paginator pages. See [Messages](https://ccbot.app/docs/reference/messages) and [Response](https://ccbot.app/docs/reference/response).

None of these functions need `await`.

## Message

Builds a message: text, an embed, or both. Every argument is optional.

```python
Message(
    content=None,
    title=None,
    url=None,
    color=None,
    description=None,
    fields=None,
    image=None,
    thumbnail=None,
    footer=None,
    footer_icon=None,
    timestamp=None,
    author=None,
    author_icon=None,
    author_url=None,
    embed=None,
    populate={},
)
```

| Argument | What it does |
|---|---|
| `content` | Plain text above the embed. |
| `title` | The embed title. |
| `url` | Makes the title a link. |
| `color` | The side color, as a hex code like `"#5865F2"`. |
| `description` | The main text of the embed. |
| `fields` | A list of fields. Each field is `(name, value, inline)`. |
| `image` | A big image at the bottom. A link, a rendered image, or a loaded file. |
| `thumbnail` | A small image in the top right. Same kinds as `image`. |
| `footer` | Small text at the bottom. |
| `footer_icon` | A small image next to the footer. |
| `timestamp` | A date shown next to the footer. Use `get_time("now")`. |
| `author` | Small text above the title. |
| `author_icon` | A small image next to the author. |
| `author_url` | Makes the author a link. |
| `embed` | A ready embed to send as is. |
| `populate` | Fills `{name}` placeholders in the text. See below. |

The embed part is only made when you set at least one embed field. `Message(content="Hi")` sends plain text.

**Example: a profile card**

```python
set_response_message(Message(
    title=user.display_name,
    color="#5865F2",
    thumbnail=user.avatar_url,
    fields=[
        ("Joined", f"<t:{user.unix_joined_at}:R>", True),
        ("Roles", str(len(user.role_names)), True),
    ],
    footer=f"ID: {user.id}",
))
```

**Example: show a rendered image inside the embed**

```python
card = await render_template("rank-card", name=user.display_name, level=5)
send_message(channel, message=Message(title="Your rank", image=card))
```

You do not need `attachments=` here. The image uploads with the message.

### Add fields one at a time

```python
msg = Message(title="Top players")
msg.add_field("1st", "Alex", True)
msg.add_field("2nd", "Sam", True)
```

`add_field(name, value, inline=False)` skips a field when the name or value is empty.

### Fill placeholders with populate

`populate` replaces `{name}` in the text with a value. Unknown names stay as written.

```python
Message(description="Hello {who}!", populate={"who": user.mention})
```

## load_embed

Loads an embed you saved on the dashboard. Variables in it, like `{user.mention}`, are filled in.

```python
load_embed(embed_id, **values)
```

| Argument | What it does |
|---|---|
| `embed_id` | The embed's ID from the dashboard. |
| `**values` | Extra values for the embed's placeholders. They win over your variables. |

```python
set_embed(load_embed("welcome-card"))
```

```python
# Fill {card} in the saved embed with a rendered image
card = await render_template("welcome", avatar=user.avatar_url)
send_message(channel, embed=load_embed("welcome-card", card=card))
```

Fails with *"Embed with id: ... not found"* when the ID is wrong.

## load_components

Loads buttons and menus you saved under **Components** on the dashboard.

```python
load_components(id)
```

```python
set_components(load_components("support-buttons"))
```

## Attachment

A file to send with a message.

```python
Attachment(file, filename)
```

| Argument | What it does |
|---|---|
| `file` | The file's bytes. |
| `filename` | The name Discord shows, like `"report.txt"`. |

```python
data = "Name,Coins\nAlex,120\n".encode()
send_message(channel, "Here is the list.", attachments=[Attachment(data, "coins.csv")])
```

To send a file from a link, use `load_file` instead. See [Web and files](https://ccbot.app/docs/reference/web-and-files).

## Embed methods

Sometimes you get a raw Discord embed, for example from `message.embeds`. You can read and change it with these:

| Name | What it does |
|---|---|
| `title`, `description`, `url`, `color`, `timestamp` | Read the main parts. |
| `author`, `footer`, `image`, `thumbnail`, `fields` | Read the other parts. |
| `add_field(name, value, inline=False)` | Adds a field. |
| `edit_field(index, ...)` | Changes a field. |
| `remove_field(index)` | Removes a field. |
| `set_author(name=..., url=..., icon=...)` | Sets the author line. |
| `set_footer(text=..., icon=...)` | Sets the footer. |
| `set_image(url)` | Sets the big image. |
| `set_thumbnail(url)` | Sets the small image. |
| `clear_fields()` | Removes all fields. |
| `total_length()` | Counts every character in the embed. |

> **Tip:** Use `Message(...)` or `load_embed(...)` when you can. They are shorter and handle images for you.

## Discord limits for embeds

| Part | Most allowed |
|---|---|
| Title | 256 characters |
| Description | 4,096 characters |
| Fields | 25 |
| Field name | 256 characters |
| Field value | 1,024 characters |
| Footer | 2,048 characters |
| Whole embed | 6,000 characters |
