1
0
Fork 0
mirror of https://github.com/diamondburned/arikawa.git synced 2024-11-16 11:54:29 +00:00
arikawa/api/message_reaction.go

228 lines
6.6 KiB
Go
Raw Normal View History

2020-01-02 05:39:52 +00:00
package api
import (
2021-06-02 02:53:19 +00:00
"github.com/diamondburned/arikawa/v3/discord"
"github.com/diamondburned/arikawa/v3/internal/intmath"
"github.com/diamondburned/arikawa/v3/utils/httputil"
2020-01-02 05:39:52 +00:00
)
const MaxMessageReactionFetchLimit = 100
2020-05-11 22:06:19 +00:00
// React creates a reaction for the message.
//
// This endpoint requires the READ_MESSAGE_HISTORY permission to be present on
// the current user. Additionally, if nobody else has reacted to the message
// 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 {
return c.FastRequest(
"PUT",
EndpointChannels+channelID.String()+
"/messages/"+messageID.String()+
"/reactions/"+emoji.PathString()+"/@me",
)
2020-01-02 05:39:52 +00:00
}
2020-05-11 22:06:19 +00:00
// 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 {
return c.DeleteUserReaction(channelID, messageID, 0, emoji)
2020-01-23 05:13:53 +00:00
}
2020-05-16 23:35:57 +00:00
// Reactions returns a list of users that reacted with the passed Emoji. This
// method automatically paginates until it reaches the passed limit, or, if the
// limit is set to 0, has fetched all users within the passed range.
2020-05-11 22:06:19 +00:00
//
2020-05-16 23:35:57 +00:00
// As the underlying endpoint has a maximum of 100 users per request, at
// maximum a total of limit/100 rounded up requests will be made, although they
// may be less, if no more guilds are available.
//
// 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) {
2020-05-16 23:35:57 +00:00
2020-05-23 02:18:00 +00:00
return c.ReactionsAfter(channelID, messageID, 0, emoji, limit)
2020-05-16 23:35:57 +00:00
}
// ReactionsBefore returns a list of users that reacted with the passed Emoji.
// This method automatically paginates until it reaches the passed limit, or,
// if the limit is set to 0, has fetched all users with an id smaller than
// before.
2020-05-16 23:35:57 +00:00
//
// As the underlying endpoint has a maximum of 100 users per request, at
// 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) {
2020-01-02 05:39:52 +00:00
users := make([]discord.User, 0, limit)
2020-01-06 05:22:26 +00:00
fetch := uint(MaxMessageReactionFetchLimit)
2020-05-16 23:35:57 +00:00
unlimited := limit == 0
for limit > 0 || unlimited {
2020-05-16 23:35:57 +00:00
if limit > 0 {
// Only fetch as much as we need. Since limit gradually decreases,
2020-12-27 00:08:41 +00:00
// we only need to fetch intmath.Min(fetch, limit).
fetch = uint(intmath.Min(MaxMessageReactionFetchLimit, int(limit)))
2020-05-16 23:35:57 +00:00
limit -= fetch
}
2020-05-23 02:18:00 +00:00
r, err := c.reactionsRange(channelID, messageID, before, 0, emoji, fetch)
2020-01-06 05:22:26 +00:00
if err != nil {
return users, err
}
users = append(r, users...)
2020-01-06 05:22:26 +00:00
if len(r) < MaxMessageReactionFetchLimit {
2020-01-06 05:22:26 +00:00
break
}
2020-05-16 23:35:57 +00:00
before = r[0].ID
2020-01-06 05:22:26 +00:00
}
if len(users) == 0 {
return nil, nil
}
2020-01-06 05:22:26 +00:00
return users, nil
}
2020-05-16 23:35:57 +00:00
// ReactionsAfter returns a list of users that reacted with the passed Emoji.
// This method automatically paginates until it reaches the passed limit, or,
// if the limit is set to 0, has fetched all users with an id higher than
// after.
2020-05-16 23:35:57 +00:00
//
// As the underlying endpoint has a maximum of 100 users per request, at
// 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) {
2020-01-06 05:22:26 +00:00
users := make([]discord.User, 0, limit)
2020-01-06 05:22:26 +00:00
fetch := uint(MaxMessageReactionFetchLimit)
2020-05-16 23:35:57 +00:00
unlimited := limit == 0
for limit > 0 || unlimited {
2020-05-16 23:35:57 +00:00
if limit > 0 {
// Only fetch as much as we need. Since limit gradually decreases,
2020-12-27 00:08:41 +00:00
// we only need to fetch intmath.Min(fetch, limit).
fetch = uint(intmath.Min(MaxMessageReactionFetchLimit, int(limit)))
2020-05-16 23:35:57 +00:00
limit -= fetch
}
2020-05-23 02:18:00 +00:00
r, err := c.reactionsRange(channelID, messageID, 0, after, emoji, fetch)
2020-05-16 23:35:57 +00:00
if err != nil {
return users, err
}
users = append(users, r...)
if len(r) < MaxMessageReactionFetchLimit {
2020-05-16 23:35:57 +00:00
break
}
2020-01-06 05:22:26 +00:00
2020-05-22 22:59:27 +00:00
after = r[len(r)-1].ID
2020-05-16 23:35:57 +00:00
}
if len(users) == 0 {
return nil, nil
}
2020-05-16 23:35:57 +00:00
return users, nil
2020-01-02 05:39:52 +00:00
}
2020-05-16 23:35:57 +00:00
// reactionsRange get users before and after IDs. Before, after, and limit are
2020-01-06 05:22:26 +00:00
// optional. A maximum limit of only 100 reactions could be returned.
2020-05-16 23:35:57 +00:00
func (c *Client) reactionsRange(
channelID discord.ChannelID, messageID discord.MessageID,
before, after discord.UserID, emoji discord.APIEmoji, limit uint) ([]discord.User, error) {
2020-01-02 05:39:52 +00:00
2020-05-11 22:06:19 +00:00
switch {
case limit == 0:
2020-01-02 05:39:52 +00:00
limit = 25
2020-05-11 22:06:19 +00:00
case limit > 100:
2020-01-02 05:39:52 +00:00
limit = 100
}
2020-01-06 03:48:39 +00:00
var param struct {
Before discord.UserID `schema:"before,omitempty"`
After discord.UserID `schema:"after,omitempty"`
2020-01-02 05:39:52 +00:00
2020-01-06 03:48:39 +00:00
Limit uint `schema:"limit"`
2020-01-02 05:39:52 +00:00
}
2020-01-06 03:48:39 +00:00
param.Before = before
param.After = after
param.Limit = limit
var users []discord.User
2020-01-06 05:22:26 +00:00
return users, c.RequestJSON(
&users, "GET", EndpointChannels+channelID.String()+
"/messages/"+messageID.String()+
"/reactions/"+emoji.PathString(),
2020-01-06 05:22:26 +00:00
httputil.WithSchema(c, param),
)
2020-01-02 05:39:52 +00:00
}
// DeleteUserReaction deletes another user's reaction.
2020-05-11 22:06:19 +00:00
//
// This endpoint requires the MANAGE_MESSAGES permission to be present on the
// current user.
2020-01-23 05:13:53 +00:00
func (c *Client) DeleteUserReaction(
channelID discord.ChannelID,
messageID discord.MessageID, userID discord.UserID, emoji discord.APIEmoji) error {
2020-01-02 05:39:52 +00:00
var user = "@me"
if userID > 0 {
user = userID.String()
}
2020-05-12 02:05:08 +00:00
return c.FastRequest(
"DELETE",
EndpointChannels+channelID.String()+
"/messages/"+messageID.String()+
"/reactions/"+emoji.PathString()+"/"+user,
2020-05-12 02:05:08 +00:00
)
2020-01-02 05:39:52 +00:00
}
2020-05-11 22:06:19 +00:00
// DeleteReactions deletes all the reactions for a given emoji on a message.
//
// This endpoint requires the MANAGE_MESSAGES permission to be present on the
// current user.
//
2020-05-11 22:06:19 +00:00
// Fires a Message Reaction Remove Emoji Gateway event.
2020-01-23 05:13:53 +00:00
func (c *Client) DeleteReactions(
channelID discord.ChannelID, messageID discord.MessageID, emoji discord.APIEmoji) error {
2020-01-02 05:39:52 +00:00
return c.FastRequest(
2020-05-12 02:05:08 +00:00
"DELETE",
EndpointChannels+channelID.String()+
"/messages/"+messageID.String()+
"/reactions/"+emoji.PathString(),
2020-05-12 02:05:08 +00:00
)
2020-01-02 05:39:52 +00:00
}
2020-05-11 22:06:19 +00:00
// DeleteAllReactions deletes all reactions on a message.
//
// This endpoint requires the MANAGE_MESSAGES permission to be present on the
// current user.
//
2020-05-11 22:06:19 +00:00
// Fires a Message Reaction Remove All Gateway event.
func (c *Client) DeleteAllReactions(
channelID discord.ChannelID, messageID discord.MessageID) error {
2020-05-12 02:05:08 +00:00
return c.FastRequest(
"DELETE",
EndpointChannels+channelID.String()+"/messages/"+messageID.String()+"/reactions",
2020-05-12 02:05:08 +00:00
)
2020-01-02 05:39:52 +00:00
}