github.com/diamondburned/arikawa/v2@v2.1.0/api/member.go (about) 1 package api 2 3 import ( 4 "github.com/diamondburned/arikawa/v2/discord" 5 "github.com/diamondburned/arikawa/v2/internal/intmath" 6 "github.com/diamondburned/arikawa/v2/utils/httputil" 7 "github.com/diamondburned/arikawa/v2/utils/json/option" 8 ) 9 10 const MaxMemberFetchLimit = 1000 11 12 // Member returns a guild member object for the specified user. 13 func (c *Client) Member(guildID discord.GuildID, userID discord.UserID) (*discord.Member, error) { 14 var m *discord.Member 15 return m, c.RequestJSON(&m, "GET", EndpointGuilds+guildID.String()+"/members/"+userID.String()) 16 } 17 18 // Members returns a list of members of the guild with the passed id. This 19 // method automatically paginates until it reaches the passed limit, or, if the 20 // limit is set to 0, has fetched all members in the guild. 21 // 22 // As the underlying endpoint has a maximum of 1000 members per request, at 23 // maximum a total of limit/1000 rounded up requests will be made, although 24 // they may be less if no more members are available. 25 // 26 // When fetching the members, those with the smallest ID will be fetched first. 27 func (c *Client) Members(guildID discord.GuildID, limit uint) ([]discord.Member, error) { 28 return c.MembersAfter(guildID, 0, limit) 29 } 30 31 // MembersAfter returns a list of members of the guild with the passed id. This 32 // method automatically paginates until it reaches the passed limit, or, if the 33 // limit is set to 0, has fetched all members with an id higher than after. 34 // 35 // As the underlying endpoint has a maximum of 1000 members per request, at 36 // maximum a total of limit/1000 rounded up requests will be made, although 37 // they may be less, if no more members are available. 38 func (c *Client) MembersAfter( 39 guildID discord.GuildID, after discord.UserID, limit uint) ([]discord.Member, error) { 40 41 mems := make([]discord.Member, 0, limit) 42 43 fetch := uint(MaxMemberFetchLimit) 44 45 unlimited := limit == 0 46 47 for limit > 0 || unlimited { 48 // Only fetch as much as we need. Since limit gradually decreases, 49 // we only need to fetch intmath.Min(fetch, limit). 50 if limit > 0 { 51 fetch = uint(intmath.Min(MaxMemberFetchLimit, int(limit))) 52 limit -= fetch 53 } 54 55 m, err := c.membersAfter(guildID, after, fetch) 56 if err != nil { 57 return mems, err 58 } 59 mems = append(mems, m...) 60 61 // There aren't any to fetch, even if this is less than limit. 62 if len(m) < MaxMemberFetchLimit { 63 break 64 } 65 66 after = mems[len(mems)-1].User.ID 67 } 68 69 if len(mems) == 0 { 70 return nil, nil 71 } 72 73 return mems, nil 74 } 75 76 func (c *Client) membersAfter( 77 guildID discord.GuildID, after discord.UserID, limit uint) ([]discord.Member, error) { 78 79 switch { 80 case limit == 0: 81 limit = 0 82 case limit > 1000: 83 limit = 1000 84 } 85 86 var param struct { 87 After discord.UserID `schema:"after,omitempty"` 88 Limit uint `schema:"limit"` 89 } 90 91 param.Limit = limit 92 param.After = after 93 94 var mems []discord.Member 95 return mems, c.RequestJSON( 96 &mems, "GET", 97 EndpointGuilds+guildID.String()+"/members", 98 httputil.WithSchema(c, param), 99 ) 100 } 101 102 // https://discord.com/developers/docs/resources/guild#add-guild-member-json-params 103 type AddMemberData struct { 104 // Token is an oauth2 access token granted with the guilds.join to the 105 // bot's application for the user you want to add to the guild. 106 Token string `json:"access_token"` 107 // Nick is the value to set users nickname to. 108 // 109 // Requires MANAGE_NICKNAMES. 110 Nick option.String `json:"nick,omitempty"` 111 // Roles is an array of role ids the member is assigned. 112 // 113 // Requires MANAGE_ROLES. 114 Roles *[]discord.RoleID `json:"roles,omitempty"` 115 // Mute specifies whether the user is muted in voice channels. 116 // 117 // Requires MUTE_MEMBERS. 118 Mute option.Bool `json:"mute,omitempty"` 119 // Deaf specifies whether the user is deafened in voice channels. 120 // 121 // Requires DEAFEN_MEMBERS. 122 Deaf option.Bool `json:"deaf,omitempty"` 123 } 124 125 // AddMember adds a user to the guild, provided you have a valid oauth2 access 126 // token for the user with the guilds.join scope. Returns a 201 Created with 127 // the guild member as the body, or 204 No Content if the user is already a 128 // member of the guild. 129 // 130 // Fires a Guild Member Add Gateway event. 131 // 132 // The Authorization header must be a Bot token (belonging to the same 133 // application used for authorization), and the bot must be a member of the 134 // guild with CREATE_INSTANT_INVITE permission. 135 func (c *Client) AddMember( 136 guildID discord.GuildID, userID discord.UserID, data AddMemberData) (*discord.Member, error) { 137 var mem *discord.Member 138 return mem, c.RequestJSON( 139 &mem, "PUT", 140 EndpointGuilds+guildID.String()+"/members/"+userID.String(), 141 httputil.WithJSONBody(data), 142 ) 143 } 144 145 // https://discord.com/developers/docs/resources/guild#add-guild-member-json-params 146 type ModifyMemberData struct { 147 // Nick is the value to set users nickname to. 148 // 149 // Requires MANAGE_NICKNAMES. 150 Nick option.String `json:"nick,omitempty"` 151 // Roles is an array of role ids the member is assigned. 152 // 153 // Requires MANAGE_ROLES. 154 Roles *[]discord.RoleID `json:"roles,omitempty"` 155 // Mute specifies whether the user is muted in voice channels. 156 // 157 // Requires MUTE_MEMBERS. 158 Mute option.Bool `json:"mute,omitempty"` 159 // Deaf specifies whether the user is deafened in voice channels. 160 // 161 // Requires DEAFEN_MEMBERS. 162 Deaf option.Bool `json:"deaf,omitempty"` 163 164 // Voice channel is the id of channel to move user to (if they are 165 // connected to voice). 166 // 167 // Requires MOVE_MEMBER 168 VoiceChannel discord.ChannelID `json:"channel_id,omitempty"` 169 } 170 171 // ModifyMember modifies attributes of a guild member. If the channel_id is set 172 // to null, this will force the target user to be disconnected from voice. 173 // 174 // Fires a Guild Member Update Gateway event. 175 func (c *Client) ModifyMember(guildID discord.GuildID, userID discord.UserID, data ModifyMemberData) error { 176 177 return c.FastRequest( 178 "PATCH", 179 EndpointGuilds+guildID.String()+"/members/"+userID.String(), 180 httputil.WithJSONBody(data), 181 ) 182 } 183 184 // https://discord.com/developers/docs/resources/guild#get-guild-prune-count-query-string-params 185 type PruneCountData struct { 186 // Days is the number of days to count prune for (1 or more, default 7). 187 Days uint `schema:"days"` 188 // IncludedRoles are the role(s) to include. 189 IncludedRoles []discord.RoleID `schema:"include_roles,omitempty"` 190 } 191 192 // PruneCount returns the number of members that would be removed in a prune 193 // operation. Days must be 1 or more, default 7. 194 // 195 // By default, prune will not remove users with roles. You can optionally 196 // include specific roles in your prune by providing the IncludedRoles 197 // parameter. Any inactive user that has a subset of the provided role(s) 198 // will be counted in the prune and users with additional roles will not. 199 // 200 // Requires KICK_MEMBERS. 201 func (c *Client) PruneCount(guildID discord.GuildID, data PruneCountData) (uint, error) { 202 if data.Days == 0 { 203 data.Days = 7 204 } 205 206 var resp struct { 207 Pruned uint `json:"pruned"` 208 } 209 210 return resp.Pruned, c.RequestJSON( 211 &resp, "GET", 212 EndpointGuilds+guildID.String()+"/prune", 213 httputil.WithSchema(c, data), 214 ) 215 } 216 217 // https://discord.com/developers/docs/resources/guild#begin-guild-prune-query-string-params 218 type PruneData struct { 219 // Days is the number of days to prune (1 or more, default 7). 220 Days uint `schema:"days"` 221 // ReturnCount specifies whether 'pruned' is returned. Discouraged for 222 // large guilds. 223 ReturnCount bool `schema:"compute_prune_count"` 224 // IncludedRoles are the role(s) to include. 225 IncludedRoles []discord.RoleID `schema:"include_roles,omitempty"` 226 } 227 228 // Prune begins a prune. Days must be 1 or more, default 7. 229 // 230 // By default, prune will not remove users with roles. You can optionally 231 // include specific roles in your prune by providing the IncludedRoles 232 // parameter. Any inactive user that has a subset of the provided role(s) 233 // will be included in the prune and users with additional roles will not. 234 // 235 // Requires KICK_MEMBERS. 236 // Fires multiple Guild Member Remove Gateway events. 237 func (c *Client) Prune(guildID discord.GuildID, data PruneData) (uint, error) { 238 if data.Days == 0 { 239 data.Days = 7 240 } 241 242 var resp struct { 243 Pruned uint `json:"pruned"` 244 } 245 246 return resp.Pruned, c.RequestJSON( 247 &resp, "POST", 248 EndpointGuilds+guildID.String()+"/prune", 249 httputil.WithSchema(c, data), 250 ) 251 } 252 253 // Kick removes a member from a guild. 254 // 255 // Requires KICK_MEMBERS permission. 256 // Fires a Guild Member Remove Gateway event. 257 func (c *Client) Kick(guildID discord.GuildID, userID discord.UserID) error { 258 return c.KickWithReason(guildID, userID, "") 259 } 260 261 // KickWithReason removes a member from a guild. 262 // The reason, if non-empty, will be displayed in the audit log of the guild. 263 // 264 // Requires KICK_MEMBERS permission. 265 // Fires a Guild Member Remove Gateway event. 266 func (c *Client) KickWithReason( 267 guildID discord.GuildID, userID discord.UserID, reason string) error { 268 269 var data struct { 270 Reason string `schema:"reason,omitempty"` 271 } 272 273 data.Reason = reason 274 275 return c.FastRequest( 276 "DELETE", 277 EndpointGuilds+guildID.String()+"/members/"+userID.String(), 278 httputil.WithSchema(c, data), 279 ) 280 } 281 282 // Bans returns a list of ban objects for the users banned from this guild. 283 // 284 // Requires the BAN_MEMBERS permission. 285 func (c *Client) Bans(guildID discord.GuildID) ([]discord.Ban, error) { 286 var bans []discord.Ban 287 return bans, c.RequestJSON( 288 &bans, "GET", 289 EndpointGuilds+guildID.String()+"/bans", 290 ) 291 } 292 293 // GetBan returns a ban object for the given user. 294 // 295 // Requires the BAN_MEMBERS permission. 296 func (c *Client) GetBan(guildID discord.GuildID, userID discord.UserID) (*discord.Ban, error) { 297 var ban *discord.Ban 298 return ban, c.RequestJSON( 299 &ban, "GET", 300 EndpointGuilds+guildID.String()+"/bans/"+userID.String(), 301 ) 302 } 303 304 // https://discord.com/developers/docs/resources/guild#create-guild-ban-query-string-params 305 type BanData struct { 306 // DeleteDays is the number of days to delete messages for (0-7). 307 DeleteDays option.Uint `schema:"delete_message_days,omitempty"` 308 // Reason is the reason for the ban. 309 Reason option.String `schema:"reason,omitempty"` 310 } 311 312 // Ban creates a guild ban, and optionally delete previous messages sent by the 313 // banned user. 314 // 315 // Requires the BAN_MEMBERS permission. 316 func (c *Client) Ban(guildID discord.GuildID, userID discord.UserID, data BanData) error { 317 return c.FastRequest( 318 "PUT", 319 EndpointGuilds+guildID.String()+"/bans/"+userID.String(), 320 httputil.WithSchema(c, data), 321 ) 322 } 323 324 // Unban removes the ban for a user. 325 // 326 // Requires the BAN_MEMBERS permissions. 327 // Fires a Guild Ban Remove Gateway event. 328 func (c *Client) Unban(guildID discord.GuildID, userID discord.UserID) error { 329 return c.FastRequest("DELETE", EndpointGuilds+guildID.String()+"/bans/"+userID.String()) 330 }