1
0
Fork 0
mirror of https://github.com/diamondburned/arikawa.git synced 2025-03-22 18:09:21 +00:00

api: Add support for the X-Audit-Log-Reason header (#259)

* api: add support for the X-Audit-Log-Reason header

* api: inline reason parameter, where data struct has a single field
This commit is contained in:
Maximilian von Lindern 2021-08-15 18:33:33 +02:00 committed by GitHub
parent dbfc49fb08
commit 244570c280
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 303 additions and 157 deletions

View file

@ -80,3 +80,18 @@ type Session struct {
Token string
UserAgent string
}
// AuditLogReason is the type embedded in data structs when the action
// performed by calling that api endpoint supports attaching a custom audit log
// reason.
type AuditLogReason string
// Header returns a http.Header containing the reason, or nil if the reason is
// empty.
func (r AuditLogReason) Header() http.Header {
if len(r) == 0 {
return nil
}
return http.Header{"X-Audit-Log-Reason": []string{string(r)}}
}

View file

@ -90,8 +90,7 @@ func (c *Client) GuildCommands(
func (c *Client) GuildCommand(
appID discord.AppID,
guildID discord.GuildID,
commandID discord.CommandID) (discord.Command, error) {
guildID discord.GuildID, commandID discord.CommandID) (discord.Command, error) {
var cmd discord.Command
return cmd, c.RequestJSON(

View file

@ -71,6 +71,8 @@ type CreateChannelData struct {
//
// ChannelTypes: Voice
VoiceQualityMode discord.VideoQualityMode `json:"voice_quality_mode,omitempty"`
AuditLogReason `json:"-"`
}
// CreateChannel creates a new channel object for the guild.
@ -83,35 +85,46 @@ type CreateChannelData struct {
// Fires a ChannelCreate Gateway event.
func (c *Client) CreateChannel(
guildID discord.GuildID, data CreateChannelData) (*discord.Channel, error) {
var ch *discord.Channel
return ch, c.RequestJSON(
&ch, "POST",
EndpointGuilds+guildID.String()+"/channels",
httputil.WithJSONBody(data),
httputil.WithJSONBody(data), httputil.WithHeaders(data.Header()),
)
}
type MoveChannelData struct {
// ID is the channel id.
ID discord.ChannelID `json:"id"`
// Position is the sorting position of the channel.
Position option.Int `json:"position"`
// LockPermissions syncs the permission overwrites with the new parent,
// if moving to a new category.
LockPermissions option.Bool `json:"lock_permissions"`
// CategoryID is the new parent ID for the channel that is moved.
CategoryID discord.ChannelID `json:"parent_id"`
}
type (
MoveChannelsData struct {
// Channels are the channels to be moved.
Channels []MoveChannelData
// MoveChannel modifies the position of channels in the guild.
AuditLogReason
}
MoveChannelData struct {
// ID is the channel id.
ID discord.ChannelID `json:"id"`
// Position is the sorting position of the channel.
Position option.Int `json:"position"`
// LockPermissions syncs the permission overwrites with the new parent,
// if moving to a new category.
LockPermissions option.Bool `json:"lock_permissions"`
// CategoryID is the new parent ID for the channel that is moved.
CategoryID discord.ChannelID `json:"parent_id"`
}
)
// MoveChannels modifies the position of channels in the guild.
//
// Requires MANAGE_CHANNELS.
//
// Fires multiple Channel Update Gateway events.
func (c *Client) MoveChannel(guildID discord.GuildID, data []MoveChannelData) error {
func (c *Client) MoveChannels(guildID discord.GuildID, data MoveChannelsData) error {
return c.FastRequest(
"PATCH",
EndpointGuilds+guildID.String()+"/channels", httputil.WithJSONBody(data),
EndpointGuilds+guildID.String()+"/channels",
httputil.WithJSONBody(data.Channels), httputil.WithHeaders(data.Header()),
)
}
@ -187,6 +200,8 @@ type ModifyChannelData struct {
// Locked specifies whether the thread is locked. When a thread is locked,
// only users with MANAGE_THREADS can unarchive it.
Locked option.Bool `json:"locked,omitempty"`
AuditLogReason `json:"-"`
}
// ModifyChannel updates a channel's settings.
@ -201,7 +216,10 @@ type ModifyChannelData struct {
// Fires a Channel Update event when modifying a guild channel, and a Thread
// Update event when modifying a thread.
func (c *Client) ModifyChannel(channelID discord.ChannelID, data ModifyChannelData) error {
return c.FastRequest("PATCH", EndpointChannels+channelID.String(), httputil.WithJSONBody(data))
return c.FastRequest(
"PATCH", EndpointChannels+channelID.String(),
httputil.WithJSONBody(data), httputil.WithHeaders(data.Header()),
)
}
// DeleteChannel deletes a channel, or closes a private message. Requires the
@ -210,8 +228,13 @@ func (c *Client) ModifyChannel(channelID discord.ChannelID, data ModifyChannelDa
// Channel Update Gateway event will fire for each of them.
//
// Fires a Channel Delete Gateway event.
func (c *Client) DeleteChannel(channelID discord.ChannelID) error {
return c.FastRequest("DELETE", EndpointChannels+channelID.String())
func (c *Client) DeleteChannel(
channelID discord.ChannelID, reason AuditLogReason) error {
return c.FastRequest(
"DELETE", EndpointChannels+channelID.String(),
httputil.WithHeaders(reason.Header()),
)
}
// https://discord.com/developers/docs/resources/channel#edit-channel-permissions-json-params
@ -222,6 +245,8 @@ type EditChannelPermissionData struct {
Allow discord.Permissions `json:"allow,string"`
// Deny is a permission bit set for denied permissions.
Deny discord.Permissions `json:"deny,string"`
AuditLogReason `json:"-"`
}
// EditChannelPermission edits the channel's permission overwrites for a user
@ -234,7 +259,7 @@ func (c *Client) EditChannelPermission(
return c.FastRequest(
"PUT", EndpointChannels+channelID.String()+"/permissions/"+overwriteID.String(),
httputil.WithJSONBody(data),
httputil.WithJSONBody(data), httputil.WithHeaders(data.Header()),
)
}
@ -242,10 +267,12 @@ func (c *Client) EditChannelPermission(
// role in a channel. Only usable for guild channels.
//
// Requires the MANAGE_ROLES permission.
func (c *Client) DeleteChannelPermission(channelID discord.ChannelID, overwriteID discord.Snowflake) error {
func (c *Client) DeleteChannelPermission(
channelID discord.ChannelID, overwriteID discord.Snowflake, reason AuditLogReason) error {
return c.FastRequest(
"DELETE",
EndpointChannels+channelID.String()+"/permissions/"+overwriteID.String(),
"DELETE", EndpointChannels+channelID.String()+"/permissions/"+overwriteID.String(),
httputil.WithHeaders(reason.Header()),
)
}
@ -265,20 +292,30 @@ func (c *Client) PinnedMessages(channelID discord.ChannelID) ([]discord.Message,
// PinMessage pins a message in a channel.
//
// Requires the MANAGE_MESSAGES permission.
func (c *Client) PinMessage(channelID discord.ChannelID, messageID discord.MessageID) error {
return c.FastRequest("PUT", EndpointChannels+channelID.String()+"/pins/"+messageID.String())
func (c *Client) PinMessage(
channelID discord.ChannelID, messageID discord.MessageID, reason AuditLogReason) error {
return c.FastRequest(
"PUT", EndpointChannels+channelID.String()+"/pins/"+messageID.String(),
httputil.WithHeaders(reason.Header()),
)
}
// UnpinMessage deletes a pinned message in a channel.
//
// Requires the MANAGE_MESSAGES permission.
func (c *Client) UnpinMessage(channelID discord.ChannelID, messageID discord.MessageID) error {
return c.FastRequest("DELETE", EndpointChannels+channelID.String()+"/pins/"+messageID.String())
func (c *Client) UnpinMessage(
channelID discord.ChannelID, messageID discord.MessageID, reason AuditLogReason) error {
return c.FastRequest(
"DELETE", EndpointChannels+channelID.String()+"/pins/"+messageID.String(),
httputil.WithHeaders(reason.Header()),
)
}
// AddRecipient adds a user to a group direct message. As accessToken is needed,
// clearly this endpoint should only be used for OAuth. AccessToken can be
// obtained with the "gdm.join" scope.
// AddRecipient adds a user to a group direct message. As accessToken is
// needed, clearly this endpoint should only be used for OAuth. AccessToken can
// be obtained with the "gdm.join" scope.
func (c *Client) AddRecipient(
channelID discord.ChannelID, userID discord.UserID, accessToken, nickname string) error {
@ -311,8 +348,8 @@ type Ack struct {
}
// Ack marks the read state of a channel. This is undocumented. The method will
// write to the ack variable passed in. If this method is called asynchronously,
// then ack should be mutex guarded.
// write to the ack variable passed in. If this method is called
// asynchronously, then ack should be mutex guarded.
func (c *Client) Ack(channelID discord.ChannelID, messageID discord.MessageID, ack *Ack) error {
return c.RequestJSON(
ack, "POST",
@ -337,6 +374,8 @@ type StartThreadData struct {
//
// This field can only be used when starting a thread without a message
Type discord.ChannelType `json:"type,omitempty"` // we can omit, since thread types start at 10
AuditLogReason `json:"-"`
}
// StartThreadWithMessage creates a new thread from an existing message.
@ -357,7 +396,7 @@ func (c *Client) StartThreadWithMessage(
return ch, c.RequestJSON(
&ch, "POST",
EndpointChannels+channelID.String()+"/messages/"+messageID.String()+"/threads",
httputil.WithJSONBody(data),
httputil.WithJSONBody(data), httputil.WithHeaders(data.Header()),
)
}
@ -372,7 +411,7 @@ func (c *Client) StartThreadWithoutMessage(
return ch, c.RequestJSON(
&ch, "POST",
EndpointChannels+channelID.String()+"/threads",
httputil.WithJSONBody(data),
httputil.WithJSONBody(data), httputil.WithHeaders(data.Header()),
)
}

View file

@ -26,14 +26,18 @@ type CreateEmojiData struct {
Image Image `json:"image"`
// Roles are the roles that can use the emoji.
Roles *[]discord.RoleID `json:"roles,omitempty"`
AuditLogReason `json:"-"`
}
// 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).
// "image/gif". However, ContentType can also be automatically detected (though
// shouldn't be relied on).
//
// Emojis and animated emojis have a maximum file size of 256kb.
func (c *Client) CreateEmoji(guildID discord.GuildID, data CreateEmojiData) (*discord.Emoji, error) {
func (c *Client) CreateEmoji(
guildID discord.GuildID, data CreateEmojiData) (*discord.Emoji, error) {
// Max 256KB
if err := data.Image.Validate(256 * 1000); err != nil {
@ -44,7 +48,7 @@ func (c *Client) CreateEmoji(guildID discord.GuildID, data CreateEmojiData) (*di
return emj, c.RequestJSON(
&emj, "POST",
EndpointGuilds+guildID.String()+"/emojis",
httputil.WithJSONBody(data),
httputil.WithJSONBody(data), httputil.WithHeaders(data.Header()),
)
}
@ -54,24 +58,34 @@ type ModifyEmojiData struct {
Name string `json:"name,omitempty"`
// Roles are the roles that can use the emoji.
Roles *[]discord.RoleID `json:"roles,omitempty"`
AuditLogReason `json:"-"`
}
// ModifyEmoji changes an existing emoji. This requires MANAGE_EMOJIS. Name and
// roles are optional fields (though you'd want to change either though).
//
// Fires a Guild Emojis Update Gateway event.
func (c *Client) ModifyEmoji(guildID discord.GuildID, emojiID discord.EmojiID, data ModifyEmojiData) error {
func (c *Client) ModifyEmoji(
guildID discord.GuildID, emojiID discord.EmojiID, data ModifyEmojiData) error {
return c.FastRequest(
"PATCH",
EndpointGuilds+guildID.String()+"/emojis/"+emojiID.String(),
httputil.WithJSONBody(data),
httputil.WithJSONBody(data), httputil.WithHeaders(data.Header()),
)
}
// Delete the given emoji.
// DeleteEmoji deletes the given emoji.
//
// Requires the MANAGE_EMOJIS permission.
//
// Fires a Guild Emojis Update Gateway event.
func (c *Client) DeleteEmoji(guildID discord.GuildID, emojiID discord.EmojiID) error {
return c.FastRequest("DELETE", EndpointGuilds+guildID.String()+"/emojis/"+emojiID.String())
func (c *Client) DeleteEmoji(
guildID discord.GuildID, emojiID discord.EmojiID, reason AuditLogReason) error {
return c.FastRequest(
"DELETE", EndpointGuilds+guildID.String()+"/emojis/"+emojiID.String(),
httputil.WithHeaders(reason.Header()),
)
}

View file

@ -79,6 +79,7 @@ func (c *Client) CreateGuild(data CreateGuildData) (*discord.Guild, error) {
}
// Guild returns the guild object for the given id.
//
// ApproximateMembers and ApproximatePresences will not be set.
func (c *Client) Guild(id discord.GuildID) (*discord.Guild, error) {
var g *discord.Guild
@ -94,9 +95,9 @@ func (c *Client) GuildPreview(id discord.GuildID) (*discord.GuildPreview, error)
return g, c.RequestJSON(&g, "GET", EndpointGuilds+id.String()+"/preview")
}
// GuildWithCount returns the guild object for the given id.
// This will also set the ApproximateMembers and ApproximatePresences fields
// of the guild struct.
// GuildWithCount returns the guild object for the given id. This will also
// set the ApproximateMembers and ApproximatePresences fields of the guild
// struct.
func (c *Client) GuildWithCount(id discord.GuildID) (*discord.Guild, error) {
var g *discord.Guild
return g, c.RequestJSON(
@ -217,9 +218,7 @@ func (c *Client) GuildsAfter(after discord.GuildID, limit uint) ([]discord.Guild
return guilds, nil
}
func (c *Client) guildsRange(
before, after discord.GuildID, limit uint) ([]discord.Guild, error) {
func (c *Client) guildsRange(before, after discord.GuildID, limit uint) ([]discord.Guild, error) {
var param struct {
Before discord.GuildID `schema:"before,omitempty"`
After discord.GuildID `schema:"after,omitempty"`
@ -304,16 +303,21 @@ type ModifyGuildData struct {
//
// This defaults to "en-US".
PreferredLocale option.NullableString `json:"preferred_locale,omitempty"`
AuditLogReason `json:"-"`
}
// ModifyGuild modifies a guild's settings. Requires the MANAGE_GUILD permission.
// ModifyGuild modifies a guild's settings.
//
// Requires the MANAGE_GUILD permission.
//
// Fires a Guild Update Gateway event.
func (c *Client) ModifyGuild(id discord.GuildID, data ModifyGuildData) (*discord.Guild, error) {
var g *discord.Guild
return g, c.RequestJSON(
&g, "PATCH",
EndpointGuilds+id.String(),
httputil.WithJSONBody(data),
httputil.WithJSONBody(data), httputil.WithHeaders(data.Header()),
)
}
@ -325,7 +329,7 @@ func (c *Client) DeleteGuild(id discord.GuildID) error {
return c.FastRequest("DELETE", EndpointGuilds+id.String())
}
// GuildVoiceRegions is the same as /voice, but returns VIP ones as well if
// VoiceRegionsGuild is the same as /voice, but returns VIP ones as well if
// available.
func (c *Client) VoiceRegionsGuild(guildID discord.GuildID) ([]discord.VoiceRegion, error) {
var vrs []discord.VoiceRegion
@ -369,6 +373,7 @@ func (c *Client) AuditLog(guildID discord.GuildID, data AuditLogData) (*discord.
//
// Requires the MANAGE_GUILD permission.
func (c *Client) Integrations(guildID discord.GuildID) ([]discord.Integration, error) {
var ints []discord.Integration
return ints, c.RequestJSON(&ints, "GET", EndpointGuilds+guildID.String()+"/integrations")
}
@ -377,10 +382,11 @@ func (c *Client) Integrations(guildID discord.GuildID) ([]discord.Integration, e
// the guild.
//
// Requires the MANAGE_GUILD permission.
//
// Fires a Guild Integrations Update Gateway event.
func (c *Client) AttachIntegration(
guildID discord.GuildID, integrationID discord.IntegrationID,
integrationType discord.Service) error {
guildID discord.GuildID,
integrationID discord.IntegrationID, integrationType discord.Service) error {
var param struct {
Type discord.Service `json:"type"`
@ -416,7 +422,9 @@ type ModifyIntegrationData struct {
// Requires the MANAGE_GUILD permission.
// Fires a Guild Integrations Update Gateway event.
func (c *Client) ModifyIntegration(
guildID discord.GuildID, integrationID discord.IntegrationID, data ModifyIntegrationData) error {
guildID discord.GuildID,
integrationID discord.IntegrationID, data ModifyIntegrationData) error {
return c.FastRequest(
"PATCH",
EndpointGuilds+guildID.String()+"/integrations/"+integrationID.String(),
@ -424,8 +432,12 @@ func (c *Client) ModifyIntegration(
)
}
// Sync an integration. Requires the MANAGE_GUILD permission.
func (c *Client) SyncIntegration(guildID discord.GuildID, integrationID discord.IntegrationID) error {
// SyncIntegration syncs an integration.
//
// Requires the MANAGE_GUILD permission.
func (c *Client) SyncIntegration(
guildID discord.GuildID, integrationID discord.IntegrationID) error {
return c.FastRequest(
"POST",
EndpointGuilds+guildID.String()+"/integrations/"+integrationID.String()+"/sync",
@ -451,6 +463,8 @@ type ModifyGuildWidgetData struct {
Enabled option.Bool `json:"enabled,omitempty"`
// ChannelID is the widget channel ID.
ChannelID discord.ChannelID `json:"channel_id,omitempty"`
AuditLogReason `json:"-"`
}
// ModifyGuildWidget modifies a guild widget object for the guild.
@ -463,7 +477,7 @@ func (c *Client) ModifyGuildWidget(
return w, c.RequestJSON(
&w, "PATCH",
EndpointGuilds+guildID.String()+"/widget",
httputil.WithJSONBody(data),
httputil.WithJSONBody(data), httputil.WithHeaders(data.Header()),
)
}
@ -526,7 +540,9 @@ func (c *Client) GuildWidgetImageURL(guildID discord.GuildID, img GuildWidgetIma
// GuildWidgetImage returns a PNG image widget for the guild. Requires no permissions
// or authentication.
func (c *Client) GuildWidgetImage(guildID discord.GuildID, img GuildWidgetImageStyle) (io.ReadCloser, error) {
func (c *Client) GuildWidgetImage(
guildID discord.GuildID, img GuildWidgetImageStyle) (io.ReadCloser, error) {
r, err := c.Request("GET", c.GuildWidgetImageURL(guildID, img))
if err != nil {
return nil, err

View file

@ -263,7 +263,7 @@ func (c *Client) EditInteractionFollowup(
EndpointWebhooks+appID.String()+"/"+token+"/messages/"+messageID.String())
}
// DeleteInteractionFollowup deletes a followup message for an interaction
// DeleteInteractionFollowup deletes a followup message for an interaction.
func (c *Client) DeleteInteractionFollowup(
appID discord.AppID, messageID discord.MessageID, token string) error {

View file

@ -19,7 +19,8 @@ func (c *Client) Invite(code string) (*discord.Invite, error) {
)
}
// Invite returns an invite object for the given code and fills ApproxMembers.
// InviteWithCounts returns an invite object for the given code and fills
// ApproxMembers.
func (c *Client) InviteWithCounts(code string) (*discord.Invite, error) {
var params struct {
WithCounts bool `schema:"with_counts,omitempty"`
@ -75,6 +76,8 @@ type CreateInviteData struct {
//
// Default: false
Unique bool `json:"unique,omitempty"`
AuditLogReason `json:"-"`
}
// CreateInvite creates a new invite object for the channel. Only usable for
@ -83,11 +86,12 @@ type CreateInviteData struct {
// Requires the CREATE_INSTANT_INVITE permission.
func (c *Client) CreateInvite(
channelID discord.ChannelID, data CreateInviteData) (*discord.Invite, error) {
var inv *discord.Invite
return inv, c.RequestJSON(
&inv, "POST",
EndpointChannels+channelID.String()+"/invites",
httputil.WithJSONBody(data),
httputil.WithJSONBody(data), httputil.WithHeaders(data.Header()),
)
}
@ -110,8 +114,13 @@ func (c *Client) JoinInvite(code string) (*JoinedInvite, error) {
//
// Requires the MANAGE_CHANNELS permission on the channel this invite belongs
// to, or MANAGE_GUILD to remove any invite across the guild.
// Fires a Invite Delete Gateway event.
func (c *Client) DeleteInvite(code string) (*discord.Invite, error) {
//
// Fires an Invite Delete Gateway event.
func (c *Client) DeleteInvite(code string, reason AuditLogReason) (*discord.Invite, error) {
var inv *discord.Invite
return inv, c.RequestJSON(&inv, "DELETE", EndpointInvites+code)
return inv, c.RequestJSON(
&inv,
"DELETE", EndpointInvites+code,
httputil.WithHeaders(reason.Header()),
)
}

View file

@ -134,6 +134,7 @@ type AddMemberData struct {
// guild with CREATE_INSTANT_INVITE permission.
func (c *Client) AddMember(
guildID discord.GuildID, userID discord.UserID, data AddMemberData) (*discord.Member, error) {
var mem *discord.Member
return mem, c.RequestJSON(
&mem, "PUT",
@ -166,18 +167,21 @@ type ModifyMemberData struct {
//
// Requires MOVE_MEMBER
VoiceChannel discord.ChannelID `json:"channel_id,omitempty"`
AuditLogReason `json:"-"`
}
// ModifyMember modifies attributes of a guild member. If the channel_id is set
// to null, this will force the target user to be disconnected from voice.
//
// Fires a Guild Member Update Gateway event.
func (c *Client) ModifyMember(guildID discord.GuildID, userID discord.UserID, data ModifyMemberData) error {
func (c *Client) ModifyMember(
guildID discord.GuildID, userID discord.UserID, data ModifyMemberData) error {
return c.FastRequest(
"PATCH",
EndpointGuilds+guildID.String()+"/members/"+userID.String(),
httputil.WithJSONBody(data),
httputil.WithJSONBody(data), httputil.WithHeaders(data.Header()),
)
}
@ -223,6 +227,8 @@ type PruneData struct {
ReturnCount bool `schema:"compute_prune_count"`
// IncludedRoles are the role(s) to include.
IncludedRoles []discord.RoleID `schema:"include_roles,omitempty"`
AuditLogReason `schema:"-"`
}
// Prune begins a prune. Days must be 1 or more, default 7.
@ -233,6 +239,7 @@ type PruneData struct {
// will be included in the prune and users with additional roles will not.
//
// Requires KICK_MEMBERS.
//
// Fires multiple Guild Member Remove Gateway events.
func (c *Client) Prune(guildID discord.GuildID, data PruneData) (uint, error) {
if data.Days == 0 {
@ -246,36 +253,28 @@ func (c *Client) Prune(guildID discord.GuildID, data PruneData) (uint, error) {
return resp.Pruned, c.RequestJSON(
&resp, "POST",
EndpointGuilds+guildID.String()+"/prune",
httputil.WithSchema(c, data),
httputil.WithSchema(c, data), httputil.WithHeaders(data.Header()),
)
}
// Kick removes a member from a guild.
//
// Requires KICK_MEMBERS permission.
//
// Fires a Guild Member Remove Gateway event.
func (c *Client) Kick(guildID discord.GuildID, userID discord.UserID) error {
return c.KickWithReason(guildID, userID, "")
}
// KickWithReason removes a member from a guild.
// The reason, if non-empty, will be displayed in the audit log of the guild.
//
// Requires KICK_MEMBERS permission.
// Fires a Guild Member Remove Gateway event.
// KickWithReason is the same as Kick, but adds the given reason to the audit
// log.
func (c *Client) KickWithReason(
guildID discord.GuildID, userID discord.UserID, reason string) error {
var data struct {
Reason string `schema:"reason,omitempty"`
}
data.Reason = reason
guildID discord.GuildID, userID discord.UserID, reason AuditLogReason) error {
return c.FastRequest(
"DELETE",
EndpointGuilds+guildID.String()+"/members/"+userID.String(),
httputil.WithSchema(c, data),
httputil.WithHeaders(reason.Header()),
)
}
@ -305,26 +304,34 @@ func (c *Client) GetBan(guildID discord.GuildID, userID discord.UserID) (*discor
type BanData struct {
// DeleteDays is the number of days to delete messages for (0-7).
DeleteDays option.Uint `schema:"delete_message_days,omitempty"`
// Reason is the reason for the ban.
Reason option.String `schema:"reason,omitempty"`
AuditLogReason `schema:"-"`
}
// Ban creates a guild ban, and optionally delete previous messages sent by the
// banned user.
//
// Requires the BAN_MEMBERS permission.
//
// Fires a Guild Ban Add Gateway event.
func (c *Client) Ban(guildID discord.GuildID, userID discord.UserID, data BanData) error {
return c.FastRequest(
"PUT",
EndpointGuilds+guildID.String()+"/bans/"+userID.String(),
httputil.WithSchema(c, data),
httputil.WithSchema(c, data), httputil.WithHeaders(data.Header()),
)
}
// Unban removes the ban for a user.
//
// Requires the BAN_MEMBERS permissions.
//
// Fires a Guild Ban Remove Gateway event.
func (c *Client) Unban(guildID discord.GuildID, userID discord.UserID) error {
return c.FastRequest("DELETE", EndpointGuilds+guildID.String()+"/bans/"+userID.String())
func (c *Client) Unban(
guildID discord.GuildID, userID discord.UserID, reason AuditLogReason) error {
return c.FastRequest(
"DELETE", EndpointGuilds+guildID.String()+"/bans/"+userID.String(),
httputil.WithHeaders(reason.Header()),
)
}

View file

@ -155,7 +155,8 @@ func (c *Client) MessagesAfter(
}
func (c *Client) messagesRange(
channelID discord.ChannelID, before, after, around discord.MessageID, limit uint) ([]discord.Message, error) {
channelID discord.ChannelID,
before, after, around discord.MessageID, limit uint) ([]discord.Message, error) {
switch {
case limit == 0:
@ -189,7 +190,9 @@ func (c *Client) messagesRange(
//
// If operating on a guild channel, this endpoint requires the
// READ_MESSAGE_HISTORY permission to be present on the current user.
func (c *Client) Message(channelID discord.ChannelID, messageID discord.MessageID) (*discord.Message, error) {
func (c *Client) Message(
channelID discord.ChannelID, messageID discord.MessageID) (*discord.Message, error) {
var msg *discord.Message
return msg, c.RequestJSON(&msg, "GET",
EndpointChannels+channelID.String()+"/messages/"+messageID.String())
@ -203,8 +206,7 @@ func (c *Client) Message(channelID discord.ChannelID, messageID discord.MessageI
// Fires a Message Create Gateway event.
func (c *Client) SendTextReply(
channelID discord.ChannelID,
content string,
referenceID discord.MessageID) (*discord.Message, error) {
content string, referenceID discord.MessageID) (*discord.Message, error) {
return c.SendMessageComplex(channelID, SendMessageData{
Content: content,
@ -234,8 +236,7 @@ func (c *Client) SendEmbeds(
// Fires a Message Create Gateway event.
func (c *Client) SendEmbedReply(
channelID discord.ChannelID,
e discord.Embed,
referenceID discord.MessageID) (*discord.Message, error) {
e discord.Embed, referenceID discord.MessageID) (*discord.Message, error) {
return c.SendMessageComplex(channelID, SendMessageData{
Embeds: []discord.Embed{e},
@ -250,7 +251,9 @@ func (c *Client) SendEmbedReply(
//
// Fires a Message Create Gateway event.
func (c *Client) SendMessage(
channelID discord.ChannelID, content string, embeds ...discord.Embed) (*discord.Message, error) {
channelID discord.ChannelID,
content string, embeds ...discord.Embed) (*discord.Message, error) {
data := SendMessageData{
Content: content,
Embeds: embeds,
@ -265,10 +268,9 @@ func (c *Client) SendMessage(
//
// Fires a Message Create Gateway event.
func (c *Client) SendMessageReply(
channelID discord.ChannelID,
content string,
embed *discord.Embed,
referenceID discord.MessageID) (*discord.Message, error) {
channelID discord.ChannelID, content string,
embed *discord.Embed, referenceID discord.MessageID) (*discord.Message, error) {
data := SendMessageData{
Content: content,
Reference: &discord.MessageReference{MessageID: referenceID},
@ -312,7 +314,8 @@ func (data EditMessageData) WriteMultipart(body *multipart.Writer) error {
// EditText edits the contents of a previously sent message. For more
// documentation, refer to EditMessageComplex.
func (c *Client) EditText(
channelID discord.ChannelID, messageID discord.MessageID, content string) (*discord.Message, error) {
channelID discord.ChannelID,
messageID discord.MessageID, content string) (*discord.Message, error) {
return c.EditMessageComplex(channelID, messageID, EditMessageData{
Content: option.NewNullableString(content),
@ -322,7 +325,8 @@ func (c *Client) EditText(
// EditEmbeds edits the embed of a previously sent message. For more
// documentation, refer to EditMessageComplex.
func (c *Client) EditEmbeds(
channelID discord.ChannelID, messageID discord.MessageID, embeds ...discord.Embed) (*discord.Message, error) {
channelID discord.ChannelID,
messageID discord.MessageID, embeds ...discord.Embed) (*discord.Message, error) {
return c.EditMessageComplex(channelID, messageID, EditMessageData{
Embeds: &embeds,
@ -360,7 +364,9 @@ func (c *Client) EditMessage(
//
// Fires a Message Update Gateway event.
func (c *Client) EditMessageComplex(
channelID discord.ChannelID, messageID discord.MessageID, data EditMessageData) (*discord.Message, error) {
channelID discord.ChannelID,
messageID discord.MessageID, data EditMessageData) (*discord.Message, error) {
if data.AllowedMentions != nil {
if err := data.AllowedMentions.Verify(); err != nil {
return nil, errors.Wrap(err, "allowedMentions error")
@ -387,7 +393,9 @@ func (c *Client) EditMessageComplex(
// CrosspostMessage crossposts a message in a news channel to following channels.
// This endpoint requires the SEND_MESSAGES permission if the current user sent the message,
// or additionally the MANAGE_MESSAGES permission for all other messages.
func (c *Client) CrosspostMessage(channelID discord.ChannelID, messageID discord.MessageID) (*discord.Message, error) {
func (c *Client) CrosspostMessage(
channelID discord.ChannelID, messageID discord.MessageID) (*discord.Message, error) {
var msg *discord.Message
return msg, c.RequestJSON(
@ -400,9 +408,12 @@ func (c *Client) CrosspostMessage(channelID discord.ChannelID, messageID discord
// DeleteMessage delete a message. If operating on a guild channel and trying
// to delete a message that was not sent by the current user, this endpoint
// requires the MANAGE_MESSAGES permission.
func (c *Client) DeleteMessage(channelID discord.ChannelID, messageID discord.MessageID) error {
return c.FastRequest("DELETE", EndpointChannels+channelID.String()+
"/messages/"+messageID.String())
func (c *Client) DeleteMessage(
channelID discord.ChannelID, messageID discord.MessageID, reason AuditLogReason) error {
return c.FastRequest(
"DELETE", EndpointChannels+channelID.String()+"/messages/"+messageID.String(),
httputil.WithHeaders(reason.Header()))
}
// DeleteMessages deletes multiple messages in a single request. This endpoint
@ -418,21 +429,23 @@ func (c *Client) DeleteMessage(channelID discord.ChannelID, messageID discord.Me
// requests.
//
// Fires a Message Delete Bulk Gateway event.
func (c *Client) DeleteMessages(channelID discord.ChannelID, messageIDs []discord.MessageID) error {
func (c *Client) DeleteMessages(
channelID discord.ChannelID, messageIDs []discord.MessageID, reason AuditLogReason) error {
switch {
case len(messageIDs) == 0:
return nil
case len(messageIDs) == 1:
return c.DeleteMessage(channelID, messageIDs[0])
return c.DeleteMessage(channelID, messageIDs[0], reason)
case len(messageIDs) <= maxMessageDeleteLimit: // Fast path
return c.deleteMessages(channelID, messageIDs)
return c.deleteMessages(channelID, messageIDs, reason)
}
// If the number of messages to be deleted exceeds the amount discord is willing
// to accept at one time then batches of messages will be deleted
for start := 0; start < len(messageIDs); start += maxMessageDeleteLimit {
end := intmath.Min(len(messageIDs), start+maxMessageDeleteLimit)
err := c.deleteMessages(channelID, messageIDs[start:end])
err := c.deleteMessages(channelID, messageIDs[start:end], reason)
if err != nil {
return err
}
@ -441,7 +454,9 @@ func (c *Client) DeleteMessages(channelID discord.ChannelID, messageIDs []discor
return nil
}
func (c *Client) deleteMessages(channelID discord.ChannelID, messageIDs []discord.MessageID) error {
func (c *Client) deleteMessages(
channelID discord.ChannelID, messageIDs []discord.MessageID, reason AuditLogReason) error {
var param struct {
Messages []discord.MessageID `json:"messages"`
}
@ -451,6 +466,6 @@ func (c *Client) deleteMessages(channelID discord.ChannelID, messageIDs []discor
return c.FastRequest(
"POST",
EndpointChannels+channelID.String()+"/messages/bulk-delete",
httputil.WithJSONBody(param),
httputil.WithJSONBody(param), httputil.WithHeaders(reason.Header()),
)
}

View file

@ -15,8 +15,7 @@ const MaxMessageReactionFetchLimit = 100
// using this emoji, this endpoint requires the 'ADD_REACTIONS' permission to
// be present on the current user.
func (c *Client) React(
channelID discord.ChannelID,
messageID discord.MessageID, emoji discord.APIEmoji) error {
channelID discord.ChannelID, messageID discord.MessageID, emoji discord.APIEmoji) error {
return c.FastRequest(
"PUT",
@ -28,8 +27,7 @@ func (c *Client) React(
// Unreact removes a reaction the current user has made for the message.
func (c *Client) Unreact(
channelID discord.ChannelID,
messageID discord.MessageID, emoji discord.APIEmoji) error {
channelID discord.ChannelID, messageID discord.MessageID, emoji discord.APIEmoji) error {
return c.DeleteUserReaction(channelID, messageID, 0, emoji)
}
@ -45,8 +43,7 @@ func (c *Client) Unreact(
// When fetching the users, those with the smallest ID will be fetched first.
func (c *Client) Reactions(
channelID discord.ChannelID,
messageID discord.MessageID,
emoji discord.APIEmoji, limit uint) ([]discord.User, error) {
messageID discord.MessageID, emoji discord.APIEmoji, limit uint) ([]discord.User, error) {
return c.ReactionsAfter(channelID, messageID, 0, emoji, limit)
}
@ -60,10 +57,8 @@ func (c *Client) Reactions(
// maximum a total of limit/100 rounded up requests will be made, although they
// may be less, if no more guilds are available.
func (c *Client) ReactionsBefore(
channelID discord.ChannelID,
messageID discord.MessageID,
before discord.UserID,
emoji discord.APIEmoji, limit uint) ([]discord.User, error) {
channelID discord.ChannelID, messageID discord.MessageID,
before discord.UserID, emoji discord.APIEmoji, limit uint) ([]discord.User, error) {
users := make([]discord.User, 0, limit)
@ -108,10 +103,8 @@ func (c *Client) ReactionsBefore(
// maximum a total of limit/100 rounded up requests will be made, although they
// may be less, if no more guilds are available.
func (c *Client) ReactionsAfter(
channelID discord.ChannelID,
messageID discord.MessageID,
after discord.UserID,
emoji discord.APIEmoji, limit uint) ([]discord.User, error) {
channelID discord.ChannelID, messageID discord.MessageID,
after discord.UserID, emoji discord.APIEmoji, limit uint) ([]discord.User, error) {
users := make([]discord.User, 0, limit)
@ -150,10 +143,8 @@ func (c *Client) ReactionsAfter(
// reactionsRange get users before and after IDs. Before, after, and limit are
// optional. A maximum limit of only 100 reactions could be returned.
func (c *Client) reactionsRange(
channelID discord.ChannelID,
messageID discord.MessageID,
before, after discord.UserID,
emoji discord.APIEmoji, limit uint) ([]discord.User, error) {
channelID discord.ChannelID, messageID discord.MessageID,
before, after discord.UserID, emoji discord.APIEmoji, limit uint) ([]discord.User, error) {
switch {
case limit == 0:
@ -182,15 +173,13 @@ func (c *Client) reactionsRange(
)
}
// DeleteReaction deletes another user's reaction.
// DeleteUserReaction deletes another user's reaction.
//
// This endpoint requires the MANAGE_MESSAGES permission to be present on the
// current user.
func (c *Client) DeleteUserReaction(
channelID discord.ChannelID,
messageID discord.MessageID,
userID discord.UserID,
emoji discord.APIEmoji) error {
messageID discord.MessageID, userID discord.UserID, emoji discord.APIEmoji) error {
var user = "@me"
if userID > 0 {
@ -209,6 +198,7 @@ func (c *Client) DeleteUserReaction(
//
// This endpoint requires the MANAGE_MESSAGES permission to be present on the
// current user.
//
// Fires a Message Reaction Remove Emoji Gateway event.
func (c *Client) DeleteReactions(
channelID discord.ChannelID, messageID discord.MessageID, emoji discord.APIEmoji) error {
@ -225,6 +215,7 @@ func (c *Client) DeleteReactions(
//
// This endpoint requires the MANAGE_MESSAGES permission to be present on the
// current user.
//
// Fires a Message Reaction Remove All Gateway event.
func (c *Client) DeleteAllReactions(
channelID discord.ChannelID, messageID discord.MessageID) error {

View file

@ -6,24 +6,37 @@ import (
"github.com/diamondburned/arikawa/v3/utils/json/option"
)
// Adds a role to a guild member.
type AddRoleData struct {
AuditLogReason
}
// AddRole adds a role to a guild member.
//
// Requires the MANAGE_ROLES permission.
func (c *Client) AddRole(guildID discord.GuildID, userID discord.UserID, roleID discord.RoleID) error {
func (c *Client) AddRole(
guildID discord.GuildID,
userID discord.UserID, roleID discord.RoleID, data AddRoleData) error {
return c.FastRequest(
"PUT",
EndpointGuilds+guildID.String()+"/members/"+userID.String()+"/roles/"+roleID.String(),
httputil.WithHeaders(data.Header()),
)
}
// RemoveRole removes a role from a guild member.
//
// Requires the MANAGE_ROLES permission.
//
// Fires a Guild Member Update Gateway event.
func (c *Client) RemoveRole(guildID discord.GuildID, userID discord.UserID, roleID discord.RoleID) error {
func (c *Client) RemoveRole(
guildID discord.GuildID,
userID discord.UserID, roleID discord.RoleID, reason AuditLogReason) error {
return c.FastRequest(
"DELETE",
EndpointGuilds+guildID.String()+"/members/"+userID.String()+"/roles/"+roleID.String(),
httputil.WithHeaders(reason.Header()),
)
}
@ -56,40 +69,51 @@ type CreateRoleData struct {
//
// Default: false
Mentionable bool `json:"mentionable,omitempty"`
AddRoleData `json:"-"`
}
// CreateRole creates a new role for the guild.
//
// Requires the MANAGE_ROLES permission.
//
// Fires a Guild Role Create Gateway event.
func (c *Client) CreateRole(guildID discord.GuildID, data CreateRoleData) (*discord.Role, error) {
var role *discord.Role
return role, c.RequestJSON(
&role, "POST",
EndpointGuilds+guildID.String()+"/roles",
httputil.WithJSONBody(data),
httputil.WithJSONBody(data), httputil.WithHeaders(data.Header()),
)
}
// https://discord.com/developers/docs/resources/guild#modify-guild-role-positions-json-params
type MoveRoleData struct {
// ID is the id of the role.
ID discord.RoleID `json:"id"`
// Position is the sorting position of the role.
Position option.NullableInt `json:"position,omitempty"`
}
type (
MoveRolesData struct {
Roles []MoveRoleData
// MoveRole modifies the positions of a set of role objects for the guild.
AuditLogReason
}
// https://discord.com/developers/docs/resources/guild#modify-guild-role-positions-json-params
MoveRoleData struct {
// ID is the id of the role.
ID discord.RoleID `json:"id"`
// Position is the sorting position of the role.
Position option.NullableInt `json:"position,omitempty"`
}
)
// MoveRoles modifies the positions of a set of role objects for the guild.
//
// Requires the MANAGE_ROLES permission.
//
// Fires multiple Guild Role Update Gateway events.
func (c *Client) MoveRole(guildID discord.GuildID, data []MoveRoleData) ([]discord.Role, error) {
func (c *Client) MoveRoles(guildID discord.GuildID, data MoveRolesData) ([]discord.Role, error) {
var roles []discord.Role
return roles, c.RequestJSON(
&roles, "PATCH",
EndpointGuilds+guildID.String()+"/roles",
httputil.WithJSONBody(data),
httputil.WithJSONBody(data.Roles), httputil.WithHeaders(data.Header()),
)
}
@ -106,29 +130,33 @@ type ModifyRoleData struct {
Hoist option.NullableBool `json:"hoist,omitempty"`
// Mentionable specifies whether the role should be mentionable.
Mentionable option.NullableBool `json:"mentionable,omitempty"`
AddRoleData `json:"-"`
}
// ModifyRole modifies a guild role.
//
// Requires the MANAGE_ROLES permission.
func (c *Client) ModifyRole(
guildID discord.GuildID, roleID discord.RoleID,
data ModifyRoleData) (*discord.Role, error) {
guildID discord.GuildID, roleID discord.RoleID, data ModifyRoleData) (*discord.Role, error) {
var role *discord.Role
return role, c.RequestJSON(
&role, "PATCH",
EndpointGuilds+guildID.String()+"/roles/"+roleID.String(),
httputil.WithJSONBody(data),
httputil.WithJSONBody(data), httputil.WithHeaders(data.Header()),
)
}
// DeleteRole deletes a guild role.
//
// Requires the MANAGE_ROLES permission.
func (c *Client) DeleteRole(guildID discord.GuildID, roleID discord.RoleID) error {
func (c *Client) DeleteRole(
guildID discord.GuildID, roleID discord.RoleID, reason AuditLogReason) error {
return c.FastRequest(
"DELETE",
EndpointGuilds+guildID.String()+"/roles/"+roleID.String(),
httputil.WithHeaders(reason.Header()),
)
}

View file

@ -17,6 +17,8 @@ type CreateStageInstanceData struct {
//
// Defaults to discord.GuildOnlyStage.
PrivacyLevel discord.PrivacyLevel `json:"privacy_level,omitempty"`
AuditLogReason `json:"-"`
}
// CreateStageInstance creates a new Stage instance associated to a Stage
@ -30,7 +32,7 @@ func (c *Client) CreateStageInstance(
return s, c.RequestJSON(
&s, "POST",
EndpointStageInstances,
httputil.WithJSONBody(data),
httputil.WithJSONBody(data), httputil.WithHeaders(data.Header()),
)
}
@ -40,6 +42,8 @@ type UpdateStageInstanceData struct {
Topic string `json:"topic,omitempty"`
// PrivacyLevel is the privacy level of the Stage instance.
PrivacyLevel discord.PrivacyLevel `json:"privacy_level,omitempty"`
AuditLogReason `json:"-"`
}
// UpdateStageInstance updates fields of an existing Stage instance.
@ -51,10 +55,13 @@ func (c *Client) UpdateStageInstance(
return c.FastRequest(
"PATCH",
EndpointStageInstances+channelID.String(),
httputil.WithJSONBody(data),
httputil.WithJSONBody(data), httputil.WithHeaders(data.Header()),
)
}
func (c *Client) DeleteStageInstance(channelID discord.ChannelID) error {
return c.FastRequest("DELETE", EndpointStageInstances+channelID.String())
func (c *Client) DeleteStageInstance(channelID discord.ChannelID, reason AuditLogReason) error {
return c.FastRequest(
"DELETE", EndpointStageInstances+channelID.String(),
httputil.WithHeaders(reason.Header()),
)
}

View file

@ -32,12 +32,18 @@ type ModifySelfData struct {
Username option.String `json:"username,omitempty"`
// Avatar modifies the user's avatar.
Avatar *Image `json:"image,omitempty"`
AuditLogReason `json:"-"`
}
// ModifyMe modifies the requester's user account settings.
func (c *Client) ModifyMe(data ModifySelfData) (*discord.User, error) {
var u *discord.User
return u, c.RequestJSON(&u, "PATCH", EndpointMe, httputil.WithJSONBody(data))
return u, c.RequestJSON(
&u,
"PATCH", EndpointMe,
httputil.WithJSONBody(data), httputil.WithHeaders(data.Header()),
)
}
// ChangeOwnNickname modifies the nickname of the current user in a guild.