diff --git a/api/channel.go b/api/channel.go index f3e31ea..f35e90d 100644 --- a/api/channel.go +++ b/api/channel.go @@ -8,7 +8,69 @@ import ( const EndpointChannels = Endpoint + "channels/" -type ChannelModifier struct { +func (c *Client) Channels(guildID discord.Snowflake) ([]discord.Channel, error) { + var chs []discord.Channel + return chs, c.RequestJSON(&chs, "GET", + EndpointGuilds+guildID.String()+"/channels") +} + +type CreateChannelData struct { + Name string `json:"name"` // 2-100 + Topic string `json:"topic,omitempty"` + + Type discord.ChannelType `json:"type,omitempty"` + + VoiceBitrate uint `json:"bitrate,omitempty"` + VoiceUserLimit uint `json:"user_limit,omitempty"` + + UserRateLimit discord.Seconds `json:"rate_limit_per_user,omitempty"` + + NSFW bool `json:"nsfw"` + Position int `json:"position,omitempty"` + + Permissions []discord.Overwrite `json:"permission_overwrites,omitempty"` + CategoryID discord.Snowflake `json:"parent_id,string,omitempty"` +} + +func (c *Client) CreateChannel(guildID discord.Snowflake, + data CreateChannelData) (*discord.Channel, error) { + + var ch *discord.Channel + return ch, c.RequestJSON( + &ch, "POST", + EndpointGuilds+guildID.String()+"/channels", + httputil.WithJSONBody(c, data), + ) +} + +func (c *Client) MoveChannel( + guildID, channelID discord.Snowflake, position int) error { + + var param struct { + ID discord.Snowflake `json:"id"` + Pos int `json:"position"` + } + + param.ID = channelID + param.Pos = position + + return c.FastRequest( + "PATCH", + EndpointGuilds+guildID.String()+"/channels", + httputil.WithJSONBody(c, param), + ) +} + +func (c *Client) Channel( + channelID discord.Snowflake) (*discord.Channel, error) { + + var channel *discord.Channel + + return channel, + c.RequestJSON(&channel, "POST", EndpointChannels+channelID.String()) +} + +type ModifyChannelData struct { ChannelID discord.Snowflake `json:"id,string,omitempty"` // All types @@ -25,28 +87,19 @@ type ChannelModifier struct { // Voice only // 8000 - 96000 (or 128000 for Nitro) - Bitrate json.OptionUint `json:"bitrate,omitempty"` + VoiceBitrate json.OptionUint `json:"bitrate,omitempty"` // 0 no limit, 1-99 - UserLimit json.OptionUint `json:"user_limit,omitempty"` + VoiceUserLimit json.OptionUint `json:"user_limit,omitempty"` // Text OR Voice - ParentID discord.Snowflake `json:"parent_id,string,omitempty"` + CategoryID discord.Snowflake `json:"parent_id,string,omitempty"` } -func (c *Client) Channel( - channelID discord.Snowflake) (*discord.Channel, error) { +func (c *Client) ModifyChannel(data ModifyChannelData) error { + url := EndpointChannels + data.ChannelID.String() + data.ChannelID = 0 - var channel *discord.Channel - - return channel, - c.RequestJSON(&channel, "POST", EndpointChannels+channelID.String()) -} - -func (c *Client) EditChannel(mod ChannelModifier) error { - url := EndpointChannels + mod.ChannelID.String() - mod.ChannelID = 0 - - return c.FastRequest("PATCH", url, httputil.WithJSONBody(c, mod)) + return c.FastRequest("PATCH", url, httputil.WithJSONBody(c, data)) } func (c *Client) DeleteChannel(channelID discord.Snowflake) error { diff --git a/api/guild.go b/api/guild.go index 9e836cb..21c4dee 100644 --- a/api/guild.go +++ b/api/guild.go @@ -66,3 +66,199 @@ func (c *Client) ModifyGuild( return g, c.RequestJSON(&g, "PATCH", EndpointGuilds+guildID.String(), httputil.WithJSONBody(c, data)) } + +func (c *Client) DeleteGuild(guildID discord.Snowflake) error { + return c.FastRequest("DELETE", EndpointGuilds+guildID.String()) +} + +func (c *Client) Members(guildID discord.Snowflake) ([]discord.Member, error) { + var mems []discord.Member + return mems, c.RequestJSON(&mems, "GET", + EndpointGuilds+guildID.String()+"/members") +} + +// AnyMemberData, all fields are optional. +type AnyMemberData struct { + Nick string `json:"nick,omitempty"` + Mute bool `json:"mute,omitempty"` + Deaf bool `json:"deaf,omitempty"` + + Roles []discord.Snowflake `json:"roles,omitempty"` + + // Only for ModifyMember, requires MOVE_MEMBER + VoiceChannel discord.Snowflake `json:"channel_id,omitempty"` +} + +// AddMember requires access(Token). +func (c *Client) AddMember(guildID, userID discord.Snowflake, + token string, data AnyMemberData) (*discord.Member, error) { + + // VoiceChannel doesn't belong here + data.VoiceChannel = 0 + + var param struct { + Token string `json:"access_token"` + AnyMemberData + } + + param.Token = token + param.AnyMemberData = data + + var mem *discord.Member + return mem, c.RequestJSON( + &mem, "PUT", + EndpointGuilds+guildID.String()+"/members/"+userID.String(), + httputil.WithJSONBody(c, param), + ) +} + +func (c *Client) ModifyMember( + guildID, userID discord.Snowflake, data AnyMemberData) error { + + return c.FastRequest( + "PATCH", + EndpointGuilds+guildID.String()+"/members/"+userID.String(), + httputil.WithJSONBody(c, data), + ) +} + +// ChangeOwnNickname only replies with the nickname back, so we're not even +// going to bother. +func (c *Client) ChangeOwnNickname( + guildID discord.Snowflake, nick string) error { + + var param struct { + Nick string `json:"nick"` + } + + param.Nick = nick + + return c.FastRequest( + "PATCH", + EndpointGuilds+guildID.String()+"/members/@me/nick", + httputil.WithJSONBody(c, param), + ) +} + +func (c *Client) AddRole(guildID, userID, roleID discord.Snowflake) error { + return c.FastRequest("PUT", EndpointGuilds+guildID.String()+ + "/members/"+userID.String()+ + "/roles/"+roleID.String()) +} + +func (c *Client) RemoveRole(guildID, userID, roleID discord.Snowflake) error { + return c.FastRequest("DELETE", EndpointGuilds+guildID.String()+ + "/members/"+userID.String()+ + "/roles/"+roleID.String()) +} + +// Kick requires KICK_MEMBERS. +func (c *Client) Kick(guildID, userID discord.Snowflake) error { + return c.FastRequest("DELETE", + EndpointGuilds+guildID.String()+"/members/"+userID.String()) +} + +func (c *Client) Bans(guildID discord.Snowflake) ([]discord.Ban, error) { + var bans []discord.Ban + return bans, c.RequestJSON(&bans, "GET", + EndpointGuilds+guildID.String()+"/bans") +} + +func (c *Client) GetBan( + guildID, userID discord.Snowflake) (*discord.Ban, error) { + + var ban *discord.Ban + return ban, c.RequestJSON(&ban, "GET", + EndpointGuilds+guildID.String()+"/bans/"+userID.String()) +} + +// Ban requires the BAN_MEMBERS permission. Days is the days back for Discord to +// delete the user's message, maximum 7 days. +func (c *Client) Ban( + guildID, userID discord.Snowflake, days uint, reason string) error { + + if days > 7 { + days = 7 + } + + var param struct { + DeleteDays uint `json:"delete_message_days,omitempty"` + Reason string `json:"reason,omitempty"` + } + + param.DeleteDays = days + param.Reason = reason + + return c.FastRequest( + "PUT", + EndpointGuilds+guildID.String()+"/bans/"+userID.String(), + httputil.WithJSONBody(c, param), + ) +} + +// Unban also requires BAN_MEMBERS. +func (c *Client) Unban(guildID, userID discord.Snowflake) error { + return c.FastRequest("DELETE", + EndpointGuilds+guildID.String()+"/bans/"+userID.String()) +} + +func (c *Client) Roles(guildID discord.Snowflake) ([]discord.Role, error) { + var roles []discord.Role + return roles, c.RequestJSON(&roles, "GET", + EndpointGuilds+guildID.String()+"/roles") +} + +type AnyRoleData struct { + Name string `json:"name,omitempty"` // "new role" + Color discord.Color `json:"color,omitempty"` // 0 + Hoist bool `json:"hoist,omitempty"` // false (show role separately) + + Mentionable bool `json:"mentionable,omitempty"` // false + Permissions discord.Permissions `json:"permissions,omitempty"` // @everyone +} + +func (c *Client) CreateRole( + guildID discord.Snowflake, data AnyRoleData) (*discord.Role, error) { + + var role *discord.Role + return role, c.RequestJSON( + &role, "POST", + EndpointGuilds+guildID.String()+"/roles", + httputil.WithJSONBody(c, data), + ) +} + +func (c *Client) MoveRole( + guildID, roleID discord.Snowflake, position int) ([]discord.Role, error) { + + var param struct { + ID discord.Snowflake `json:"id"` + Pos int `json:"position"` + } + + param.ID = roleID + param.Pos = position + + var roles []discord.Role + return roles, c.RequestJSON( + &roles, "PATCH", + EndpointGuilds+guildID.String()+"/roles", + httputil.WithJSONBody(c, param), + ) +} + +func (c *Client) ModifyRole(guildID, roleID discord.Snowflake, + data AnyRoleData) (*discord.Role, error) { + + var role *discord.Role + return role, c.RequestJSON( + &role, "PATCH", + EndpointGuilds+guildID.String()+"/roles/"+roleID.String(), + httputil.WithJSONBody(c, data), + ) +} + +func (c *Client) DeleteRole(guildID, roleID discord.Snowflake) error { + return c.FastRequest("DELETE", + EndpointGuilds+guildID.String()+"/roles/"+roleID.String()) +} diff --git a/discord/channel.go b/discord/channel.go index 466e6d3..03d2676 100644 --- a/discord/channel.go +++ b/discord/channel.go @@ -37,8 +37,8 @@ type Channel struct { UserRateLimit Seconds `json:"rate_limit_per_user,omitempty"` // Voice, so GuildVoice only - VoiceBitrate int `json:"bitrate,omitempty"` - VoiceUserLimit int `json:"user_limit,omitempty"` + VoiceBitrate uint `json:"bitrate,omitempty"` + VoiceUserLimit uint `json:"user_limit,omitempty"` } type ChannelType uint8 diff --git a/discord/guild.go b/discord/guild.go index fa1b3c1..e3b478a 100644 --- a/discord/guild.go +++ b/discord/guild.go @@ -109,3 +109,8 @@ type Member struct { Deaf bool `json:"deaf"` Mute bool `json:"mute"` } + +type Ban struct { + Reason string `json:"reason,omitempty"` + User User `json:"user"` +}