DEV: Cache slack users list for 10 minutes (#113)
This should help to avoid Slack API rate limiting in very large slack communities
This commit is contained in:
parent
55f9b7873b
commit
20f0b1c6ce
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
module DiscourseChatIntegration::Provider::SlackProvider
|
module DiscourseChatIntegration::Provider::SlackProvider
|
||||||
class SlackTranscript
|
class SlackTranscript
|
||||||
|
class UserFetchError < RuntimeError; end
|
||||||
|
|
||||||
attr_reader :users, :channel_id, :messages
|
attr_reader :users, :channel_id, :messages
|
||||||
|
|
||||||
def initialize(channel_name:, channel_id:, requested_thread_ts: nil)
|
def initialize(channel_name:, channel_id:, requested_thread_ts: nil)
|
||||||
|
@ -250,19 +252,29 @@ module DiscourseChatIntegration::Provider::SlackProvider
|
||||||
end
|
end
|
||||||
|
|
||||||
def load_user_data
|
def load_user_data
|
||||||
|
key = "slack_user_info_#{Digest::SHA1.hexdigest(SiteSetting.chat_integration_slack_access_token)}"
|
||||||
|
@users = Discourse.cache.fetch(key, expires_in: 10.minutes) do
|
||||||
|
fetch_user_data
|
||||||
|
end
|
||||||
|
true
|
||||||
|
rescue UserFetchError
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch_user_data
|
||||||
http = ::DiscourseChatIntegration::Provider::SlackProvider.slack_api_http
|
http = ::DiscourseChatIntegration::Provider::SlackProvider.slack_api_http
|
||||||
|
|
||||||
cursor = nil
|
cursor = nil
|
||||||
req = Net::HTTP::Post.new(URI('https://slack.com/api/users.list'))
|
req = Net::HTTP::Post.new(URI('https://slack.com/api/users.list'))
|
||||||
|
|
||||||
@users = {}
|
users = {}
|
||||||
loop do
|
loop do
|
||||||
break if cursor == ""
|
break if cursor == ""
|
||||||
req.set_form_data(token: SiteSetting.chat_integration_slack_access_token, limit: 200, cursor: cursor)
|
req.set_form_data(token: SiteSetting.chat_integration_slack_access_token, limit: 200, cursor: cursor)
|
||||||
response = http.request(req)
|
response = http.request(req)
|
||||||
return false unless response.kind_of? Net::HTTPSuccess
|
raise UserFetchError.new unless response.kind_of? Net::HTTPSuccess
|
||||||
json = JSON.parse(response.body)
|
json = JSON.parse(response.body)
|
||||||
return false unless json['ok']
|
raise UserFetchError.new unless json['ok']
|
||||||
cursor = json['response_metadata']['next_cursor']
|
cursor = json['response_metadata']['next_cursor']
|
||||||
json['members'].each do |user|
|
json['members'].each do |user|
|
||||||
# Slack uses display_name and falls back to real_name if it is not set
|
# Slack uses display_name and falls back to real_name if it is not set
|
||||||
|
@ -272,10 +284,10 @@ module DiscourseChatIntegration::Provider::SlackProvider
|
||||||
user['_transcript_username'] = user['profile']['display_name']
|
user['_transcript_username'] = user['profile']['display_name']
|
||||||
end
|
end
|
||||||
user['_transcript_username'] = user['_transcript_username'].gsub(' ', '_')
|
user['_transcript_username'] = user['_transcript_username'].gsub(' ', '_')
|
||||||
@users[user['id']] = user
|
users[user['id']] = user
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
true
|
users
|
||||||
end
|
end
|
||||||
|
|
||||||
def load_chat_history(count: 500)
|
def load_chat_history(count: 500)
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
RSpec.describe DiscourseChatIntegration::Provider::SlackProvider::SlackTranscript do
|
RSpec.describe DiscourseChatIntegration::Provider::SlackProvider::SlackTranscript do
|
||||||
|
before do
|
||||||
|
Discourse.cache.clear
|
||||||
|
end
|
||||||
|
|
||||||
let(:messages_fixture) {
|
let(:messages_fixture) {
|
||||||
[
|
[
|
||||||
|
@ -132,14 +135,14 @@ RSpec.describe DiscourseChatIntegration::Provider::SlackProvider::SlackTranscrip
|
||||||
stub_request(:post, "https://slack.com/api/users.list")
|
stub_request(:post, "https://slack.com/api/users.list")
|
||||||
.to_return(status: 500, body: '')
|
.to_return(status: 500, body: '')
|
||||||
|
|
||||||
expect(transcript.load_user_data).to be_falsey
|
expect(transcript.load_user_data).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'handles slack failure' do
|
it 'handles slack failure' do
|
||||||
stub_request(:post, "https://slack.com/api/users.list")
|
stub_request(:post, "https://slack.com/api/users.list")
|
||||||
.to_return(status: 200, body: { ok: false }.to_json)
|
.to_return(status: 200, body: { ok: false }.to_json)
|
||||||
|
|
||||||
expect(transcript.load_user_data).to be_falsey
|
expect(transcript.load_user_data).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue