diff --git a/endpoints.go b/endpoints.go index 682433d..c79cfe6 100644 --- a/endpoints.go +++ b/endpoints.go @@ -24,6 +24,7 @@ var ( EndpointChannels = EndpointAPI + "channels/" EndpointUsers = EndpointAPI + "users/" EndpointGateway = EndpointAPI + "gateway" + EndpointWebhooks = EndpointAPI + "webhooks/" EndpointAuth = EndpointAPI + "auth/" EndpointLogin = EndpointAuth + "login" @@ -73,6 +74,7 @@ var ( EndpointGuildPrune = func(gID string) string { return EndpointGuilds + gID + "/prune" } EndpointGuildIcon = func(gID, hash string) string { return EndpointGuilds + gID + "/icons/" + hash + ".jpg" } EndpointGuildSplash = func(gID, hash string) string { return EndpointGuilds + gID + "/splashes/" + hash + ".jpg" } + EndpointGuildWebhooks = func(gID string) string { return EndpointGuilds + gID + "/webhooks" } EndpointChannel = func(cID string) string { return EndpointChannels + cID } EndpointChannelPermissions = func(cID string) string { return EndpointChannels + cID + "/permissions" } @@ -85,6 +87,10 @@ var ( EndpointChannelMessagesBulkDelete = func(cID string) string { return EndpointChannel(cID) + "/messages/bulk_delete" } EndpointChannelMessagesPins = func(cID string) string { return EndpointChannel(cID) + "/pins" } EndpointChannelMessagePin = func(cID, mID string) string { return EndpointChannel(cID) + "/pins/" + mID } + 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 } EndpointInvite = func(iID string) string { return EndpointAPI + "invite/" + iID } diff --git a/message.go b/message.go index 9e33dd2..7b85973 100644 --- a/message.go +++ b/message.go @@ -41,31 +41,73 @@ type MessageAttachment struct { Size int `json:"size"` } +// MessageEmbedFooter is a part of a MessageEmbed struct. +type MessageEmbedFooter struct { + Text string `json:"text,omitempty"` + IconURL string `json:"icon_url,omitempty"` + ProxyIconURL string `json:"proxy_icon_url,omitempty"` +} + +// MessageEmbedImage is a part of a MessageEmbed struct. +type MessageEmbedImage struct { + URL string `json:"url,omitempty"` + ProxyURL string `json:"proxy_url,omitempty"` + Width int `json:"width,omitempty"` + Height int `json:"height,omitempty"` +} + +// MessageEmbedThumbnail is a part of a MessageEmbed struct. +type MessageEmbedThumbnail struct { + URL string `json:"url,omitempty"` + ProxyURL string `json:"proxy_url,omitempty"` + Width int `json:"width,omitempty"` + Height int `json:"height,omitempty"` +} + +// MessageEmbedVideo is a part of a MessageEmbed struct. +type MessageEmbedVideo struct { + URL string `json:"url,omitempty"` + ProxyURL string `json:"proxy_url,omitempty"` + Width int `json:"width,omitempty"` + Height int `json:"height,omitempty"` +} + +// MessageEmbedProvider is a part of a MessageEmbed struct. +type MessageEmbedProvider struct { + URL string `json:"url,omitempty"` + Name string `json:"name,omitempty"` +} + +// MessageEmbedAuthor is a part of a MessageEmbed struct. +type MessageEmbedAuthor struct { + URL string `json:"url,omitempty"` + Name string `json:"name,omitempty"` + IconURL string `json:"icon_url,omitempty"` + ProxyIconURL string `json:"proxy_icon_url,omitempty"` +} + +// MessageEmbedField is a part of a MessageEmbed struct. +type MessageEmbedField struct { + Name string `json:"name,omitempty"` + Value string `json:"value,omitempty"` + Inline bool `json:"inline,omitempty"` +} + // An MessageEmbed stores data for message embeds. type MessageEmbed struct { - URL string `json:"url"` - Type string `json:"type"` - Title string `json:"title"` - Description string `json:"description"` - Thumbnail *struct { - URL string `json:"url"` - ProxyURL string `json:"proxy_url"` - Width int `json:"width"` - Height int `json:"height"` - } `json:"thumbnail"` - Provider *struct { - URL string `json:"url"` - Name string `json:"name"` - } `json:"provider"` - Author *struct { - URL string `json:"url"` - Name string `json:"name"` - } `json:"author"` - Video *struct { - URL string `json:"url"` - Width int `json:"width"` - Height int `json:"height"` - } `json:"video"` + URL string `json:"url,omitempty"` + Type string `json:"type,omitempty"` + Title string `json:"title,omitempty"` + Description string `json:"description,omitempty"` + Timestamp string `json:"timestamp,omitempty"` + Color int `json:"color,omitempty"` + Footer *MessageEmbedFooter `json:"footer,omitempty"` + Image *MessageEmbedImage `json:"image,omitempty"` + Thumbnail *MessageEmbedThumbnail `json:"thumbnail,omitempty"` + Video *MessageEmbedVideo `json:"video,omitempty"` + Provider *MessageEmbedProvider `json:"provider,omitempty"` + Author *MessageEmbedAuthor `json:"author,omitempty"` + Fields []*MessageEmbedField `json:"fields,omitempty"` } // ContentWithMentionsReplaced will replace all @ mentions with the diff --git a/restapi.go b/restapi.go index d51fcbe..fae8d61 100644 --- a/restapi.go +++ b/restapi.go @@ -461,7 +461,7 @@ func (s *Session) UserChannelPermissions(userID, channelID string) (apermissions } } - if apermissions&PermissionManageRoles > 0 { + if apermissions&PermissionAdministrator > 0 { apermissions |= PermissionAll } @@ -1466,3 +1466,172 @@ func (s *Session) Gateway() (gateway string, err error) { gateway = temp.URL return } + +// Functions specific to Webhooks + +// WebhookCreate returns a new Webhook. +// channelID: The ID of a Channel. +// name : The name of the webhook. +// avatar : The avatar of the webhook. +func (s *Session) WebhookCreate(channelID, name, avatar string) (st *Webhook, err error) { + + data := struct { + Name string `json:"name"` + Avatar string `json:"avatar,omitempty"` + }{name, avatar} + + body, err := s.Request("POST", EndpointChannelWebhooks(channelID), data) + if err != nil { + return + } + + err = unmarshal(body, &st) + + return +} + +// ChannelWebhooks returns all webhooks for a given channel. +// channelID: The ID of a channel. +func (s *Session) ChannelWebhooks(channelID string) (st []*Webhook, err error) { + + body, err := s.Request("GET", EndpointChannelWebhooks(channelID), nil) + if err != nil { + return + } + + err = unmarshal(body, &st) + + return +} + +// GuildWebhooks returns all webhooks for a given guild. +// guildID: The ID of a Guild. +func (s *Session) GuildWebhooks(guildID string) (st []*Webhook, err error) { + + body, err := s.Request("GET", EndpointGuildWebhooks(guildID), nil) + if err != nil { + return + } + + err = unmarshal(body, &st) + + return +} + +// Webhook returns a webhook for a given ID +// webhookID: The ID of a webhook. +func (s *Session) Webhook(webhookID string) (st *Webhook, err error) { + + body, err := s.Request("GET", EndpointWebhook(webhookID), nil) + if err != nil { + return + } + + err = unmarshal(body, &st) + + return +} + +// WebhookWithToken returns a webhook for a given ID +// webhookID: The ID of a webhook. +// token : The auth token for the webhook. +func (s *Session) WebhookWithToken(webhookID, token string) (st *Webhook, err error) { + + body, err := s.Request("GET", EndpointWebhookToken(webhookID, token), nil) + if err != nil { + return + } + + err = unmarshal(body, &st) + + return +} + +// WebhookEdit updates an existing Webhook. +// webhookID: The ID of a webhook. +// name : The name of the webhook. +// avatar : The avatar of the webhook. +func (s *Session) WebhookEdit(webhookID, name, avatar string) (st *Role, err error) { + + data := struct { + Name string `json:"name,omitempty"` + Avatar string `json:"avatar,omitempty"` + }{name, avatar} + + body, err := s.Request("PATCH", EndpointWebhook(webhookID), data) + if err != nil { + return + } + + err = unmarshal(body, &st) + + return +} + +// WebhookEditWithToken updates an existing Webhook with an auth token. +// webhookID: The ID of a webhook. +// token : The auth token for the webhook. +// name : The name of the webhook. +// avatar : The avatar of the webhook. +func (s *Session) WebhookEditWithToken(webhookID, token, name, avatar string) (st *Role, err error) { + + data := struct { + Name string `json:"name,omitempty"` + Avatar string `json:"avatar,omitempty"` + }{name, avatar} + + body, err := s.Request("PATCH", EndpointWebhookToken(webhookID, token), data) + if err != nil { + return + } + + err = unmarshal(body, &st) + + return +} + +// WebhookDelete deletes a webhook for a given ID +// webhookID: The ID of a webhook. +func (s *Session) WebhookDelete(webhookID string) (st *Webhook, err error) { + + body, err := s.Request("DELETE", EndpointWebhook(webhookID), nil) + if err != nil { + return + } + + err = unmarshal(body, &st) + + return +} + +// WebhookDeleteWithToken deletes a webhook for a given ID with an auth token. +// webhookID: The ID of a webhook. +// token : The auth token for the webhook. +func (s *Session) WebhookDeleteWithToken(webhookID, token string) (st *Webhook, err error) { + + body, err := s.Request("DELETE", EndpointWebhookToken(webhookID, token), nil) + if err != nil { + return + } + + err = unmarshal(body, &st) + + return +} + +// WebhookExecute executes a webhook. +// webhookID: The ID of a webhook. +// token : The auth token for the bebhook +func (s *Session) WebhookExecute(webhookID, token string, wait bool, data *WebhookParams) (err error) { + uri := EndpointWebhookToken(webhookID, token) + + if wait { + uri += "?wait=true" + } + + fmt.Println(uri) + + _, err = s.Request("POST", uri, data) + + return +} diff --git a/state.go b/state.go index aa7997e..5b6ed07 100644 --- a/state.go +++ b/state.go @@ -755,7 +755,7 @@ func (s *State) UserChannelPermissions(userID, channelID string) (apermissions i } } - if apermissions&PermissionManageRoles > 0 { + if apermissions&PermissionAdministrator > 0 { apermissions |= PermissionAll } diff --git a/structs.go b/structs.go index 47623f4..ce4add3 100644 --- a/structs.go +++ b/structs.go @@ -514,6 +514,27 @@ type ChannelPinsUpdate struct { ChannelID string `json:"channel_id"` } +// Webhook stores the data for a webhook. +type Webhook struct { + ID string `json:"id"` + 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"` +} + +// 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"` +} + // Constants for the different bit offsets of text channel permissions const ( PermissionReadMessages = 1 << (iota + 10) @@ -524,6 +545,7 @@ const ( PermissionAttachFiles PermissionReadMessageHistory PermissionMentionEveryone + PermissionUseExternalEmojis ) // Constants for the different bit offsets of voice permissions @@ -536,12 +558,21 @@ const ( PermissionVoiceUseVAD ) +// Constants for general management. +const ( + PermissionChangeNickname = 1 << (iota + 26) + PermissionManageNicknames + PermissionManageRoles + PermissionManageWebhooks + PermissionManageEmojis +) + // Constants for the different bit offsets of general permissions const ( PermissionCreateInstantInvite = 1 << iota PermissionKickMembers PermissionBanMembers - PermissionManageRoles + PermissionAdministrator PermissionManageChannels PermissionManageServer