diff --git a/app/services/slack/loads_slack_channel_members.rb b/app/services/slack/loads_slack_channel_members.rb index 6ee17fb..f684b0f 100644 --- a/app/services/slack/loads_slack_channel_members.rb +++ b/app/services/slack/loads_slack_channel_members.rb @@ -14,10 +14,21 @@ def call(channel:) def eligible_user_ids response = retry_when_rate_limited do - ClientWrapper.client.users_list + ClientWrapper.client.users_list(limit: 200) end - (response&.members || []).reject { |u| u.is_bot }.map(&:id) + members = get_paged_members(cursor: response&.response_metadata&.next_cursor, members: response&.members || []) + (members || []).reject { |u| u.is_bot }.map(&:id) + end + + def get_paged_members(cursor:, members:) + while cursor.present? + response = ClientWrapper.client.users_list(cursor: cursor, limit: 200) + members.append(response.members) + cursor = response.response_metadata&.next_cursor + end + + members.flatten end end end diff --git a/spec/lib/slack/loads_slack_channel_members_spec.rb b/spec/lib/slack/loads_slack_channel_members_spec.rb index d48f934..564ff43 100644 --- a/spec/lib/slack/loads_slack_channel_members_spec.rb +++ b/spec/lib/slack/loads_slack_channel_members_spec.rb @@ -35,6 +35,33 @@ expect(members).to eq(slack_members) end + it "loads members found in a channel when pagination is required" do + all_slack_users = (0..205).map do |id| + Slack::Messages::Message.new(id: "USER_ID_#{id}") + end + + slack_members = [ + "USER_ID_1", + "USER_ID_3", + "USER_ID_205" + ] + + response_metadata = Slack::Messages::Message.new(next_cursor: "cursor") + expect(@slack_client).to receive(:users_list).with(limit: 200) { + Slack::Messages::Message.new(ok: true, members: all_slack_users[0..199], response_metadata: response_metadata) + } + expect(@slack_client).to receive(:users_list).with(cursor: response_metadata.next_cursor, limit: 200) { + Slack::Messages::Message.new(ok: true, members: all_slack_users[200..]) + } + expect(@slack_client).to receive(:conversations_members).with(channel: "CHANNEL_ID", limit: 1000) { + Slack::Messages::Message.new(ok: true, members: slack_members) + } + + members = subject.call(channel: "CHANNEL_ID") + + expect(members).to eq(slack_members) + end + it "excludes bots from the returned users" do slack_user = Slack::Messages::Message.new(id: "USER_ID", is_bot: false) slack_app = Slack::Messages::Message.new(id: "APP_ID", is_bot: true)