Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
577e7dd
commit e6cc744
Showing
6 changed files
with
286 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package discordgo | ||
|
||
import ( | ||
"encoding/json" | ||
) | ||
|
||
// ComponentType is type of component. | ||
type ComponentType uint | ||
|
||
// Component types. | ||
const ( | ||
ActionsRowComponent ComponentType = iota + 1 | ||
ButtonComponent | ||
) | ||
|
||
// Component is a base interface for all components | ||
type Component interface { | ||
json.Marshaler | ||
Type() ComponentType | ||
} | ||
|
||
// ActionsRow is a container for components within one row. | ||
type ActionsRow struct { | ||
Components []Component `json:"components"` | ||
} | ||
|
||
func (r ActionsRow) MarshalJSON() ([]byte, error) { | ||
type actionRow ActionsRow | ||
|
||
return json.Marshal(struct { | ||
actionRow | ||
Type ComponentType `json:"type"` | ||
}{ | ||
actionRow: actionRow(r), | ||
Type: r.Type(), | ||
}) | ||
} | ||
|
||
func (r ActionsRow) Type() ComponentType { | ||
return ActionsRowComponent | ||
} | ||
|
||
// ButtonStyle is style of button. | ||
type ButtonStyle uint | ||
|
||
// Button styles. | ||
const ( | ||
// PrimaryButton is a button with blurple color. | ||
PrimaryButton ButtonStyle = iota + 1 | ||
// SecondaryButton is a button with grey color. | ||
SecondaryButton | ||
// SuccessButton is a button with green color. | ||
SuccessButton | ||
// DangerButton is a button with red color. | ||
DangerButton | ||
// LinkButton is a special type of button which navigates to a URL. Has grey color. | ||
LinkButton | ||
) | ||
|
||
// ButtonEmoji represents button emoji, if it does have one. | ||
type ButtonEmoji struct { | ||
Name string `json:"name,omitempty"` | ||
ID string `json:"id,omitempty"` | ||
Animated bool `json:"animated,omitempty"` | ||
} | ||
|
||
// Button represents button component. | ||
type Button struct { | ||
Label string `json:"label"` | ||
Style ButtonStyle `json:"style"` | ||
Disabled bool `json:"disabled"` | ||
Emoji ButtonEmoji `json:"emoji"` | ||
|
||
// NOTE: Only button with LinkButton style can have link. Also, Link is mutually exclusive with CustomID. | ||
Link string `json:"url,omitempty"` | ||
CustomID string `json:"custom_id,omitempty"` | ||
} | ||
|
||
func (b Button) MarshalJSON() ([]byte, error) { | ||
type button Button | ||
|
||
if b.Style == 0 { | ||
b.Style = PrimaryButton | ||
} | ||
|
||
return json.Marshal(struct { | ||
button | ||
Type ComponentType `json:"type"` | ||
}{ | ||
button: button(b), | ||
Type: b.Type(), | ||
}) | ||
} | ||
|
||
func (b Button) Type() ComponentType { | ||
return ButtonComponent | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
package main | ||
|
||
import ( | ||
"flag" | ||
"github.com/bwmarrin/discordgo" | ||
"log" | ||
"os" | ||
"os/signal" | ||
) | ||
|
||
// Bot parameters | ||
var ( | ||
GuildID = flag.String("guild", "", "Test guild ID") | ||
ChannelID = flag.String("channel", "", "Test channel ID") | ||
BotToken = flag.String("token", "", "Bot access token") | ||
AppID = flag.String("app", "", "Application ID") | ||
) | ||
|
||
var s *discordgo.Session | ||
|
||
func init() { flag.Parse() } | ||
|
||
func init() { | ||
var err error | ||
s, err = discordgo.New("Bot " + *BotToken) | ||
if err != nil { | ||
log.Fatalf("Invalid bot parameters: %v", err) | ||
} | ||
} | ||
|
||
func main() { | ||
s.AddHandler(func(s *discordgo.Session, r *discordgo.Ready) { | ||
log.Println("Bot is up!") | ||
}) | ||
// Buttons are part of interactions, so we register InteractionCreate handler | ||
s.AddHandler(func(s *discordgo.Session, i *discordgo.InteractionCreate) { | ||
if i.Type == discordgo.InteractionApplicationCommand { | ||
if i.Data.Name == "feedback" { | ||
err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ | ||
Type: discordgo.InteractionResponseChannelMessageWithSource, | ||
Data: &discordgo.InteractionResponseData{ | ||
Content: "Are you satisfied with Buttons?", | ||
// Buttons and other components are specified in Components field. | ||
Components: []discordgo.Component{ | ||
// ActionRow is a container of all buttons in the same raw. | ||
discordgo.ActionsRow{ | ||
Components: []discordgo.Component{ | ||
discordgo.Button{ | ||
Label: "Yes", | ||
Style: discordgo.SuccessButton, | ||
Disabled: false, | ||
CustomID: "yes_btn", | ||
}, | ||
discordgo.Button{ | ||
Label: "No", | ||
Style: discordgo.DangerButton, | ||
Disabled: false, | ||
CustomID: "no_btn", | ||
}, | ||
discordgo.Button{ | ||
Label: "I don't know", | ||
Style: discordgo.LinkButton, | ||
Disabled: false, | ||
// Link buttons doesn't require CustomID and does not trigger the gateway/HTTP event | ||
Link: "https://www.youtube.com/watch?v=dQw4w9WgXcQ", | ||
Emoji: discordgo.ButtonEmoji{ | ||
Name: "🤷♂️", | ||
}, | ||
}, | ||
}, | ||
}, | ||
// The message may have multiple actions rows. | ||
discordgo.ActionsRow{ | ||
Components: []discordgo.Component{ | ||
discordgo.Button{ | ||
Label: "Discord Developers server", | ||
Style: discordgo.LinkButton, | ||
Disabled: false, | ||
Link: "https://discord.gg/discord-developers", | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}) | ||
if err != nil { | ||
panic(err) | ||
} | ||
} | ||
return | ||
} | ||
// Type for button press will be always InteractionButton (3) | ||
if i.Type != discordgo.InteractionButton { | ||
return | ||
} | ||
|
||
content := "Thanks for your feedback " | ||
|
||
// CustomID field contains the same id as when was sent. It's used to identify the which button was clicked. | ||
switch i.Data.CustomID { | ||
case "yes_btn": | ||
content += "(yes)" | ||
case "no_btn": | ||
content += "(no)" | ||
} | ||
|
||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ | ||
// Buttons also may update the message which they was attached to. | ||
// Or may just acknowledge (InteractionResponseDeferredMessageUpdate) that the event was received and not update the message. | ||
// To update it later you need to use interaction response edit endpoint. | ||
Type: discordgo.InteractionResponseUpdateMessage, | ||
Data: &discordgo.InteractionResponseData{ | ||
Content: content, | ||
Components: []discordgo.Component{ | ||
discordgo.ActionsRow{ | ||
Components: []discordgo.Component{ | ||
discordgo.Button{ | ||
Label: "Our sponsor", | ||
Style: discordgo.LinkButton, | ||
Disabled: false, | ||
Link: "https://www.youtube.com/watch?v=dQw4w9WgXcQ", | ||
Emoji: discordgo.ButtonEmoji{ | ||
Name: "💠", | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}) | ||
}) | ||
_, err := s.ApplicationCommandCreate(*AppID, *GuildID, &discordgo.ApplicationCommand{ | ||
Name: "feedback", | ||
Description: "Give your feedback", | ||
}) | ||
|
||
if err != nil { | ||
log.Fatalf("Cannot create slash command: %v", err) | ||
} | ||
|
||
err = s.Open() | ||
if err != nil { | ||
log.Fatalf("Cannot open the session: %v", err) | ||
} | ||
defer s.Close() | ||
|
||
stop := make(chan os.Signal) | ||
signal.Notify(stop, os.Interrupt) | ||
<-stop | ||
log.Println("Graceful shutdown") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This is a breaking change, no?