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