Defer processing of transcripts to avoid timeouts
This commit is contained in:
parent
6a976c4d66
commit
47a6a89e5a
|
@ -137,6 +137,7 @@ en:
|
||||||
posted_in: "posted in %{name}"
|
posted_in: "posted in %{name}"
|
||||||
change_first_message: "Change first message..."
|
change_first_message: "Change first message..."
|
||||||
change_last_message: "Change last message..."
|
change_last_message: "Change last message..."
|
||||||
|
loading: "Loading the transcript..."
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
########## TELEGRAM STRINGS ###########
|
########## TELEGRAM STRINGS ###########
|
||||||
|
|
|
@ -40,54 +40,63 @@ module DiscourseChat::Provider::SlackProvider
|
||||||
channel ||= DiscourseChat::Channel.create!(provider: provider, data: { identifier: channel_id })
|
channel ||= DiscourseChat::Channel.create!(provider: provider, data: { identifier: channel_id })
|
||||||
|
|
||||||
if tokens[0] == 'post'
|
if tokens[0] == 'post'
|
||||||
return process_post_request(channel, tokens, params[:channel_id], channel_id)
|
return process_post_request(channel, tokens, params[:channel_id], channel_id, params[:response_url])
|
||||||
end
|
end
|
||||||
|
|
||||||
return { text: ::DiscourseChat::Helper.process_command(channel, tokens) }
|
return { text: ::DiscourseChat::Helper.process_command(channel, tokens) }
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def process_post_request(channel, tokens, slack_channel_id, channel_name)
|
def process_post_request(channel, tokens, slack_channel_id, channel_name, response_url)
|
||||||
if SiteSetting.chat_integration_slack_access_token.empty?
|
if SiteSetting.chat_integration_slack_access_token.empty?
|
||||||
return { text: I18n.t("chat_integration.provider.slack.transcript.api_required") }
|
return { text: I18n.t("chat_integration.provider.slack.transcript.api_required") }
|
||||||
end
|
end
|
||||||
|
|
||||||
requested_messages = nil
|
Scheduler::Defer.later "Processing slack transcript request" do
|
||||||
first_message_ts = nil
|
requested_messages = nil
|
||||||
|
first_message_ts = nil
|
||||||
|
|
||||||
slack_url_regex = /^https:\/\/\S+\.slack\.com\/archives\/\S+\/p([0-9]{16})\/?$/
|
slack_url_regex = /^https:\/\/\S+\.slack\.com\/archives\/\S+\/p([0-9]{16})\/?$/
|
||||||
if tokens.size > 1 && match = slack_url_regex.match(tokens[1])
|
if tokens.size > 1 && match = slack_url_regex.match(tokens[1])
|
||||||
first_message_ts = match.captures[0].insert(10, '.')
|
first_message_ts = match.captures[0].insert(10, '.')
|
||||||
elsif tokens.size > 1
|
elsif tokens.size > 1
|
||||||
begin
|
begin
|
||||||
requested_messages = Integer(tokens[1], 10)
|
requested_messages = Integer(tokens[1], 10)
|
||||||
rescue ArgumentError
|
rescue ArgumentError
|
||||||
return { text: I18n.t("chat_integration.provider.slack.parse_error") }
|
return { text: I18n.t("chat_integration.provider.slack.parse_error") }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
error_message = { text: I18n.t("chat_integration.provider.slack.transcript.error") }
|
||||||
|
|
||||||
|
return error_message unless transcript = SlackTranscript.new(channel_name: channel_name, channel_id: slack_channel_id)
|
||||||
|
return error_message unless transcript.load_user_data
|
||||||
|
return error_message unless transcript.load_chat_history
|
||||||
|
|
||||||
|
if first_message_ts
|
||||||
|
return error_message unless transcript.set_first_message_by_ts(first_message_ts)
|
||||||
|
elsif requested_messages
|
||||||
|
transcript.set_first_message_by_index(-requested_messages)
|
||||||
|
else
|
||||||
|
transcript.set_first_message_by_index(-10) unless transcript.guess_first_message
|
||||||
|
end
|
||||||
|
|
||||||
|
http = Net::HTTP.new("slack.com", 443)
|
||||||
|
http.use_ssl = true
|
||||||
|
req = Net::HTTP::Post.new(URI(response_url), 'Content-Type' => 'application/json')
|
||||||
|
req.body = transcript.build_slack_ui.to_json
|
||||||
|
response = http.request(req)
|
||||||
end
|
end
|
||||||
|
|
||||||
error_message = { text: I18n.t("chat_integration.provider.slack.transcript.error") }
|
return { text: I18n.t("chat_integration.provider.slack.transcript.loading") }
|
||||||
|
|
||||||
return error_message unless transcript = SlackTranscript.new(channel_name: channel_name, channel_id: slack_channel_id)
|
|
||||||
return error_message unless transcript.load_user_data
|
|
||||||
return error_message unless transcript.load_chat_history
|
|
||||||
|
|
||||||
if first_message_ts
|
|
||||||
return error_message unless transcript.set_first_message_by_ts(first_message_ts)
|
|
||||||
elsif requested_messages
|
|
||||||
transcript.set_first_message_by_index(-requested_messages)
|
|
||||||
else
|
|
||||||
transcript.set_first_message_by_index(-10) unless transcript.guess_first_message
|
|
||||||
end
|
|
||||||
|
|
||||||
return transcript.build_slack_ui
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def interactive
|
def interactive
|
||||||
json = JSON.parse(params[:payload], symbolize_names: true)
|
json = JSON.parse(params[:payload], symbolize_names: true)
|
||||||
|
process_interactive(json)
|
||||||
|
|
||||||
render json: process_interactive(json)
|
render nothing: true, status: 200
|
||||||
end
|
end
|
||||||
|
|
||||||
def process_interactive(json)
|
def process_interactive(json)
|
||||||
|
@ -101,14 +110,20 @@ module DiscourseChat::Provider::SlackProvider
|
||||||
|
|
||||||
error_message = { text: I18n.t("chat_integration.provider.slack.transcript.error") }
|
error_message = { text: I18n.t("chat_integration.provider.slack.transcript.error") }
|
||||||
|
|
||||||
return error_message unless transcript = SlackTranscript.new(channel_name: "##{json[:channel][:name]}", channel_id: json[:channel][:id])
|
Scheduler::Defer.later "Processing slack transcript update" do
|
||||||
return error_message unless transcript.load_user_data
|
return error_message unless transcript = SlackTranscript.new(channel_name: "##{json[:channel][:name]}", channel_id: json[:channel][:id])
|
||||||
return error_message unless transcript.load_chat_history
|
return error_message unless transcript.load_user_data
|
||||||
|
return error_message unless transcript.load_chat_history
|
||||||
|
|
||||||
return error_message unless transcript.set_first_message_by_ts(first_message)
|
return error_message unless transcript.set_first_message_by_ts(first_message)
|
||||||
return error_message unless transcript.set_last_message_by_ts(last_message)
|
return error_message unless transcript.set_last_message_by_ts(last_message)
|
||||||
|
|
||||||
return transcript.build_slack_ui
|
http = Net::HTTP.new("slack.com", 443)
|
||||||
|
http.use_ssl = true
|
||||||
|
req = Net::HTTP::Post.new(URI(json[:response_url]), 'Content-Type' => 'application/json')
|
||||||
|
req.body = transcript.build_slack_ui.to_json
|
||||||
|
response = http.request(req)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def slack_token_valid?
|
def slack_token_valid?
|
||||||
|
|
|
@ -180,50 +180,63 @@ describe 'Slack Command Controller', type: :request do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'generates the transcript UI properly' do
|
it 'generates the transcript UI properly' do
|
||||||
|
command_stub = stub_request(:post, "https://slack.com/commands/1234")
|
||||||
|
.with(body: /attachments/)
|
||||||
|
.to_return(body: { ok: true }.to_json)
|
||||||
|
|
||||||
post "/chat-integration/slack/command.json",
|
post "/chat-integration/slack/command.json",
|
||||||
text: "post",
|
text: "post",
|
||||||
|
response_url: 'https://hooks.slack.com/commands/1234',
|
||||||
channel_name: 'general',
|
channel_name: 'general',
|
||||||
channel_id: 'C6029G78F',
|
channel_id: 'C6029G78F',
|
||||||
token: token
|
token: token
|
||||||
|
|
||||||
json = JSON.parse(response.body)
|
expect(command_stub).to have_been_requested
|
||||||
expect(json["attachments"].length).to eq(2)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'can select by url' do
|
it 'can select by url' do
|
||||||
|
command_stub = stub_request(:post, "https://slack.com/commands/1234")
|
||||||
|
.with(body: /1501801629\.052212/)
|
||||||
|
.to_return(body: { ok: true }.to_json)
|
||||||
|
|
||||||
post "/chat-integration/slack/command.json",
|
post "/chat-integration/slack/command.json",
|
||||||
text: "post https://sometestslack.slack.com/archives/C6029G78F/p1501801629052212",
|
text: "post https://sometestslack.slack.com/archives/C6029G78F/p1501801629052212",
|
||||||
|
response_url: 'https://hooks.slack.com/commands/1234',
|
||||||
channel_name: 'general',
|
channel_name: 'general',
|
||||||
channel_id: 'C6029G78F',
|
channel_id: 'C6029G78F',
|
||||||
token: token
|
token: token
|
||||||
|
|
||||||
json = JSON.parse(response.body)
|
expect(command_stub).to have_been_requested
|
||||||
expect(json["attachments"].length).to eq(2)
|
|
||||||
expect(json["attachments"][0]["ts"]).to eq("1501801629.052212")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'can select by count' do
|
it 'can select by count' do
|
||||||
|
command_stub = stub_request(:post, "https://slack.com/commands/1234")
|
||||||
|
.with(body: /1501801629\.052212/)
|
||||||
|
.to_return(body: { ok: true }.to_json)
|
||||||
|
|
||||||
post "/chat-integration/slack/command.json",
|
post "/chat-integration/slack/command.json",
|
||||||
text: "post 4",
|
text: "post 4",
|
||||||
|
response_url: 'https://hooks.slack.com/commands/1234',
|
||||||
channel_name: 'general',
|
channel_name: 'general',
|
||||||
channel_id: 'C6029G78F',
|
channel_id: 'C6029G78F',
|
||||||
token: token
|
token: token
|
||||||
|
|
||||||
json = JSON.parse(response.body)
|
expect(command_stub).to have_been_requested
|
||||||
expect(json["attachments"].length).to eq(2)
|
|
||||||
expect(json["attachments"][0]["ts"]).to eq("1501801629.052212")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'can auto select' do
|
it 'can auto select' do
|
||||||
|
command_stub = stub_request(:post, "https://slack.com/commands/1234")
|
||||||
|
.with(body: /1501615820\.949638/)
|
||||||
|
.to_return(body: { ok: true }.to_json)
|
||||||
|
|
||||||
post "/chat-integration/slack/command.json",
|
post "/chat-integration/slack/command.json",
|
||||||
text: "post",
|
text: "post",
|
||||||
|
response_url: 'https://hooks.slack.com/commands/1234',
|
||||||
channel_name: 'general',
|
channel_name: 'general',
|
||||||
channel_id: 'C6029G78F',
|
channel_id: 'C6029G78F',
|
||||||
token: token
|
token: token
|
||||||
|
|
||||||
json = JSON.parse(response.body)
|
expect(command_stub).to have_been_requested
|
||||||
expect(json["attachments"].length).to eq(2)
|
|
||||||
expect(json["attachments"][0]["ts"]).to eq("1501615820.949638")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -232,6 +245,7 @@ describe 'Slack Command Controller', type: :request do
|
||||||
|
|
||||||
post "/chat-integration/slack/command.json",
|
post "/chat-integration/slack/command.json",
|
||||||
text: "post 2",
|
text: "post 2",
|
||||||
|
response_url: 'https://hooks.slack.com/commands/1234',
|
||||||
channel_name: 'general',
|
channel_name: 'general',
|
||||||
channel_id: 'C6029G78F',
|
channel_id: 'C6029G78F',
|
||||||
token: token
|
token: token
|
||||||
|
@ -246,6 +260,7 @@ describe 'Slack Command Controller', type: :request do
|
||||||
|
|
||||||
post "/chat-integration/slack/command.json",
|
post "/chat-integration/slack/command.json",
|
||||||
text: "post 2",
|
text: "post 2",
|
||||||
|
response_url: 'https://hooks.slack.com/commands/1234',
|
||||||
channel_name: 'general',
|
channel_name: 'general',
|
||||||
channel_id: 'C6029G78F',
|
channel_id: 'C6029G78F',
|
||||||
token: token
|
token: token
|
||||||
|
|
Loading…
Reference in New Issue