Your first V2 message
In this guide you’ll send a message like this one. Pick your language in the tabs: your choice is remembered on every page.
{ "flags": 32768, "components": [ { "type": 17, "accent_color": 5793266, "components": [ { "type": 10, "content": "## My first V2 message 🎉\nMade with a **Container** and a **Text Display**." }, { "type": 14 }, { "type": 1, "components": [ { "type": 2, "style": 1, "label": "Hello", "custom_id": "say_hello" } ] } ] } ]}Requirements
Section titled “Requirements”-
Create an application in the Discord Developer Portal and copy the bot token (Bot tab).
-
Invite the bot to your server with the Send Messages permission.
-
Install the library for your language:
Nothing needed: just
curlor any HTTP client.Ventana de terminal npm install discord.jsUse a recent discord.js v14 release (Components V2 builders arrived in 14.19).
Ventana de terminal pip install -U discord.pyYou need discord.py 2.6 or newer (adds
LayoutView,Container,Section…).Ventana de terminal go get github.com/bwmarrin/discordgo@latestUse the latest version: it includes
Container,TextDisplay,SectionandMessageFlagsIsComponentsV2.
Send the message
Section titled “Send the message”Save the JSON above as payload.json and send it:
curl -X POST "https://discord.com/api/v10/channels/CHANNEL_ID/messages" \ -H "Authorization: Bot $DISCORD_TOKEN" \ -H "Content-Type: application/json" \ -d @payload.jsonimport { Client, GatewayIntentBits, MessageFlags, ContainerBuilder, ButtonBuilder, ButtonStyle,} from 'discord.js';
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
client.once('clientReady', async () => { const channel = await client.channels.fetch('CHANNEL_ID');
const container = new ContainerBuilder() .setAccentColor(0x5865f2) .addTextDisplayComponents((text) => text.setContent('## My first V2 message 🎉\nMade with a **Container** and a **Text Display**.'), ) .addSeparatorComponents((separator) => separator) .addActionRowComponents((row) => row.setComponents( new ButtonBuilder().setCustomId('say_hello').setLabel('Hello').setStyle(ButtonStyle.Primary), ), );
await channel.send({ flags: MessageFlags.IsComponentsV2, components: [container], });});
client.login(process.env.DISCORD_TOKEN);import osimport discord
intents = discord.Intents.default()client = discord.Client(intents=intents)
@client.eventasync def on_ready(): channel = client.get_channel(123456789012345678) # channel ID
view = discord.ui.LayoutView() container = discord.ui.Container( discord.ui.TextDisplay("## My first V2 message 🎉\nMade with a **Container** and a **Text Display**."), discord.ui.Separator(), discord.ui.ActionRow( discord.ui.Button(label="Hello", style=discord.ButtonStyle.primary, custom_id="say_hello"), ), accent_colour=0x5865F2, ) view.add_item(container)
# discord.py sets the IS_COMPONENTS_V2 flag automatically when you use LayoutView await channel.send(view=view)
client.run(os.environ["DISCORD_TOKEN"])package main
import ( "log" "os" "os/signal"
"github.com/bwmarrin/discordgo")
func main() { s, err := discordgo.New("Bot " + os.Getenv("DISCORD_TOKEN")) if err != nil { log.Fatal(err) }
s.AddHandler(func(s *discordgo.Session, r *discordgo.Ready) { color := 0x5865F2 _, err := s.ChannelMessageSendComplex("CHANNEL_ID", &discordgo.MessageSend{ Flags: discordgo.MessageFlagsIsComponentsV2, Components: []discordgo.MessageComponent{ discordgo.Container{ AccentColor: &color, Components: []discordgo.MessageComponent{ discordgo.TextDisplay{Content: "## My first V2 message 🎉\nMade with a **Container** and a **Text Display**."}, discordgo.Separator{}, discordgo.ActionsRow{ Components: []discordgo.MessageComponent{ discordgo.Button{Label: "Hello", Style: discordgo.PrimaryButton, CustomID: "say_hello"}, }, }, }, }, }, }) if err != nil { log.Println("error sending message:", err) } })
if err := s.Open(); err != nil { log.Fatal(err) } defer s.Close()
stop := make(chan os.Signal, 1) signal.Notify(stop, os.Interrupt) <-stop}Other ways to send a V2 message
Section titled “Other ways to send a V2 message”Responding to a command or button
Section titled “Responding to a command or button”An interaction response uses the same body, wrapped in type and data:
{ "type": 4, "data": { "flags": 32768, "components": [ { "type": 10, "content": "Command received!" } ] }}See Interactions for the details.
With a webhook
Section titled “With a webhook”Webhooks ignore components unless you add ?with_components=true:
curl -X POST "https://discord.com/api/v10/webhooks/ID/TOKEN?with_components=true" \ -H "Content-Type: application/json" \ -d @payload.jsonWith attachments
Section titled “With attachments”To display an image or file uploaded by your bot, send the request as multipart/form-data and refer to the file with attachment://name:
curl -X POST "https://discord.com/api/v10/channels/CHANNEL_ID/messages" \ -H "Authorization: Bot $DISCORD_TOKEN" \ -F 'payload_json={"flags":32768,"components":[{"type":12,"items":[{"media":{"url":"attachment://photo.png"}}]}]}' \import { AttachmentBuilder, MediaGalleryBuilder, MessageFlags } from 'discord.js';
const file = new AttachmentBuilder('./photo.png');const gallery = new MediaGalleryBuilder().addItems((item) => item.setURL('attachment://photo.png'));
await channel.send({ flags: MessageFlags.IsComponentsV2, components: [gallery], files: [file] });file = discord.File("photo.png", filename="photo.png")
view = discord.ui.LayoutView()gallery = discord.ui.MediaGallery()gallery.add_item(media="attachment://photo.png")view.add_item(gallery)
await channel.send(view=view, file=file)f, _ := os.Open("photo.png")defer f.Close()
s.ChannelMessageSendComplex(channelID, &discordgo.MessageSend{ Flags: discordgo.MessageFlagsIsComponentsV2, Files: []*discordgo.File{{Name: "photo.png", ContentType: "image/png", Reader: f}}, Components: []discordgo.MessageComponent{ discordgo.MediaGallery{ Items: []discordgo.MediaGalleryItem{ {Media: discordgo.UnfurledMediaItem{URL: "attachment://photo.png"}}, }, }, },})Next step
Section titled “Next step”Your bot can now send V2 messages. Next, learn how to respond when someone clicks a button.