Slash commands (#856)
* UnknownBan error code addition * GuildBan method implementation * Gofmt fix Gofmt fix * Interactions: application commands basic API and gateway integration * Some gitignore update * Application commands and interactions API implementation * Some fixes * Some improvements of slash-commands example and slash-commands API * OAuth2 endpoints backward compatibility * Gofmt fix * Requested fixes and documentation improvement for application commands * Some fixes * New and more interesting example of slash-commands usage, merging "interaction.go" and "interactions.go" into a single file. And some fixes. * Gofmt and documentation fixes * More fixes * Gofmt fixes * More fixes! * Doc and endpoint fixes * Gofmt fix * Remove dependence on open gateway connection * Remove redundant command ID checks * Fix typo in ApplicationCommandCreate comment * Tidy up function calls returning body * Add upcoming API changes * Correct return value name, swap parameter order * Add Version field to ApplicationCommand * Fix up language in comments * Remove redundant conversion to float64 Co-authored-by: Carson Hoffman <c@rsonhoffman.com>
This commit is contained in:
parent
4617d8e379
commit
b0fa920925
11 changed files with 921 additions and 49 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,2 +1,5 @@
|
|||
# IDE-specific metadata
|
||||
.idea/
|
||||
|
||||
# Environment variables. Useful for examples.
|
||||
.env
|
||||
|
|
52
endpoints.go
52
endpoints.go
|
@ -122,6 +122,9 @@ var (
|
|||
EndpointChannelWebhooks = func(cID string) string { return EndpointChannel(cID) + "/webhooks" }
|
||||
EndpointWebhook = func(wID string) string { return EndpointWebhooks + wID }
|
||||
EndpointWebhookToken = func(wID, token string) string { return EndpointWebhooks + wID + "/" + token }
|
||||
EndpointWebhookMessage = func(wID, token, messageID string) string {
|
||||
return EndpointWebhookToken(wID, token) + "/messages/" + messageID
|
||||
}
|
||||
|
||||
EndpointMessageReactionsAll = func(cID, mID string) string {
|
||||
return EndpointChannelMessage(cID, mID) + "/reactions"
|
||||
|
@ -133,6 +136,35 @@ var (
|
|||
return EndpointMessageReactions(cID, mID, eID) + "/" + uID
|
||||
}
|
||||
|
||||
EndpointApplicationGlobalCommands = func(aID string) string {
|
||||
return EndpointApplication(aID) + "/commands"
|
||||
}
|
||||
EndpointApplicationGlobalCommand = func(aID, cID string) string {
|
||||
return EndpointApplicationGlobalCommands(aID) + "/" + cID
|
||||
}
|
||||
|
||||
EndpointApplicationGuildCommands = func(aID, gID string) string {
|
||||
return EndpointApplication(aID) + "/guilds/" + gID + "/commands"
|
||||
}
|
||||
EndpointApplicationGuildCommand = func(aID, gID, cID string) string {
|
||||
return EndpointApplicationGuildCommands(aID, gID) + "/" + cID
|
||||
}
|
||||
EndpointInteraction = func(aID, iToken string) string {
|
||||
return EndpointAPI + "interactions/" + aID + "/" + iToken
|
||||
}
|
||||
EndpointInteractionResponse = func(iID, iToken string) string {
|
||||
return EndpointInteraction(iID, iToken) + "/callback"
|
||||
}
|
||||
EndpointInteractionResponseActions = func(aID, iToken string) string {
|
||||
return EndpointWebhookMessage(aID, iToken, "@original")
|
||||
}
|
||||
EndpointFollowupMessage = func(aID, iToken string) string {
|
||||
return EndpointWebhookToken(aID, iToken)
|
||||
}
|
||||
EndpointFollowupMessageActions = func(aID, iToken, mID string) string {
|
||||
return EndpointWebhookMessage(aID, iToken, mID)
|
||||
}
|
||||
|
||||
EndpointRelationships = func() string { return EndpointUsers + "@me" + "/relationships" }
|
||||
EndpointRelationship = func(uID string) string { return EndpointRelationships() + "/" + uID }
|
||||
EndpointRelationshipsMutual = func(uID string) string { return EndpointUsers + uID + "/relationships" }
|
||||
|
@ -146,9 +178,19 @@ var (
|
|||
EndpointEmoji = func(eID string) string { return EndpointCDN + "emojis/" + eID + ".png" }
|
||||
EndpointEmojiAnimated = func(eID string) string { return EndpointCDN + "emojis/" + eID + ".gif" }
|
||||
|
||||
EndpointOauth2 = EndpointAPI + "oauth2/"
|
||||
EndpointApplications = EndpointOauth2 + "applications"
|
||||
EndpointApplication = func(aID string) string { return EndpointApplications + "/" + aID }
|
||||
EndpointApplicationsBot = func(aID string) string { return EndpointApplications + "/" + aID + "/bot" }
|
||||
EndpointApplicationAssets = func(aID string) string { return EndpointApplications + "/" + aID + "/assets" }
|
||||
EndpointApplications = EndpointAPI + "applications"
|
||||
EndpointApplication = func(aID string) string { return EndpointApplications + "/" + aID }
|
||||
|
||||
EndpointOAuth2 = EndpointAPI + "oauth2/"
|
||||
EndpointOAuth2Applications = EndpointOAuth2 + "applications"
|
||||
EndpointOAuth2Application = func(aID string) string { return EndpointOAuth2Applications + "/" + aID }
|
||||
EndpointOAuth2ApplicationsBot = func(aID string) string { return EndpointOAuth2Applications + "/" + aID + "/bot" }
|
||||
EndpointOAuth2ApplicationAssets = func(aID string) string { return EndpointOAuth2Applications + "/" + aID + "/assets" }
|
||||
|
||||
// TODO: Deprecated, remove in the next release
|
||||
EndpointOauth2 = EndpointOAuth2
|
||||
EndpointOauth2Applications = EndpointOAuth2Applications
|
||||
EndpointOauth2Application = EndpointOAuth2Application
|
||||
EndpointOauth2ApplicationsBot = EndpointOAuth2ApplicationsBot
|
||||
EndpointOauth2ApplicationAssets = EndpointOAuth2ApplicationAssets
|
||||
)
|
||||
|
|
|
@ -28,6 +28,7 @@ const (
|
|||
guildRoleDeleteEventType = "GUILD_ROLE_DELETE"
|
||||
guildRoleUpdateEventType = "GUILD_ROLE_UPDATE"
|
||||
guildUpdateEventType = "GUILD_UPDATE"
|
||||
interactionCreateEventType = "INTERACTION_CREATE"
|
||||
messageAckEventType = "MESSAGE_ACK"
|
||||
messageCreateEventType = "MESSAGE_CREATE"
|
||||
messageDeleteEventType = "MESSAGE_DELETE"
|
||||
|
@ -458,6 +459,26 @@ func (eh guildUpdateEventHandler) Handle(s *Session, i interface{}) {
|
|||
}
|
||||
}
|
||||
|
||||
// interactionCreateEventHandler is an event handler for InteractionCreate events.
|
||||
type interactionCreateEventHandler func(*Session, *InteractionCreate)
|
||||
|
||||
// Type returns the event type for InteractionCreate events.
|
||||
func (eh interactionCreateEventHandler) Type() string {
|
||||
return interactionCreateEventType
|
||||
}
|
||||
|
||||
// New returns a new instance of InteractionCreate.
|
||||
func (eh interactionCreateEventHandler) New() interface{} {
|
||||
return &InteractionCreate{}
|
||||
}
|
||||
|
||||
// Handle is the handler for InteractionCreate events.
|
||||
func (eh interactionCreateEventHandler) Handle(s *Session, i interface{}) {
|
||||
if t, ok := i.(*InteractionCreate); ok {
|
||||
eh(s, t)
|
||||
}
|
||||
}
|
||||
|
||||
// messageAckEventHandler is an event handler for MessageAck events.
|
||||
type messageAckEventHandler func(*Session, *MessageAck)
|
||||
|
||||
|
@ -959,6 +980,8 @@ func handlerForInterface(handler interface{}) EventHandler {
|
|||
return guildRoleUpdateEventHandler(v)
|
||||
case func(*Session, *GuildUpdate):
|
||||
return guildUpdateEventHandler(v)
|
||||
case func(*Session, *InteractionCreate):
|
||||
return interactionCreateEventHandler(v)
|
||||
case func(*Session, *MessageAck):
|
||||
return messageAckEventHandler(v)
|
||||
case func(*Session, *MessageCreate):
|
||||
|
@ -1029,6 +1052,7 @@ func init() {
|
|||
registerInterfaceProvider(guildRoleDeleteEventHandler(nil))
|
||||
registerInterfaceProvider(guildRoleUpdateEventHandler(nil))
|
||||
registerInterfaceProvider(guildUpdateEventHandler(nil))
|
||||
registerInterfaceProvider(interactionCreateEventHandler(nil))
|
||||
registerInterfaceProvider(messageAckEventHandler(nil))
|
||||
registerInterfaceProvider(messageCreateEventHandler(nil))
|
||||
registerInterfaceProvider(messageDeleteEventHandler(nil))
|
||||
|
|
|
@ -267,3 +267,8 @@ type WebhooksUpdate struct {
|
|||
GuildID string `json:"guild_id"`
|
||||
ChannelID string `json:"channel_id"`
|
||||
}
|
||||
|
||||
// InteractionCreate is the data for a InteractionCreate event
|
||||
type InteractionCreate struct {
|
||||
*Interaction
|
||||
}
|
||||
|
|
375
examples/slash_commands/main.go
Normal file
375
examples/slash_commands/main.go
Normal file
|
@ -0,0 +1,375 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"time"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
)
|
||||
|
||||
// Bot parameters
|
||||
var (
|
||||
GuildID = flag.String("guild", "", "Test guild ID. If not passed - bot registers commands globally")
|
||||
BotToken = flag.String("token", "", "Bot access token")
|
||||
RemoveCommands = flag.Bool("rmcmd", true, "Remove all commands after shutdowning or not")
|
||||
)
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
commands = []*discordgo.ApplicationCommand{
|
||||
{
|
||||
Name: "basic-command",
|
||||
// All commands and options must have an description
|
||||
// Commands/options without description will fail the registration
|
||||
// of the command.
|
||||
Description: "Basic command",
|
||||
},
|
||||
{
|
||||
Name: "options",
|
||||
Description: "Command for demonstrating options",
|
||||
Options: []*discordgo.ApplicationCommandOption{
|
||||
|
||||
{
|
||||
Type: discordgo.ApplicationCommandOptionString,
|
||||
Name: "string-option",
|
||||
Description: "String option",
|
||||
Required: true,
|
||||
},
|
||||
{
|
||||
Type: discordgo.ApplicationCommandOptionInteger,
|
||||
Name: "integer-option",
|
||||
Description: "Integer option",
|
||||
Required: true,
|
||||
},
|
||||
{
|
||||
Type: discordgo.ApplicationCommandOptionBoolean,
|
||||
Name: "bool-option",
|
||||
Description: "Boolean option",
|
||||
Required: true,
|
||||
},
|
||||
|
||||
// Required options must be listed first, because
|
||||
// like everyone knows - optional parameters is on the back.
|
||||
// The same concept applies to Discord's Slash-commands API
|
||||
|
||||
{
|
||||
Type: discordgo.ApplicationCommandOptionChannel,
|
||||
Name: "channel-option",
|
||||
Description: "Channel option",
|
||||
Required: false,
|
||||
},
|
||||
{
|
||||
Type: discordgo.ApplicationCommandOptionUser,
|
||||
Name: "user-option",
|
||||
Description: "User option",
|
||||
Required: false,
|
||||
},
|
||||
{
|
||||
Type: discordgo.ApplicationCommandOptionRole,
|
||||
Name: "role-option",
|
||||
Description: "Role option",
|
||||
Required: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "subcommands",
|
||||
Description: "Subcommands and command groups example",
|
||||
Options: []*discordgo.ApplicationCommandOption{
|
||||
// When command have subcommands/subcommand groups
|
||||
// It must not have top-level options, they aren't accesible in the UI
|
||||
// in this case (at least, yet), so if command is with
|
||||
// subcommands/subcommand groups registering top-level options
|
||||
// will fail the registration of the command
|
||||
|
||||
{
|
||||
Name: "scmd-grp",
|
||||
Description: "Subcommands group",
|
||||
Options: []*discordgo.ApplicationCommandOption{
|
||||
// Also, subcommand groups isn't capable of
|
||||
// containg options, by the name of them, you can see
|
||||
// they can contain only subcommands
|
||||
{
|
||||
Name: "nst-subcmd",
|
||||
Description: "Nested subcommand",
|
||||
Type: discordgo.ApplicationCommandOptionSubCommand,
|
||||
},
|
||||
},
|
||||
Type: discordgo.ApplicationCommandOptionSubCommandGroup,
|
||||
},
|
||||
// Also, you can create both subcommand groups and subcommands
|
||||
// in the command at the same time. But, there's some limits to
|
||||
// nesting, count of subcommands (top level and nested) and options.
|
||||
// Read the intro of slash-commands docs on Discord dev portal
|
||||
// to get more information
|
||||
{
|
||||
Name: "subcmd",
|
||||
Description: "Top-level subcommand",
|
||||
Type: discordgo.ApplicationCommandOptionSubCommand,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "responses",
|
||||
Description: "Interaction responses testing initiative",
|
||||
Options: []*discordgo.ApplicationCommandOption{
|
||||
{
|
||||
Name: "resp-type",
|
||||
Description: "Response type",
|
||||
Type: discordgo.ApplicationCommandOptionInteger,
|
||||
Choices: []*discordgo.ApplicationCommandOptionChoice{
|
||||
{
|
||||
Name: "Acknowledge",
|
||||
Value: 2,
|
||||
},
|
||||
{
|
||||
Name: "Channel message",
|
||||
Value: 3,
|
||||
},
|
||||
{
|
||||
Name: "Channel message with source",
|
||||
Value: 4,
|
||||
},
|
||||
{
|
||||
Name: "Acknowledge with source",
|
||||
Value: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "followups",
|
||||
Description: "Followup messages",
|
||||
},
|
||||
}
|
||||
commandHandlers = map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate){
|
||||
"basic-command": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionApplicationCommandResponseData{
|
||||
Content: "Hey there! Congratulations, you just executed your first slash command",
|
||||
},
|
||||
})
|
||||
},
|
||||
"options": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
margs := []interface{}{
|
||||
// Here we need to convert raw interface{} value to wanted type.
|
||||
// Also, as you can see, here is used utility functions to convert the value
|
||||
// to particular type. Yeah, you can use just switch type,
|
||||
// but this is much simpler
|
||||
i.Data.Options[0].StringValue(),
|
||||
i.Data.Options[1].IntValue(),
|
||||
i.Data.Options[2].BoolValue(),
|
||||
}
|
||||
msgformat :=
|
||||
` Now you just leared how to use command options. Take a look to the value of which you've just entered:
|
||||
> string_option: %s
|
||||
> integer_option: %d
|
||||
> bool_option: %v
|
||||
`
|
||||
if len(i.Data.Options) >= 4 {
|
||||
margs = append(margs, i.Data.Options[3].ChannelValue(nil).ID)
|
||||
msgformat += "> channel-option: <#%s>\n"
|
||||
}
|
||||
if len(i.Data.Options) >= 5 {
|
||||
margs = append(margs, i.Data.Options[4].UserValue(nil).ID)
|
||||
msgformat += "> user-option: <@%s>\n"
|
||||
}
|
||||
if len(i.Data.Options) >= 6 {
|
||||
margs = append(margs, i.Data.Options[5].RoleValue(nil, "").ID)
|
||||
msgformat += "> role-option: <@&%s>\n"
|
||||
}
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
// Ignore type for now, we'll discuss them in "responses" part
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionApplicationCommandResponseData{
|
||||
Content: fmt.Sprintf(
|
||||
msgformat,
|
||||
margs...,
|
||||
),
|
||||
},
|
||||
})
|
||||
},
|
||||
"subcommands": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
content := ""
|
||||
|
||||
// As you can see, the name of subcommand (nested, top-level) or subcommand group
|
||||
// is provided through arguments.
|
||||
switch i.Data.Options[0].Name {
|
||||
case "subcmd":
|
||||
content =
|
||||
"The top-level subcommand is executed. Now try to execute nested one."
|
||||
default:
|
||||
if i.Data.Options[0].Name != "scmd-grp" {
|
||||
return
|
||||
}
|
||||
switch i.Data.Options[0].Options[0].Name {
|
||||
case "nst-subcmd":
|
||||
content = "Nice, now you know how to execute nested commands too"
|
||||
default:
|
||||
// I added this in the case something might go wrong
|
||||
content = "Oops, something gone wrong.\n" +
|
||||
"Hol' up, you aren't supposed to see this message."
|
||||
}
|
||||
}
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionApplicationCommandResponseData{
|
||||
Content: content,
|
||||
},
|
||||
})
|
||||
},
|
||||
"responses": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
// Responses to a command is really important thing.
|
||||
// First of all, because you need to react to the interaction
|
||||
// by sending the response in 3 seconds after receiving, otherwise
|
||||
// interaction will be considered invalid and you can no longer
|
||||
// use interaction token and ID for responding to the user's request
|
||||
|
||||
content := ""
|
||||
// As you can see, response type names saying by themselvs
|
||||
// how they're used, but for those who want to get
|
||||
// more information - read the official documentation
|
||||
switch i.Data.Options[0].IntValue() {
|
||||
case int64(discordgo.InteractionResponseChannelMessage):
|
||||
content =
|
||||
"Well, you just responded to an interaction, and sent a message.\n" +
|
||||
"That's all what I wanted to say, yeah."
|
||||
content +=
|
||||
"\nAlso... you can edit your response, wait 5 seconds and this message will be changed"
|
||||
case int64(discordgo.InteractionResponseChannelMessageWithSource):
|
||||
content =
|
||||
"You just responded to an interaction, sent a message and showed the original one. " +
|
||||
"Congratulations!"
|
||||
content +=
|
||||
"\nAlso... you can edit your response, wait 5 seconds and this message will be changed"
|
||||
default:
|
||||
err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseType(i.Data.Options[0].IntValue()),
|
||||
})
|
||||
if err != nil {
|
||||
s.FollowupMessageCreate("", i.Interaction, true, &discordgo.WebhookParams{
|
||||
Content: "Something gone wrong",
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseType(i.Data.Options[0].IntValue()),
|
||||
Data: &discordgo.InteractionApplicationCommandResponseData{
|
||||
Content: content,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
s.FollowupMessageCreate("", i.Interaction, true, &discordgo.WebhookParams{
|
||||
Content: "Something gone wrong",
|
||||
})
|
||||
return
|
||||
}
|
||||
time.AfterFunc(time.Second*5, func() {
|
||||
err = s.InteractionResponseEdit("", i.Interaction, &discordgo.WebhookEdit{
|
||||
Content: content + "\n\nWell, now you know how to create and edit responses. " +
|
||||
"But you still don't know how to delete them... so... wait 10 seconds and this " +
|
||||
"message will be deleted.",
|
||||
})
|
||||
if err != nil {
|
||||
s.FollowupMessageCreate("", i.Interaction, true, &discordgo.WebhookParams{
|
||||
Content: "Something gone wrong",
|
||||
})
|
||||
return
|
||||
}
|
||||
time.Sleep(time.Second * 10)
|
||||
s.InteractionResponseDelete("", i.Interaction)
|
||||
})
|
||||
},
|
||||
"followups": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
// Followup messages is basically regular messages (you can create as many of them as you wish),
|
||||
// but working as they is created by webhooks and their functional
|
||||
// is for handling additional messages after sending response.
|
||||
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionApplicationCommandResponseData{
|
||||
// Note: this isn't documented, but you can use that if you want to.
|
||||
// This flag just allows to create messages visible only for the caller (user who triggered the command)
|
||||
// of the command
|
||||
Flags: 1 << 6,
|
||||
Content: "Surprise!",
|
||||
},
|
||||
})
|
||||
msg, err := s.FollowupMessageCreate("", i.Interaction, true, &discordgo.WebhookParams{
|
||||
Content: "Followup message has created, after 5 seconds it will be edited",
|
||||
})
|
||||
if err != nil {
|
||||
s.FollowupMessageCreate("", i.Interaction, true, &discordgo.WebhookParams{
|
||||
Content: "Something gone wrong",
|
||||
})
|
||||
return
|
||||
}
|
||||
time.Sleep(time.Second * 5)
|
||||
|
||||
s.FollowupMessageEdit("", i.Interaction, msg.ID, &discordgo.WebhookEdit{
|
||||
Content: "Now original message is gone and after 10 seconds this message will ~~self-destruct~~ be deleted.",
|
||||
})
|
||||
|
||||
time.Sleep(time.Second * 10)
|
||||
|
||||
s.FollowupMessageDelete("", i.Interaction, msg.ID)
|
||||
|
||||
s.FollowupMessageCreate("", i.Interaction, true, &discordgo.WebhookParams{
|
||||
Content: "For those, who didn't skip anything and followed tutorial along fairly, " +
|
||||
"take a unicorn :unicorn: as reward!\n" +
|
||||
"Also, as bonus..., look at the original interaction response :D",
|
||||
})
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
s.AddHandler(func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
if h, ok := commandHandlers[i.Data.Name]; ok {
|
||||
h(s, i)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func main() {
|
||||
s.AddHandler(func(s *discordgo.Session, r *discordgo.Ready) {
|
||||
log.Println("Bot is up!")
|
||||
})
|
||||
err := s.Open()
|
||||
if err != nil {
|
||||
log.Fatalf("Cannot open the session: %v", err)
|
||||
}
|
||||
|
||||
for _, v := range commands {
|
||||
_, err := s.ApplicationCommandCreate("", *GuildID, v)
|
||||
if err != nil {
|
||||
log.Panicf("Cannot create '%v' command: %v", v.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
defer s.Close()
|
||||
|
||||
stop := make(chan os.Signal)
|
||||
signal.Notify(stop, os.Interrupt)
|
||||
<-stop
|
||||
log.Println("Gracefully shutdowning")
|
||||
}
|
237
interactions.go
237
interactions.go
|
@ -7,8 +7,245 @@ import (
|
|||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// InteractionDeadline is the time allowed to respond to an interaction.
|
||||
const InteractionDeadline = time.Second * 3
|
||||
|
||||
// ApplicationCommand represents an application's slash command.
|
||||
type ApplicationCommand struct {
|
||||
ID string `json:"id"`
|
||||
ApplicationID string `json:"application_id,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
Options []*ApplicationCommandOption `json:"options"`
|
||||
}
|
||||
|
||||
// ApplicationCommandOptionType indicates the type of a slash command's option.
|
||||
type ApplicationCommandOptionType uint8
|
||||
|
||||
// Application command option types.
|
||||
const (
|
||||
ApplicationCommandOptionSubCommand = ApplicationCommandOptionType(iota + 1)
|
||||
ApplicationCommandOptionSubCommandGroup
|
||||
ApplicationCommandOptionString
|
||||
ApplicationCommandOptionInteger
|
||||
ApplicationCommandOptionBoolean
|
||||
ApplicationCommandOptionUser
|
||||
ApplicationCommandOptionChannel
|
||||
ApplicationCommandOptionRole
|
||||
)
|
||||
|
||||
// ApplicationCommandOption represents an option/subcommand/subcommands group.
|
||||
type ApplicationCommandOption struct {
|
||||
Type ApplicationCommandOptionType `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description,omitempty"`
|
||||
// NOTE: This feature was on the API, but at some point developers decided to remove it.
|
||||
// So I commented it, until it will be officially on the docs.
|
||||
// Default bool `json:"default"`
|
||||
Required bool `json:"required"`
|
||||
Choices []*ApplicationCommandOptionChoice `json:"choices"`
|
||||
Options []*ApplicationCommandOption `json:"options"`
|
||||
}
|
||||
|
||||
// ApplicationCommandOptionChoice represents a slash command option choice.
|
||||
type ApplicationCommandOptionChoice struct {
|
||||
Name string `json:"name"`
|
||||
Value interface{} `json:"value"`
|
||||
}
|
||||
|
||||
// InteractionType indicates the type of an interaction event.
|
||||
type InteractionType uint8
|
||||
|
||||
// Interaction types
|
||||
const (
|
||||
InteractionPing = InteractionType(iota + 1)
|
||||
InteractionApplicationCommand
|
||||
)
|
||||
|
||||
// Interaction represents an interaction event created via a slash command.
|
||||
type Interaction struct {
|
||||
ID string `json:"id"`
|
||||
Type InteractionType `json:"type"`
|
||||
Data ApplicationCommandInteractionData `json:"data"`
|
||||
GuildID string `json:"guild_id"`
|
||||
ChannelID string `json:"channel_id"`
|
||||
Member *Member `json:"member"`
|
||||
Token string `json:"token"`
|
||||
Version int `json:"version"`
|
||||
}
|
||||
|
||||
// ApplicationCommandInteractionData contains data received in an interaction event.
|
||||
type ApplicationCommandInteractionData struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Options []*ApplicationCommandInteractionDataOption `json:"options"`
|
||||
}
|
||||
|
||||
// ApplicationCommandInteractionDataOption represents an option of a slash command.
|
||||
type ApplicationCommandInteractionDataOption struct {
|
||||
Name string `json:"name"`
|
||||
// NOTE: Contains the value specified by InteractionType.
|
||||
Value interface{} `json:"value,omitempty"`
|
||||
Options []*ApplicationCommandInteractionDataOption `json:"options,omitempty"`
|
||||
}
|
||||
|
||||
// IntValue is a utility function for casting option value to integer
|
||||
func (o ApplicationCommandInteractionDataOption) IntValue() int64 {
|
||||
if v, ok := o.Value.(float64); ok {
|
||||
return int64(v)
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// UintValue is a utility function for casting option value to unsigned integer
|
||||
func (o ApplicationCommandInteractionDataOption) UintValue() uint64 {
|
||||
if v, ok := o.Value.(float64); ok {
|
||||
return uint64(v)
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// FloatValue is a utility function for casting option value to float
|
||||
func (o ApplicationCommandInteractionDataOption) FloatValue() float64 {
|
||||
if v, ok := o.Value.(float64); ok {
|
||||
return v
|
||||
}
|
||||
|
||||
return 0.0
|
||||
}
|
||||
|
||||
// StringValue is a utility function for casting option value to string
|
||||
func (o ApplicationCommandInteractionDataOption) StringValue() string {
|
||||
if v, ok := o.Value.(string); ok {
|
||||
return v
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// BoolValue is a utility function for casting option value to bool
|
||||
func (o ApplicationCommandInteractionDataOption) BoolValue() bool {
|
||||
if v, ok := o.Value.(bool); ok {
|
||||
return v
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// ChannelValue is a utility function for casting option value to channel object.
|
||||
// s : Session object, if not nil, function additionaly fetches all channel's data
|
||||
func (o ApplicationCommandInteractionDataOption) ChannelValue(s *Session) *Channel {
|
||||
chanID := o.StringValue()
|
||||
if chanID == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if s == nil {
|
||||
return &Channel{ID: chanID}
|
||||
}
|
||||
|
||||
ch, err := s.State.Channel(chanID)
|
||||
if err != nil {
|
||||
ch, err = s.Channel(chanID)
|
||||
if err != nil {
|
||||
return &Channel{ID: chanID}
|
||||
}
|
||||
}
|
||||
|
||||
return ch
|
||||
}
|
||||
|
||||
// RoleValue is a utility function for casting option value to role object.
|
||||
// s : Session object, if not nil, function additionaly fetches all role's data
|
||||
func (o ApplicationCommandInteractionDataOption) RoleValue(s *Session, gID string) *Role {
|
||||
roleID := o.StringValue()
|
||||
if roleID == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if s == nil || gID == "" {
|
||||
return &Role{ID: roleID}
|
||||
}
|
||||
|
||||
r, err := s.State.Role(roleID, gID)
|
||||
if err != nil {
|
||||
roles, err := s.GuildRoles(gID)
|
||||
if err == nil {
|
||||
for _, r = range roles {
|
||||
if r.ID == roleID {
|
||||
return r
|
||||
}
|
||||
}
|
||||
}
|
||||
return &Role{ID: roleID}
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// UserValue is a utility function for casting option value to user object.
|
||||
// s : Session object, if not nil, function additionaly fetches all user's data
|
||||
func (o ApplicationCommandInteractionDataOption) UserValue(s *Session) *User {
|
||||
userID := o.StringValue()
|
||||
if userID == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if s == nil {
|
||||
return &User{ID: userID}
|
||||
}
|
||||
|
||||
u, err := s.User(userID)
|
||||
if err != nil {
|
||||
return &User{ID: userID}
|
||||
}
|
||||
|
||||
return u
|
||||
}
|
||||
|
||||
// InteractionResponseType is type of interaction response.
|
||||
type InteractionResponseType uint8
|
||||
|
||||
// Interaction response types.
|
||||
const (
|
||||
// InteractionResponsePong is for ACK ping event.
|
||||
InteractionResponsePong = InteractionResponseType(iota + 1)
|
||||
// InteractionResponseAcknowledge is for ACK a command without sending a message, eating the user's input.
|
||||
// NOTE: this type is being imminently deprecated, and **will be removed when this occurs.**
|
||||
InteractionResponseAcknowledge
|
||||
// InteractionResponseChannelMessage is for responding with a message, eating the user's input.
|
||||
// NOTE: this type is being imminently deprecated, and **will be removed when this occurs.**
|
||||
InteractionResponseChannelMessage
|
||||
// InteractionResponseChannelMessageWithSource is for responding with a message, showing the user's input.
|
||||
InteractionResponseChannelMessageWithSource
|
||||
// InteractionResponseDeferredChannelMessageWithSource acknowledges that the event was received, and that a follow-up will come later.
|
||||
// It was previously named InteractionResponseACKWithSource.
|
||||
InteractionResponseDeferredChannelMessageWithSource
|
||||
)
|
||||
|
||||
// InteractionResponse represents a response for an interaction event.
|
||||
type InteractionResponse struct {
|
||||
Type InteractionResponseType `json:"type,omitempty"`
|
||||
Data *InteractionApplicationCommandResponseData `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
// InteractionApplicationCommandResponseData is response data for a slash command interaction.
|
||||
type InteractionApplicationCommandResponseData struct {
|
||||
TTS bool `json:"tts,omitempty"`
|
||||
Content string `json:"content,omitempty"`
|
||||
Embeds []*MessageEmbed `json:"embeds,omitempty"`
|
||||
AllowedMentions *MessageAllowedMentions `json:"allowed_mentions,omitempty"`
|
||||
|
||||
// NOTE: Undocumented feature, be careful with it.
|
||||
Flags uint64 `json:"flags,omitempty"`
|
||||
}
|
||||
|
||||
// VerifyInteraction implements message verification of the discord interactions api
|
||||
// signing algorithm, as documented here:
|
||||
// https://discord.com/developers/docs/interactions/slash-commands#security-and-authorization
|
||||
|
|
14
oauth2.go
14
oauth2.go
|
@ -61,7 +61,7 @@ type Application struct {
|
|||
// appID : The ID of an Application
|
||||
func (s *Session) Application(appID string) (st *Application, err error) {
|
||||
|
||||
body, err := s.RequestWithBucketID("GET", EndpointApplication(appID), nil, EndpointApplication(""))
|
||||
body, err := s.RequestWithBucketID("GET", EndpointOAuth2Application(appID), nil, EndpointOAuth2Application(""))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ func (s *Session) Application(appID string) (st *Application, err error) {
|
|||
// Applications returns all applications for the authenticated user
|
||||
func (s *Session) Applications() (st []*Application, err error) {
|
||||
|
||||
body, err := s.RequestWithBucketID("GET", EndpointApplications, nil, EndpointApplications)
|
||||
body, err := s.RequestWithBucketID("GET", EndpointOAuth2Applications, nil, EndpointOAuth2Applications)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ func (s *Session) ApplicationCreate(ap *Application) (st *Application, err error
|
|||
RedirectURIs *[]string `json:"redirect_uris,omitempty"`
|
||||
}{ap.Name, ap.Description, ap.RedirectURIs}
|
||||
|
||||
body, err := s.RequestWithBucketID("POST", EndpointApplications, data, EndpointApplications)
|
||||
body, err := s.RequestWithBucketID("POST", EndpointOAuth2Applications, data, EndpointOAuth2Applications)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ func (s *Session) ApplicationUpdate(appID string, ap *Application) (st *Applicat
|
|||
RedirectURIs *[]string `json:"redirect_uris,omitempty"`
|
||||
}{ap.Name, ap.Description, ap.RedirectURIs}
|
||||
|
||||
body, err := s.RequestWithBucketID("PUT", EndpointApplication(appID), data, EndpointApplication(""))
|
||||
body, err := s.RequestWithBucketID("PUT", EndpointOAuth2Application(appID), data, EndpointOAuth2Application(""))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ func (s *Session) ApplicationUpdate(appID string, ap *Application) (st *Applicat
|
|||
// appID : The ID of an Application
|
||||
func (s *Session) ApplicationDelete(appID string) (err error) {
|
||||
|
||||
_, err = s.RequestWithBucketID("DELETE", EndpointApplication(appID), nil, EndpointApplication(""))
|
||||
_, err = s.RequestWithBucketID("DELETE", EndpointOAuth2Application(appID), nil, EndpointOAuth2Application(""))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ type Asset struct {
|
|||
// ApplicationAssets returns an application's assets
|
||||
func (s *Session) ApplicationAssets(appID string) (ass []*Asset, err error) {
|
||||
|
||||
body, err := s.RequestWithBucketID("GET", EndpointApplicationAssets(appID), nil, EndpointApplicationAssets(""))
|
||||
body, err := s.RequestWithBucketID("GET", EndpointOAuth2ApplicationAssets(appID), nil, EndpointOAuth2ApplicationAssets(""))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ func (s *Session) ApplicationAssets(appID string) (ass []*Asset, err error) {
|
|||
// NOTE: func name may change, if I can think up something better.
|
||||
func (s *Session) ApplicationBotCreate(appID string) (st *User, err error) {
|
||||
|
||||
body, err := s.RequestWithBucketID("POST", EndpointApplicationsBot(appID), nil, EndpointApplicationsBot(""))
|
||||
body, err := s.RequestWithBucketID("POST", EndpointOAuth2ApplicationsBot(appID), nil, EndpointOAuth2ApplicationsBot(""))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ func NewRatelimiter() *RateLimiter {
|
|||
buckets: make(map[string]*Bucket),
|
||||
global: new(int64),
|
||||
customRateLimits: []*customRateLimit{
|
||||
&customRateLimit{
|
||||
{
|
||||
suffix: "//reactions//",
|
||||
requests: 1,
|
||||
reset: 200 * time.Millisecond,
|
||||
|
|
178
restapi.go
178
restapi.go
|
@ -2180,7 +2180,29 @@ func (s *Session) WebhookExecute(webhookID, token string, wait bool, data *Webho
|
|||
}
|
||||
|
||||
err = unmarshal(response, &st)
|
||||
return
|
||||
}
|
||||
|
||||
// WebhookMessageEdit edits a webhook message.
|
||||
// webhookID : The ID of a webhook
|
||||
// token : The auth token for the webhook
|
||||
// messageID : The ID of message to edit
|
||||
func (s *Session) WebhookMessageEdit(webhookID, token, messageID string, data *WebhookEdit) (err error) {
|
||||
uri := EndpointWebhookMessage(webhookID, token, messageID)
|
||||
|
||||
_, err = s.RequestWithBucketID("PATCH", uri, data, EndpointWebhookToken("", ""))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// WebhookMessageDelete deletes a webhook message.
|
||||
// webhookID : The ID of a webhook
|
||||
// token : The auth token for the webhook
|
||||
// messageID : The ID of message to edit
|
||||
func (s *Session) WebhookMessageDelete(webhookID, token, messageID string) (err error) {
|
||||
uri := EndpointWebhookMessage(webhookID, token, messageID)
|
||||
|
||||
_, err = s.RequestWithBucketID("DELETE", uri, nil, EndpointWebhookToken("", ""))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -2351,3 +2373,159 @@ func (s *Session) RelationshipsMutualGet(userID string) (mf []*User, err error)
|
|||
err = unmarshal(body, &mf)
|
||||
return
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Functions specific to application (slash) commands
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
// ApplicationCommandCreate creates a global application command and returns it.
|
||||
// appID : The application ID.
|
||||
// guildID : Guild ID to create guild-specific application command. If empty - creates global application command.
|
||||
// cmd : New application command data.
|
||||
func (s *Session) ApplicationCommandCreate(appID string, guildID string, cmd *ApplicationCommand) (ccmd *ApplicationCommand, err error) {
|
||||
endpoint := EndpointApplicationGlobalCommands(appID)
|
||||
if guildID != "" {
|
||||
endpoint = EndpointApplicationGuildCommands(appID, guildID)
|
||||
}
|
||||
|
||||
body, err := s.RequestWithBucketID("POST", endpoint, *cmd, endpoint)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = unmarshal(body, &ccmd)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ApplicationCommandEdit edits application command and returns new command data.
|
||||
// appID : The application ID.
|
||||
// cmdID : Application command ID to edit.
|
||||
// guildID : Guild ID to edit guild-specific application command. If empty - edits global application command.
|
||||
// cmd : Updated application command data.
|
||||
func (s *Session) ApplicationCommandEdit(appID, guildID, cmdID string, cmd *ApplicationCommand) (updated *ApplicationCommand, err error) {
|
||||
endpoint := EndpointApplicationGlobalCommand(appID, cmdID)
|
||||
if guildID != "" {
|
||||
endpoint = EndpointApplicationGuildCommand(appID, guildID, cmdID)
|
||||
}
|
||||
|
||||
body, err := s.RequestWithBucketID("PATCH", endpoint, *cmd, endpoint)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = unmarshal(body, &updated)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ApplicationCommandDelete deletes application command by ID.
|
||||
// appID : The application ID.
|
||||
// cmdID : Application command ID to delete.
|
||||
// guildID : Guild ID to delete guild-specific application command. If empty - deletes global application command.
|
||||
func (s *Session) ApplicationCommandDelete(appID, guildID, cmdID string) error {
|
||||
endpoint := EndpointApplicationGlobalCommand(appID, cmdID)
|
||||
if guildID != "" {
|
||||
endpoint = EndpointApplicationGuildCommand(appID, guildID, cmdID)
|
||||
}
|
||||
|
||||
_, err := s.RequestWithBucketID("DELETE", endpoint, nil, endpoint)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// ApplicationCommand retrieves an application command by given ID.
|
||||
// appID : The application ID.
|
||||
// cmdID : Application command ID.
|
||||
// guildID : Guild ID to retrieve guild-specific application command. If empty - retrieves global application command.
|
||||
func (s *Session) ApplicationCommand(appID, guildID, cmdID string) (cmd *ApplicationCommand, err error) {
|
||||
endpoint := EndpointApplicationGlobalCommand(appID, cmdID)
|
||||
if guildID != "" {
|
||||
endpoint = EndpointApplicationGuildCommand(appID, guildID, cmdID)
|
||||
}
|
||||
|
||||
body, err := s.RequestWithBucketID("GET", endpoint, nil, endpoint)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = unmarshal(body, &cmd)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ApplicationCommands retrieves all commands in application.
|
||||
// appID : The application ID.
|
||||
// guildID : Guild ID to retrieve all guild-specific application commands. If empty - retrieves global application commands.
|
||||
func (s *Session) ApplicationCommands(appID, guildID string) (cmd []*ApplicationCommand, err error) {
|
||||
endpoint := EndpointApplicationGlobalCommands(appID)
|
||||
if guildID != "" {
|
||||
endpoint = EndpointApplicationGuildCommands(appID, guildID)
|
||||
}
|
||||
|
||||
body, err := s.RequestWithBucketID("GET", endpoint, nil, endpoint)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = unmarshal(body, &cmd)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// InteractionRespond creates the response to an interaction.
|
||||
// appID : The application ID.
|
||||
// interaction : Interaction instance.
|
||||
// resp : Response message data.
|
||||
func (s *Session) InteractionRespond(interaction *Interaction, resp *InteractionResponse) error {
|
||||
endpoint := EndpointInteractionResponse(interaction.ID, interaction.Token)
|
||||
|
||||
_, err := s.RequestWithBucketID("POST", endpoint, *resp, endpoint)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// InteractionResponseEdit edits the response to an interaction.
|
||||
// appID : The application ID.
|
||||
// interaction : Interaction instance.
|
||||
// newresp : Updated response message data.
|
||||
func (s *Session) InteractionResponseEdit(appID string, interaction *Interaction, newresp *WebhookEdit) error {
|
||||
return s.WebhookMessageEdit(appID, interaction.Token, "@original", newresp)
|
||||
}
|
||||
|
||||
// InteractionResponseDelete deletes the response to an interaction.
|
||||
// appID : The application ID.
|
||||
// interaction : Interaction instance.
|
||||
func (s *Session) InteractionResponseDelete(appID string, interaction *Interaction) error {
|
||||
endpoint := EndpointInteractionResponseActions(appID, interaction.Token)
|
||||
|
||||
_, err := s.RequestWithBucketID("DELETE", endpoint, nil, endpoint)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// FollowupMessageCreate creates the followup message for an interaction.
|
||||
// appID : The application ID.
|
||||
// interaction : Interaction instance.
|
||||
// wait : Waits for server confirmation of message send and ensures that the return struct is populated (it is nil otherwise)
|
||||
// data : Data of the message to send.
|
||||
func (s *Session) FollowupMessageCreate(appID string, interaction *Interaction, wait bool, data *WebhookParams) (*Message, error) {
|
||||
return s.WebhookExecute(appID, interaction.Token, wait, data)
|
||||
}
|
||||
|
||||
// FollowupMessageEdit edits a followup message of an interaction.
|
||||
// appID : The application ID.
|
||||
// interaction : Interaction instance.
|
||||
// messageID : The followup message ID.
|
||||
// data : Data to update the message
|
||||
func (s *Session) FollowupMessageEdit(appID string, interaction *Interaction, messageID string, data *WebhookEdit) error {
|
||||
return s.WebhookMessageEdit(appID, interaction.Token, messageID, data)
|
||||
}
|
||||
|
||||
// FollowupMessageDelete deletes a followup message of an interaction.
|
||||
// appID : The application ID.
|
||||
// interaction : Interaction instance.
|
||||
// messageID : The followup message ID.
|
||||
func (s *Session) FollowupMessageDelete(appID string, interaction *Interaction, messageID string) error {
|
||||
return s.WebhookMessageDelete(appID, interaction.Token, messageID)
|
||||
}
|
||||
|
|
36
structs.go
36
structs.go
|
@ -1087,42 +1087,6 @@ type APIErrorMessage struct {
|
|||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// Webhook stores the data for a webhook.
|
||||
type Webhook struct {
|
||||
ID string `json:"id"`
|
||||
Type WebhookType `json:"type"`
|
||||
GuildID string `json:"guild_id"`
|
||||
ChannelID string `json:"channel_id"`
|
||||
User *User `json:"user"`
|
||||
Name string `json:"name"`
|
||||
Avatar string `json:"avatar"`
|
||||
Token string `json:"token"`
|
||||
|
||||
// ApplicationID is the bot/OAuth2 application that created this webhook
|
||||
ApplicationID string `json:"application_id,omitempty"`
|
||||
}
|
||||
|
||||
// WebhookType is the type of Webhook (see WebhookType* consts) in the Webhook struct
|
||||
// https://discord.com/developers/docs/resources/webhook#webhook-object-webhook-types
|
||||
type WebhookType int
|
||||
|
||||
// Valid WebhookType values
|
||||
const (
|
||||
WebhookTypeIncoming WebhookType = iota
|
||||
WebhookTypeChannelFollower
|
||||
)
|
||||
|
||||
// WebhookParams is a struct for webhook params, used in the WebhookExecute command.
|
||||
type WebhookParams struct {
|
||||
Content string `json:"content,omitempty"`
|
||||
Username string `json:"username,omitempty"`
|
||||
AvatarURL string `json:"avatar_url,omitempty"`
|
||||
TTS bool `json:"tts,omitempty"`
|
||||
File string `json:"file,omitempty"`
|
||||
Embeds []*MessageEmbed `json:"embeds,omitempty"`
|
||||
AllowedMentions *MessageAllowedMentions `json:"allowed_mentions,omitempty"`
|
||||
}
|
||||
|
||||
// MessageReaction stores the data for a message reaction.
|
||||
type MessageReaction struct {
|
||||
UserID string `json:"user_id"`
|
||||
|
|
44
webhook.go
Normal file
44
webhook.go
Normal file
|
@ -0,0 +1,44 @@
|
|||
package discordgo
|
||||
|
||||
// Webhook stores the data for a webhook.
|
||||
type Webhook struct {
|
||||
ID string `json:"id"`
|
||||
Type WebhookType `json:"type"`
|
||||
GuildID string `json:"guild_id"`
|
||||
ChannelID string `json:"channel_id"`
|
||||
User *User `json:"user"`
|
||||
Name string `json:"name"`
|
||||
Avatar string `json:"avatar"`
|
||||
Token string `json:"token"`
|
||||
|
||||
// ApplicationID is the bot/OAuth2 application that created this webhook
|
||||
ApplicationID string `json:"application_id,omitempty"`
|
||||
}
|
||||
|
||||
// WebhookType is the type of Webhook (see WebhookType* consts) in the Webhook struct
|
||||
// https://discord.com/developers/docs/resources/webhook#webhook-object-webhook-types
|
||||
type WebhookType int
|
||||
|
||||
// Valid WebhookType values
|
||||
const (
|
||||
WebhookTypeIncoming WebhookType = iota
|
||||
WebhookTypeChannelFollower
|
||||
)
|
||||
|
||||
// WebhookParams is a struct for webhook params, used in the WebhookExecute command.
|
||||
type WebhookParams struct {
|
||||
Content string `json:"content,omitempty"`
|
||||
Username string `json:"username,omitempty"`
|
||||
AvatarURL string `json:"avatar_url,omitempty"`
|
||||
TTS bool `json:"tts,omitempty"`
|
||||
File string `json:"file,omitempty"`
|
||||
Embeds []*MessageEmbed `json:"embeds,omitempty"`
|
||||
AllowedMentions *MessageAllowedMentions `json:"allowed_mentions,omitempty"`
|
||||
}
|
||||
|
||||
// WebhookEdit stores data for editing of a webhook message.
|
||||
type WebhookEdit struct {
|
||||
Content string `json:"content,omitempty"`
|
||||
Embeds []*MessageEmbed `json:"embeds,omitempty"`
|
||||
AllowedMentions *MessageAllowedMentions `json:"allowed_mentions,omitempty"`
|
||||
}
|
Loading…
Reference in a new issue