mirror of
https://github.com/diamondburned/arikawa.git
synced 2025-12-02 09:47:52 +00:00
Added Permissions and stuff
This commit is contained in:
parent
b77d5f20da
commit
6b993f2032
|
|
@ -9,7 +9,7 @@ import (
|
||||||
const EndpointChannels = Endpoint + "channels/"
|
const EndpointChannels = Endpoint + "channels/"
|
||||||
|
|
||||||
type ChannelModifier struct {
|
type ChannelModifier struct {
|
||||||
ChannelID discord.Snowflake `json:"id,omitempty"`
|
ChannelID discord.Snowflake `json:"id,string,omitempty"`
|
||||||
|
|
||||||
// All types
|
// All types
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
|
|
@ -30,10 +30,12 @@ type ChannelModifier struct {
|
||||||
UserLimit json.OptionUint `json:"user_limit,omitempty"`
|
UserLimit json.OptionUint `json:"user_limit,omitempty"`
|
||||||
|
|
||||||
// Text OR Voice
|
// Text OR Voice
|
||||||
ParentID discord.Snowflake `json:"parent_id,omitempty"`
|
ParentID discord.Snowflake `json:"parent_id,string,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) Channel(channelID discord.Snowflake) (*discord.Channel, error) {
|
func (c *Client) Channel(
|
||||||
|
channelID discord.Snowflake) (*discord.Channel, error) {
|
||||||
|
|
||||||
var channel *discord.Channel
|
var channel *discord.Channel
|
||||||
|
|
||||||
return channel,
|
return channel,
|
||||||
|
|
|
||||||
62
api/emoji.go
62
api/emoji.go
|
|
@ -1,7 +1,10 @@
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
"github.com/diamondburned/arikawa/discord"
|
"github.com/diamondburned/arikawa/discord"
|
||||||
|
"github.com/diamondburned/arikawa/httputil"
|
||||||
)
|
)
|
||||||
|
|
||||||
// EmojiAPI is a special format that the API wants.
|
// EmojiAPI is a special format that the API wants.
|
||||||
|
|
@ -31,4 +34,61 @@ func (c *Client) Emoji(
|
||||||
EndpointGuilds+guildID.String()+"/emojis/"+emojiID.String())
|
EndpointGuilds+guildID.String()+"/emojis/"+emojiID.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (c *Client) CreateEmoji()
|
var (
|
||||||
|
ErrEmojiTooLarge = errors.New("Emoji is larger than 256k")
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateEmoji creates a new emoji in the guild. This endpoint requires
|
||||||
|
// MANAGE_EMOJIS. ContentType must be "image/jpeg", "image/png", or
|
||||||
|
// "image/gif". However, ContentType can also be automatically detected
|
||||||
|
// (though shouldn't be relied on). Roles slice is optional.
|
||||||
|
func (c *Client) CreateEmoji(
|
||||||
|
guildID discord.Snowflake, name string, image Image,
|
||||||
|
roles []discord.Snowflake) (*discord.Emoji, error) {
|
||||||
|
|
||||||
|
image.MaxSize = 256 * 1000
|
||||||
|
if err := image.Validate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var param struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Image Image `json:"image"`
|
||||||
|
Roles []discord.Snowflake `json:"roles"`
|
||||||
|
}
|
||||||
|
|
||||||
|
param.Name = name
|
||||||
|
param.Roles = roles
|
||||||
|
param.Image = image
|
||||||
|
|
||||||
|
var emj *discord.Emoji
|
||||||
|
return emj, c.RequestJSON(
|
||||||
|
&emj, "POST",
|
||||||
|
EndpointGuilds+guildID.String()+"/emojis",
|
||||||
|
httputil.WithJSONBody(c, param),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ModifyEmoji changes an existing emoji. This requires MANAGE_EMOJIS. Name and
|
||||||
|
// roles are optional fields (though you'd want to change either though).
|
||||||
|
func (c *Client) ModifyEmoji(
|
||||||
|
guildID, emojiID discord.Snowflake, name string,
|
||||||
|
roles []discord.Snowflake) error {
|
||||||
|
|
||||||
|
var param struct {
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Roles []discord.Snowflake `json:"roles,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.FastRequest(
|
||||||
|
"PATCH",
|
||||||
|
EndpointGuilds+guildID.String()+"/emojis/"+emojiID.String(),
|
||||||
|
httputil.WithJSONBody(c, param),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteEmoji requires MANAGE_EMOJIS.
|
||||||
|
func (c *Client) DeleteEmoji(guildID, emojiID discord.Snowflake) error {
|
||||||
|
return c.FastRequest("DELETE",
|
||||||
|
EndpointGuilds+guildID.String()+"/emojis/"+emojiID.String())
|
||||||
|
}
|
||||||
|
|
|
||||||
65
api/guild.go
65
api/guild.go
|
|
@ -1,3 +1,68 @@
|
||||||
package api
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/diamondburned/arikawa/discord" // for clarity
|
||||||
|
d "github.com/diamondburned/arikawa/discord"
|
||||||
|
"github.com/diamondburned/arikawa/httputil"
|
||||||
|
)
|
||||||
|
|
||||||
const EndpointGuilds = Endpoint + "guilds/"
|
const EndpointGuilds = Endpoint + "guilds/"
|
||||||
|
|
||||||
|
// https://discordapp.com/developers/docs/resources/guild#create-guild-json-params
|
||||||
|
type CreateGuildData struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Region string `json:"region"`
|
||||||
|
Icon Image `json:"image"`
|
||||||
|
|
||||||
|
// package dc is just package discord
|
||||||
|
Verification d.Verification `json:"verification_level"`
|
||||||
|
Notification d.Notification `json:"default_message_notifications"`
|
||||||
|
ExplicitFilter d.ExplicitFilter `json:"explicit_content_filter"`
|
||||||
|
|
||||||
|
// [0] (First entry) is ALWAYS @everyone.
|
||||||
|
Roles []discord.Role `json:"roles"`
|
||||||
|
|
||||||
|
// Partial, id field is ignored. Usually only Name and Type are changed.
|
||||||
|
Channels []discord.Channel `json:"channels"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) CreateGuild(data CreateGuildData) (*discord.Guild, error) {
|
||||||
|
var g *discord.Guild
|
||||||
|
return g, c.RequestJSON(&g, "POST", Endpoint+"guilds",
|
||||||
|
httputil.WithJSONBody(c, data))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) Guild(guildID discord.Snowflake) (*discord.Guild, error) {
|
||||||
|
var g *discord.Guild
|
||||||
|
return g, c.RequestJSON(&g, "GET", EndpointGuilds+guildID.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://discordapp.com/developers/docs/resources/guild#modify-guild-json-params
|
||||||
|
type ModifyGuildData struct {
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Region string `json:"region,omitempty"`
|
||||||
|
Icon *Image `json:"image,omitempty"`
|
||||||
|
|
||||||
|
// package d is just package discord
|
||||||
|
Verification *d.Verification `json:"verification_level,omitempty"`
|
||||||
|
Notification *d.Notification `json:"default_message_notifications,omitempty"`
|
||||||
|
ExplicitFilter *d.ExplicitFilter `json:"explicit_content_filter,omitempty"`
|
||||||
|
|
||||||
|
AFKChannelID *d.Snowflake `json:"afk_channel_id,string,omitempty"`
|
||||||
|
AFKTimeout *d.Seconds `json:"afk_timeout,omitempty"`
|
||||||
|
|
||||||
|
OwnerID d.Snowflake `json:"owner_id,string,omitempty"`
|
||||||
|
|
||||||
|
Splash *Image `json:"splash,omitempty"`
|
||||||
|
Banner *Image `json:"banner,omitempty"`
|
||||||
|
|
||||||
|
SystemChannelID d.Snowflake `json:"system_channel_id,string,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) ModifyGuild(
|
||||||
|
guildID discord.Snowflake, data ModifyGuildData) (*discord.Guild, error) {
|
||||||
|
|
||||||
|
var g *discord.Guild
|
||||||
|
return g, c.RequestJSON(&g, "PATCH", EndpointGuilds+guildID.String(),
|
||||||
|
httputil.WithJSONBody(c, data))
|
||||||
|
}
|
||||||
|
|
|
||||||
123
api/image.go
Normal file
123
api/image.go
Normal file
|
|
@ -0,0 +1,123 @@
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ErrInvalidImageCT = errors.New("Unknown image content-type")
|
||||||
|
var ErrInvalidImageData = errors.New("Invalid image data")
|
||||||
|
|
||||||
|
type ErrImageTooLarge struct {
|
||||||
|
Size, Max int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err ErrImageTooLarge) Error() string {
|
||||||
|
return fmt.Sprintf("Image is %.02fkb, larger than %.02fkb",
|
||||||
|
float64(err.Size)/1000, float64(err.Max)/1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Image wraps around the Data URI Scheme that Discord uses:
|
||||||
|
// https://discordapp.com/developers/docs/reference#image-data
|
||||||
|
type Image struct {
|
||||||
|
// ContentType is optional and will be automatically detected. However, it
|
||||||
|
// should always return "image/jpeg," "image/png" or "image/gif".
|
||||||
|
ContentType string
|
||||||
|
|
||||||
|
// Just raw content of the file.
|
||||||
|
Content []byte
|
||||||
|
|
||||||
|
// Utility fields, not used for encoding
|
||||||
|
MaxSize int // bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
func DecodeImage(data []byte) (*Image, error) {
|
||||||
|
parts := bytes.SplitN(data, []byte{';'}, 2)
|
||||||
|
if len(parts) < 2 {
|
||||||
|
return nil, ErrInvalidImageData
|
||||||
|
}
|
||||||
|
|
||||||
|
if !bytes.HasPrefix(parts[0], []byte("data:")) {
|
||||||
|
return nil, errors.Wrap(ErrInvalidImageData, "invalid header")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !bytes.HasPrefix(parts[1], []byte("base64,")) {
|
||||||
|
return nil, errors.Wrap(ErrInvalidImageData, "invalid base64")
|
||||||
|
}
|
||||||
|
|
||||||
|
var b64 = parts[1][len("base64,"):]
|
||||||
|
var img = Image{
|
||||||
|
ContentType: string(parts[0][len("data:"):]),
|
||||||
|
Content: make([]byte, base64.StdEncoding.DecodedLen(len(b64))),
|
||||||
|
}
|
||||||
|
|
||||||
|
base64.StdEncoding.Decode(img.Content, b64)
|
||||||
|
return &img, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i Image) Validate() error {
|
||||||
|
if i.MaxSize > 0 && len(i.Content) > i.MaxSize {
|
||||||
|
return ErrImageTooLarge{len(i.Content), i.MaxSize}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch i.ContentType {
|
||||||
|
case "image/png", "image/jpeg", "image/gif":
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
return ErrInvalidImageCT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i Image) Encode() ([]byte, error) {
|
||||||
|
if i.ContentType == "" {
|
||||||
|
var max = 512
|
||||||
|
if len(i.Content) < max {
|
||||||
|
max = len(i.Content)
|
||||||
|
}
|
||||||
|
i.ContentType = http.DetectContentType(i.Content[:max])
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := i.Validate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
b64enc := make([]byte, base64.StdEncoding.EncodedLen(len(i.Content)))
|
||||||
|
base64.StdEncoding.Encode(b64enc, i.Content)
|
||||||
|
|
||||||
|
return bytes.Join([][]byte{
|
||||||
|
[]byte("data:"),
|
||||||
|
[]byte(i.ContentType),
|
||||||
|
[]byte(";base64,"),
|
||||||
|
b64enc,
|
||||||
|
}, nil), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ json.Marshaler = (*Image)(nil)
|
||||||
|
var _ json.Unmarshaler = (*Image)(nil)
|
||||||
|
|
||||||
|
func (i Image) MarshalJSON() ([]byte, error) {
|
||||||
|
b, err := i.Encode()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes.Join([][]byte{{'"'}, b, {'"'}}, nil), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Image) UnmarshalJSON(v []byte) error {
|
||||||
|
// Trim string
|
||||||
|
v = bytes.Trim(v, `"`)
|
||||||
|
|
||||||
|
img, err := DecodeImage(v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*i = *img
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
@ -16,21 +16,21 @@ type Channel struct {
|
||||||
Icon Hash `json:"icon,omitempty"`
|
Icon Hash `json:"icon,omitempty"`
|
||||||
|
|
||||||
// Direct Messaging fields
|
// Direct Messaging fields
|
||||||
DMOwnerID Snowflake `json:"owner_id,omitempty"`
|
DMOwnerID Snowflake `json:"owner_id,string,omitempty"`
|
||||||
DMRecipients []User `json:"recipients,omitempty"`
|
DMRecipients []User `json:"recipients,omitempty"`
|
||||||
|
|
||||||
// AppID of the group DM creator if it's bot-created
|
// AppID of the group DM creator if it's bot-created
|
||||||
AppID Snowflake `json:"application_id,omitempty"`
|
AppID Snowflake `json:"application_id,string,omitempty"`
|
||||||
|
|
||||||
// ID of the category the channel is in, if any.
|
// ID of the category the channel is in, if any.
|
||||||
CategoryID Snowflake `json:"parent_id,omitempty"`
|
CategoryID Snowflake `json:"parent_id,string,omitempty"`
|
||||||
|
|
||||||
LastPinTime Timestamp `json:"last_pin_timestamp,omitempty"`
|
LastPinTime Timestamp `json:"last_pin_timestamp,omitempty"`
|
||||||
|
|
||||||
// Explicit permission overrides for members and roles.
|
// Explicit permission overrides for members and roles.
|
||||||
Permissions []Overwrite `json:"permission_overwrites,omitempty"`
|
Permissions []Overwrite `json:"permission_overwrites,omitempty"`
|
||||||
// ID of the last message, may not point to a valid one.
|
// ID of the last message, may not point to a valid one.
|
||||||
LastMessageID Snowflake `json:"last_message_id,omitempty"`
|
LastMessageID Snowflake `json:"last_message_id,string,omitempty"`
|
||||||
|
|
||||||
// Slow mode duration. Bots and people with "manage_messages" or
|
// Slow mode duration. Bots and people with "manage_messages" or
|
||||||
// "manage_channel" permissions are unaffected.
|
// "manage_channel" permissions are unaffected.
|
||||||
|
|
@ -54,10 +54,10 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Overwrite struct {
|
type Overwrite struct {
|
||||||
ID Snowflake `json:"id,omitempty"`
|
ID Snowflake `json:"id,string,omitempty"`
|
||||||
Type OverwriteType `json:"type"`
|
Type OverwriteType `json:"type"`
|
||||||
Allow uint64 `json:"allow"`
|
Allow Permissions `json:"allow"`
|
||||||
Deny uint64 `json:"deny"`
|
Deny Permissions `json:"deny"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type OverwriteType string
|
type OverwriteType string
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package discord
|
||||||
import "strings"
|
import "strings"
|
||||||
|
|
||||||
type Emoji struct {
|
type Emoji struct {
|
||||||
ID Snowflake `json:"id"` // 0 for Unicode emojis
|
ID Snowflake `json:"id,string"` // 0 for Unicode emojis
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
|
||||||
// These fields are optional
|
// These fields are optional
|
||||||
|
|
|
||||||
110
discord/guild.go
110
discord/guild.go
|
|
@ -1,5 +1,111 @@
|
||||||
package discord
|
package discord
|
||||||
|
|
||||||
type Guild struct{}
|
type Guild struct {
|
||||||
|
ID Snowflake `json:"id,string"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Icon Hash `json:"icon"`
|
||||||
|
Splash Hash `json:"splash,omitempty"` // server invite bg
|
||||||
|
|
||||||
type GuildMember struct{}
|
Owner bool `json:"owner,omitempty"` // self is owner
|
||||||
|
OwnerID Snowflake `json:"owner_id,string"`
|
||||||
|
|
||||||
|
Permissions Permissions `json:"permissions,omitempty"`
|
||||||
|
|
||||||
|
VoiceRegion string `json:"region"`
|
||||||
|
|
||||||
|
AFKChannelID Snowflake `json:"afk_channel_id,string,omitempty"`
|
||||||
|
AFKTimeout Seconds `json:"afk_timeout"`
|
||||||
|
|
||||||
|
Embeddable bool `json:"embed_enabled,omitempty"`
|
||||||
|
EmbedChannelID Snowflake `json:"embed_channel_id,string,omitempty"`
|
||||||
|
|
||||||
|
Verification Verification `json:"verification_level"`
|
||||||
|
Notification Notification `json:"default_message_notifications"`
|
||||||
|
ExplicitFilter ExplicitFilter `json:"explicit_content_filter"`
|
||||||
|
|
||||||
|
Roles []Role `json:"roles"`
|
||||||
|
Emojis []Emoji `json:"emojis"`
|
||||||
|
Features []GuildFeature `json:"guild_features"`
|
||||||
|
|
||||||
|
MFA MFALevel `json:"mfa"`
|
||||||
|
|
||||||
|
AppID Snowflake `json:"application_id,string,omitempty"`
|
||||||
|
|
||||||
|
Widget bool `json:"widget_enabled,omitempty"`
|
||||||
|
|
||||||
|
WidgetChannelID Snowflake `json:"widget_channel_id,string,omitempty"`
|
||||||
|
SystemChannelID Snowflake `json:"system_channel_id,string,omitempty"`
|
||||||
|
|
||||||
|
// GUILD_CREATE only.
|
||||||
|
Joined Timestamp `json:"timestamp,omitempty"`
|
||||||
|
Large bool `json:"large,omitempty"`
|
||||||
|
Unavailable bool `json:"unavailable,omitempty"`
|
||||||
|
MemberCount uint64 `json:"member_count,omitempty"`
|
||||||
|
VoiceStates []VoiceState `json:"voice_state,omitempty"`
|
||||||
|
Members []Member `json:"members,omitempty"`
|
||||||
|
Channels []Channel `json:"channel,omitempty"`
|
||||||
|
Presences []Presence `json:"presences,omitempty"`
|
||||||
|
|
||||||
|
// It's DefaultMaxPresences when MaxPresences is 0.
|
||||||
|
MaxPresences uint64 `json:"max_presences,omitempty"`
|
||||||
|
MaxMembers uint64 `json:"max_members,omitempty"`
|
||||||
|
|
||||||
|
VanityURLCode string `json:"vanity_url_code,omitempty"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
Banner Hash `json:"banner,omitempty"`
|
||||||
|
|
||||||
|
NitroBoost NitroBoost `json:"premium_tier"`
|
||||||
|
NitroBoosters uint64 `json:"premium_subscription_count,omitempty"`
|
||||||
|
|
||||||
|
// Defaults to en-US, only set if guild has DISCOVERABLE
|
||||||
|
PreferredLocale string `json:"preferred_locale"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Role struct {
|
||||||
|
ID Snowflake `json:"id,string"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
|
||||||
|
Color Color `json:"color"`
|
||||||
|
Hoist bool `json:"hoist"` // if the role is separated
|
||||||
|
Position int `json:"position"`
|
||||||
|
|
||||||
|
Permissions Permissions `json:"permissions"`
|
||||||
|
|
||||||
|
Managed bool `json:"managed"`
|
||||||
|
Mentionable bool `json:"mentionable"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Presence struct {
|
||||||
|
User User `json:"user"`
|
||||||
|
RoleIDs []Snowflake `json:"roles"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type VoiceState struct {
|
||||||
|
// GuildID isn't available from the Guild struct.
|
||||||
|
GuildID Snowflake `json:"guild_id,string"`
|
||||||
|
|
||||||
|
ChannelID Snowflake `json:"channel_id,string"`
|
||||||
|
UserID Snowflake `json:"user_id,string"`
|
||||||
|
Member *Member `json:"member,omitempty"`
|
||||||
|
SessionID string `json:"session_id"`
|
||||||
|
|
||||||
|
Deaf bool `json:"deaf"`
|
||||||
|
Mute bool `json:"mute"`
|
||||||
|
|
||||||
|
SelfDeaf bool `json:"self_deaf"`
|
||||||
|
SelfMute bool `json:"self_mute"`
|
||||||
|
SelfStream bool `json:"self_stream,omitempty"`
|
||||||
|
Suppress bool `json:"suppress"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Member struct {
|
||||||
|
User User `json:"user"`
|
||||||
|
Nick string `json:"nick,omitempty"`
|
||||||
|
RoleIDs []Snowflake `json:"roles"`
|
||||||
|
|
||||||
|
Joined Timestamp `json:"joined_at"`
|
||||||
|
BoostedSince Timestamp `json:"premium_since,omitempty"`
|
||||||
|
|
||||||
|
Deaf bool `json:"deaf"`
|
||||||
|
Mute bool `json:"mute"`
|
||||||
|
}
|
||||||
|
|
|
||||||
87
discord/guild_const.go
Normal file
87
discord/guild_const.go
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
package discord
|
||||||
|
|
||||||
|
// Guild.MaxPresences is 5000 when it's 0. Seriously. The fucker who thought of
|
||||||
|
// this API thought it was also a good idea to return "null" instead of
|
||||||
|
// "5000." What the fucK? It has the same byte count, thus the same size.
|
||||||
|
// Sending the number over means it could be changed anytime and not force
|
||||||
|
// the developers to recheck. You could make the change right today and it
|
||||||
|
// would just work on all the clients. But no. IT'S FUCKING NULL!
|
||||||
|
const DefaultMaxPresences = 5000
|
||||||
|
|
||||||
|
type NitroBoost uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
NoNitroLevel NitroBoost = iota
|
||||||
|
NitroLevel1
|
||||||
|
NitroLevel2
|
||||||
|
NitroLevel3
|
||||||
|
)
|
||||||
|
|
||||||
|
type MFALevel uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
NoMFA MFALevel = iota
|
||||||
|
ElevatedMFA
|
||||||
|
)
|
||||||
|
|
||||||
|
type GuildFeature string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Guild has access to set an invite splash background
|
||||||
|
InviteSplash GuildFeature = "INVITE_SPLASH"
|
||||||
|
// Guild has access to set 384kbps bitrate in voice (previously VIP voice
|
||||||
|
// servers)
|
||||||
|
VIPRegions GuildFeature = "VIP_REGIONS"
|
||||||
|
// Guild has access to set a vanity URL
|
||||||
|
VanityURL GuildFeature = "VANITY_URL"
|
||||||
|
// Guild is verified
|
||||||
|
Verified GuildFeature = "VERIFIED"
|
||||||
|
// Guild is partnered
|
||||||
|
Partnered GuildFeature = "PARTNERED"
|
||||||
|
// Guild is public
|
||||||
|
Public GuildFeature = "PUBLIC"
|
||||||
|
// Guild has access to use commerce features (i.e. create store channels)
|
||||||
|
Commerce GuildFeature = "COMMERCE"
|
||||||
|
// Guild has access to create news channels
|
||||||
|
News GuildFeature = "NEWS"
|
||||||
|
// Guild is able to be discovered in the directory
|
||||||
|
Discoverable GuildFeature = "DISCOVERABLE"
|
||||||
|
// Guild is able to be featured in the directory
|
||||||
|
Featurable GuildFeature = "FEATURABLE"
|
||||||
|
// Guild has access to set an animated guild icon
|
||||||
|
AnimatedIcon GuildFeature = "ANIMATED_ICON"
|
||||||
|
// Guild has access to set a guild banner image
|
||||||
|
Banner GuildFeature = "BANNER"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ExplicitFilter uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
NoContentFilter ExplicitFilter = iota
|
||||||
|
MembersWithoutRoles
|
||||||
|
AllMembers
|
||||||
|
)
|
||||||
|
|
||||||
|
type Notification uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
AllMessages Notification = iota
|
||||||
|
OnlyMentions
|
||||||
|
)
|
||||||
|
|
||||||
|
type Verification uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
NoVerification Verification = iota
|
||||||
|
// LowVerification requires a verified email
|
||||||
|
LowVerification
|
||||||
|
// MediumVerification requires the user be registered for at least 5
|
||||||
|
// minutes.
|
||||||
|
MediumVerification
|
||||||
|
// HighVerification requires the member be in the server for more than 10
|
||||||
|
// minutes.
|
||||||
|
HighVerification
|
||||||
|
// VeryHighVerification requires the member to have a verified phone
|
||||||
|
// number.
|
||||||
|
VeryHighVerification
|
||||||
|
)
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
package discord
|
package discord
|
||||||
|
|
||||||
type Message struct {
|
type Message struct {
|
||||||
ID Snowflake `json:"id"`
|
ID Snowflake `json:"id,string"`
|
||||||
Type MessageType `json:"type"`
|
Type MessageType `json:"type"`
|
||||||
ChannelID Snowflake `json:"channel_id"`
|
ChannelID Snowflake `json:"channel_id,string"`
|
||||||
GuildID Snowflake `json:"guild_id,omitempty"`
|
GuildID Snowflake `json:"guild_id,string,omitempty"`
|
||||||
|
|
||||||
// The author object follows the structure of the user object, but is only
|
// The author object follows the structure of the user object, but is only
|
||||||
// a valid user in the case where the message is generated by a user or bot
|
// a valid user in the case where the message is generated by a user or bot
|
||||||
|
|
@ -16,7 +16,7 @@ type Message struct {
|
||||||
|
|
||||||
// The member object exists in MESSAGE_CREATE and MESSAGE_UPDATE
|
// The member object exists in MESSAGE_CREATE and MESSAGE_UPDATE
|
||||||
// events from text-based guild channels.
|
// events from text-based guild channels.
|
||||||
Member *GuildMember `json:"member,omitempty"`
|
Member *Member `json:"member,omitempty"`
|
||||||
|
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
|
|
||||||
|
|
@ -45,7 +45,7 @@ type Message struct {
|
||||||
// Used for validating a message was sent
|
// Used for validating a message was sent
|
||||||
Nonce string `json:"nonce,omitempty"`
|
Nonce string `json:"nonce,omitempty"`
|
||||||
|
|
||||||
WebhookID Snowflake `json:"webhook_id,omitempty"`
|
WebhookID Snowflake `json:"webhook_id,string,omitempty"`
|
||||||
Activity *MessageActivity `json:"activity,omitempty"`
|
Activity *MessageActivity `json:"activity,omitempty"`
|
||||||
Application *MessageApplication `json:"application,omitempty"`
|
Application *MessageApplication `json:"application,omitempty"`
|
||||||
Reference *MessageReference `json:"message_reference,omitempty"`
|
Reference *MessageReference `json:"message_reference,omitempty"`
|
||||||
|
|
@ -81,15 +81,15 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type ChannelMention struct {
|
type ChannelMention struct {
|
||||||
ChannelID Snowflake `json:"id"`
|
ChannelID Snowflake `json:"id,string"`
|
||||||
GuildID Snowflake `json:"guild_id"`
|
GuildID Snowflake `json:"guild_id,string"`
|
||||||
ChannelType ChannelType `json:"type"`
|
ChannelType ChannelType `json:"type"`
|
||||||
ChannelName string `json:"name"`
|
ChannelName string `json:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GuildUser struct {
|
type GuildUser struct {
|
||||||
User
|
User
|
||||||
Member *GuildMember `json:"member,omitempty"`
|
Member *Member `json:"member,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -113,7 +113,7 @@ const (
|
||||||
//
|
//
|
||||||
|
|
||||||
type MessageApplication struct {
|
type MessageApplication struct {
|
||||||
ID Snowflake `json:"id"`
|
ID Snowflake `json:"id,string"`
|
||||||
CoverID string `json:"cover_image,omitempty"`
|
CoverID string `json:"cover_image,omitempty"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Icon string `json:"icon"`
|
Icon string `json:"icon"`
|
||||||
|
|
@ -123,17 +123,17 @@ type MessageApplication struct {
|
||||||
//
|
//
|
||||||
|
|
||||||
type MessageReference struct {
|
type MessageReference struct {
|
||||||
ChannelID Snowflake `json:"channel_id"`
|
ChannelID Snowflake `json:"channel_id,string"`
|
||||||
|
|
||||||
// Field might not be provided
|
// Field might not be provided
|
||||||
MessageID Snowflake `json:"message_id,omitempty"`
|
MessageID Snowflake `json:"message_id,string,omitempty"`
|
||||||
GuildID Snowflake `json:"guild_id,omitempty"`
|
GuildID Snowflake `json:"guild_id,string,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
type Attachment struct {
|
type Attachment struct {
|
||||||
ID Snowflake `json:"id"`
|
ID Snowflake `json:"id,string"`
|
||||||
Filename string `json:"filename"`
|
Filename string `json:"filename"`
|
||||||
Size uint64 `json:"size"`
|
Size uint64 `json:"size"`
|
||||||
|
|
||||||
|
|
|
||||||
181
discord/permission.go
Normal file
181
discord/permission.go
Normal file
|
|
@ -0,0 +1,181 @@
|
||||||
|
package discord
|
||||||
|
|
||||||
|
type Permissions uint64
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Allows creation of instant invites
|
||||||
|
PermissionCreateInstantInvite Permissions = 1 << iota
|
||||||
|
// Allows kicking members
|
||||||
|
PermissionKickMembers
|
||||||
|
// Allows banning members
|
||||||
|
PermissionBanMembers
|
||||||
|
// Allows all permissions and bypasses channel permission overwrites
|
||||||
|
PermissionAdministrator
|
||||||
|
// Allows management and editing of channels
|
||||||
|
PermissionManageChannels
|
||||||
|
// Allows management and editing of the guild
|
||||||
|
PermissionManageGuild
|
||||||
|
// Allows for the addition of reactions to messages
|
||||||
|
PermissionAddReactions
|
||||||
|
// Allows for viewing of audit logs
|
||||||
|
PermissionViewAuditLog
|
||||||
|
// Allows for using priority speaker in a voice channel
|
||||||
|
PermissionPrioritySpeaker
|
||||||
|
// Allows the user to go live
|
||||||
|
PermissionStream
|
||||||
|
// Allows guild members to view a channel, which includes reading messages
|
||||||
|
// in text channels
|
||||||
|
PermissionViewChannel
|
||||||
|
// Allows for sending messages in a channel
|
||||||
|
PermissionSendMessages
|
||||||
|
// Allows for sending of /tts messages
|
||||||
|
PermissionSendTTSMessages
|
||||||
|
// Allows for deletion of other users messages
|
||||||
|
PermissionManageMessages
|
||||||
|
// Links sent by users with this permission will be auto-embedded
|
||||||
|
PermissionEmbedLinks
|
||||||
|
// Allows for uploading images and files
|
||||||
|
PermissionAttachFiles
|
||||||
|
// Allows for reading of message history
|
||||||
|
PermissionReadMessageHistory
|
||||||
|
// Allows for using the @everyone tag to notify all users in a channel,
|
||||||
|
// and the @here tag to notify all online users in a channel
|
||||||
|
PermissionMentionEveryone
|
||||||
|
// Allows the usage of custom emojis from other servers
|
||||||
|
PermissionUseExternalEmojis
|
||||||
|
|
||||||
|
_ // ?
|
||||||
|
|
||||||
|
// Allows for joining of a voice channel
|
||||||
|
PermissionConnect
|
||||||
|
// Allows for speaking in a voice channel
|
||||||
|
PermissionSpeak
|
||||||
|
// Allows for muting members in a voice channel
|
||||||
|
PermissionMuteMembers
|
||||||
|
// Allows for deafening of members in a voice channel
|
||||||
|
PermissionDeafenMembers
|
||||||
|
// Allows for moving of members between voice channels
|
||||||
|
PermissionMoveMembers
|
||||||
|
// Allows for using voice-activity-detection in a voice channel
|
||||||
|
PermissionUseVAD
|
||||||
|
// Allows for modification of own nickname
|
||||||
|
PermissionChangeNickname
|
||||||
|
// Allows for modification of other users nicknames
|
||||||
|
PermissionManageNicknames
|
||||||
|
// Allows management and editing of roles
|
||||||
|
PermissionManageRoles
|
||||||
|
// Allows management and editing of webhooks
|
||||||
|
PermissionManageWebhooks
|
||||||
|
// Allows management and editing of emojis
|
||||||
|
PermissionManageEmojis
|
||||||
|
|
||||||
|
PermissionAllText = 0 |
|
||||||
|
PermissionViewChannel |
|
||||||
|
PermissionSendMessages |
|
||||||
|
PermissionSendTTSMessages |
|
||||||
|
PermissionManageMessages |
|
||||||
|
PermissionEmbedLinks |
|
||||||
|
PermissionAttachFiles |
|
||||||
|
PermissionReadMessageHistory |
|
||||||
|
PermissionMentionEveryone
|
||||||
|
|
||||||
|
PermissionAllVoice = 0 |
|
||||||
|
PermissionConnect |
|
||||||
|
PermissionSpeak |
|
||||||
|
PermissionMuteMembers |
|
||||||
|
PermissionDeafenMembers |
|
||||||
|
PermissionMoveMembers |
|
||||||
|
PermissionUseVAD |
|
||||||
|
PermissionPrioritySpeaker
|
||||||
|
|
||||||
|
PermissionAllChannel = 0 |
|
||||||
|
PermissionAllText |
|
||||||
|
PermissionAllVoice |
|
||||||
|
PermissionCreateInstantInvite |
|
||||||
|
PermissionManageRoles |
|
||||||
|
PermissionManageChannels |
|
||||||
|
PermissionAddReactions |
|
||||||
|
PermissionViewAuditLog
|
||||||
|
|
||||||
|
PermissionAll = 0 |
|
||||||
|
PermissionAllChannel |
|
||||||
|
PermissionKickMembers |
|
||||||
|
PermissionBanMembers |
|
||||||
|
PermissionManageGuild |
|
||||||
|
PermissionAdministrator |
|
||||||
|
PermissionManageWebhooks |
|
||||||
|
PermissionManageEmojis
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p Permissions) Has(perm Permissions) bool {
|
||||||
|
return (p & perm) == perm
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p Permissions) Add(perm Permissions) Permissions {
|
||||||
|
return p | perm
|
||||||
|
}
|
||||||
|
|
||||||
|
func CalcOverwrites(guild Guild, channel Channel, member Member) Permissions {
|
||||||
|
if guild.OwnerID == member.User.ID {
|
||||||
|
return PermissionAll
|
||||||
|
}
|
||||||
|
|
||||||
|
var perm Permissions
|
||||||
|
|
||||||
|
for _, role := range guild.Roles {
|
||||||
|
if role.ID == guild.ID {
|
||||||
|
perm |= role.Permissions
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, role := range guild.Roles {
|
||||||
|
for _, id := range member.RoleIDs {
|
||||||
|
if id == role.ID {
|
||||||
|
perm |= role.Permissions
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if perm.Has(PermissionAdministrator) {
|
||||||
|
return PermissionAll
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, overwrite := range channel.Permissions {
|
||||||
|
if overwrite.ID == guild.ID {
|
||||||
|
perm &= ^overwrite.Deny
|
||||||
|
perm |= overwrite.Allow
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var deny, allow Permissions
|
||||||
|
|
||||||
|
for _, overwrite := range channel.Permissions {
|
||||||
|
for _, id := range member.RoleIDs {
|
||||||
|
if id == overwrite.ID && overwrite.Type == "role" {
|
||||||
|
deny |= overwrite.Deny
|
||||||
|
allow |= overwrite.Allow
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
perm &= ^deny
|
||||||
|
perm |= allow
|
||||||
|
|
||||||
|
for _, overwrite := range channel.Permissions {
|
||||||
|
if overwrite.ID == member.User.ID {
|
||||||
|
perm &= ^overwrite.Deny
|
||||||
|
perm |= overwrite.Allow
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if perm.Has(PermissionAdministrator) {
|
||||||
|
return PermissionAll
|
||||||
|
}
|
||||||
|
|
||||||
|
return perm
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package discord
|
package discord
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
@ -13,6 +14,21 @@ func NewSnowflake(t time.Time) Snowflake {
|
||||||
return Snowflake(TimeToDiscordEpoch(t) << 22)
|
return Snowflake(TimeToDiscordEpoch(t) << 22)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Snowflake) UnmarshalJSON(v []byte) error {
|
||||||
|
v = bytes.Trim(v, `"`)
|
||||||
|
u, err := strconv.ParseUint(string(v), 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*s = Snowflake(u)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Snowflake) MarshalJSON() ([]byte, error) {
|
||||||
|
return []byte(`"` + strconv.FormatUint(uint64(*s), 10) + `"`), nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s Snowflake) String() string {
|
func (s Snowflake) String() string {
|
||||||
return strconv.FormatUint(uint64(s), 10)
|
return strconv.FormatUint(uint64(s), 10)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package discord
|
package discord
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
UserID Snowflake `json:"id"`
|
ID Snowflake `json:"id,string"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
Discriminator string `json:"discriminator"`
|
Discriminator string `json:"discriminator"`
|
||||||
Avatar Hash `json:"avatar"`
|
Avatar Hash `json:"avatar"`
|
||||||
|
|
@ -18,7 +18,7 @@ type User struct {
|
||||||
Email string `json:"email,omitempty"`
|
Email string `json:"email,omitempty"`
|
||||||
|
|
||||||
Flags UserFlags `json:"flags,omitempty"`
|
Flags UserFlags `json:"flags,omitempty"`
|
||||||
Nitro Nitro `json:"premium_type,omitempty"`
|
Nitro UserNitro `json:"premium_type,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserFlags uint16
|
type UserFlags uint16
|
||||||
|
|
@ -38,10 +38,10 @@ const (
|
||||||
System
|
System
|
||||||
)
|
)
|
||||||
|
|
||||||
type Nitro uint8
|
type UserNitro uint8
|
||||||
|
|
||||||
const (
|
const (
|
||||||
NoNitro Nitro = iota
|
NoUserNitro UserNitro = iota
|
||||||
NitroClassic
|
NitroClassic
|
||||||
NitroFull
|
NitroFull
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue