diff --git a/.rubocop.yml b/.rubocop.yml index 100d21b06d..4c4466ca2d 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -125,5 +125,6 @@ Style/Documentation: Enabled: true Style/IfUnlessModifier: - Exclude: - - lib/discordrb/data/role.rb \ No newline at end of file + Exclude: + - lib/discordrb/data/channel.rb + - lib/discordrb/data/role.rb diff --git a/lib/discordrb/api/channel.rb b/lib/discordrb/api/channel.rb index de727961b8..cdcda18cf2 100644 --- a/lib/discordrb/api/channel.rb +++ b/lib/discordrb/api/channel.rb @@ -61,15 +61,22 @@ def delete(token, channel_id, reason = nil) ) end - # Get a list of messages from a channel's history - # https://discord.com/developers/docs/resources/channel#get-channel-messages + # @deprecated Please use {get_channel_messages} instead. + # https://docs.discord.com/developers/resources/message#get-channel-messages def messages(token, channel_id, amount, before = nil, after = nil, around = nil) - query_string = URI.encode_www_form({ limit: amount, before: before, after: after, around: around }.compact) + get_channel_messages(token, channel_id, limit: amount, after:, before:, around:) + end + + # Fetch the messages that have been sent in the channel. + # https://docs.discord.com/developers/resources/message#get-channel-messages + def get_channel_messages(token, channel_id, limit: 50, after: nil, before: nil, around: nil) + query = URI.encode_www_form({ limit:, after:, before:, around: }.compact) + Discordrb::API.request( :channels_cid_messages, channel_id, :get, - "#{Discordrb::API.api_base}/channels/#{channel_id}/messages?#{query_string}", + "#{Discordrb::API.api_base}/channels/#{channel_id}/messages?#{query}", Authorization: token ) end diff --git a/lib/discordrb/data/channel.rb b/lib/discordrb/data/channel.rb index 85070a91a8..247ccaf1fb 100644 --- a/lib/discordrb/data/channel.rb +++ b/lib/discordrb/data/channel.rb @@ -802,6 +802,51 @@ def load_message(message_id) alias_method :message, :load_message + # Fetch the messages that have been sent in the channel. + # @param limit [Integer, nil] The maximum number of messages to fetch, or `nil` for no limit. + # @param after [Message, Integer, String, Time, nil] Get messages sent after this snowflake ID. + # @param before [Message, Integer, String, Time, nil] Get messages sent before this snowflake ID. + # @param around [Message, Integer, String, Time, nil] Get messages sent around this snowflake ID. + # @param oldest_first [true, false] Whether the oldest messages in the channel should be fetched first. + # @return [Array] The messages that were fetched. By default, messages will be returned in descending + # order by message ID (newest messages first). On the contrary, when using the `after:` or `oldest_first:` parameters, + # messages will be returned in ascending order by message ID (oldest messages first). + def messages(limit: 100, after: nil, before: nil, around: nil, oldest_first: false) + if [before, after, around, oldest_first].count(&:itself) > 1 + raise ArgumentError, "'before', 'after', 'around', and 'oldest_first' are mutually exclusive" + end + + if around && (!limit || limit > 100) + raise ArgumentError, "You cannot fetch more than 100 messages when using the 'around' parameter" + end + + after = 0 if oldest_first + + rest = { + limit: limit && limit <= 100 ? limit : 100, + after: after.is_a?(Time) ? IDObject.synthesise(after) : after&.resolve_id, + before: before.is_a?(Time) ? IDObject.synthesise(before) : before&.resolve_id, + around: around.is_a?(Time) ? IDObject.synthesise(around) : around&.resolve_id + }.compact + + get_messages = proc do |query = nil| + response = API::Channel.get_channel_messages(@bot.token, @id, **rest, **query&.compact) + JSON.parse(response).map { |message| Message.new(message, @bot) } + end + + return get_messages.call if around + + paginator = Paginator.new(limit, after ? :up : :down) do |page| + if after + get_messages.call(after: page&.first&.id) + else + get_messages.call(before: page&.last&.id) + end + end + + paginator.to_a + end + # Requests the pinned messages in a channel. # @param limit [Integer, nil] the limit of how many pinned messages to retrieve. `nil` will return all the pinned messages. # @return [Array] the messages pinned in the channel.