diff --git a/lib/discourse_chat/provider/slack/slack_command_controller.rb b/lib/discourse_chat/provider/slack/slack_command_controller.rb index 5ad1bbf..6c1a011 100644 --- a/lib/discourse_chat/provider/slack/slack_command_controller.rb +++ b/lib/discourse_chat/provider/slack/slack_command_controller.rb @@ -52,9 +52,9 @@ module DiscourseChat::Provider::SlackProvider return { text: I18n.t("chat_integration.provider.slack.transcript.api_required") } end - requested_messages = 10 - + requested_messages = nil first_message_ts = nil + slack_url_regex = /^https:\/\/\S+\.slack\.com\/archives\/\S+\/p([0-9]{16})\/?$/ if tokens.size > 1 && match = slack_url_regex.match(tokens[1]) first_message_ts = match.captures[0].insert(10, '.') @@ -74,8 +74,10 @@ module DiscourseChat::Provider::SlackProvider 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(-requested_messages) # Don't fail if this doesn't work, just use the default + transcript.set_first_message_by_index(-10) unless transcript.guess_first_message end return transcript.build_slack_ui diff --git a/lib/discourse_chat/provider/slack/slack_transcript.rb b/lib/discourse_chat/provider/slack/slack_transcript.rb index cc6c3ee..82025fc 100644 --- a/lib/discourse_chat/provider/slack/slack_transcript.rb +++ b/lib/discourse_chat/provider/slack/slack_transcript.rb @@ -112,6 +112,36 @@ module DiscourseChat::Provider::SlackProvider @last_message_index = val if @messages[val] end + # Apply a heuristic to decide which is the first message in the current conversation + def guess_first_message(skip_messages: 5) # Can skip the last n messages + + possible_first_messages = @messages[0..-skip_messages] + + # Work through the messages in order. If a gap is found, this could be the first message + new_first_message_index = nil + previous_message_ts = @messages[-skip_messages].ts.split('.').first.to_i + possible_first_messages.each_with_index do |message, index| + + # Calculate the time since the last message + this_ts = message.ts.split('.').first.to_i + time_since_previous_message = this_ts - previous_message_ts + + # If greater than 3 minutes, this could be the first message + if time_since_previous_message > 3.minutes + new_first_message_index = index + end + + previous_message_ts = this_ts + end + + if new_first_message_index + @first_message_index = new_first_message_index + return true + else + return false + end + end + def first_message return @messages[@first_message_index] end diff --git a/spec/lib/discourse_chat/provider/slack/slack_command_controller_spec.rb b/spec/lib/discourse_chat/provider/slack/slack_command_controller_spec.rb index 799ae6e..a11b502 100644 --- a/spec/lib/discourse_chat/provider/slack/slack_command_controller_spec.rb +++ b/spec/lib/discourse_chat/provider/slack/slack_command_controller_spec.rb @@ -213,6 +213,18 @@ describe 'Slack Command Controller', type: :request do expect(json["attachments"].length).to eq(2) expect(json["attachments"][0]["ts"]).to eq("1501801629.052212") end + + it 'can auto select' do + post "/chat-integration/slack/command.json", + text: "post", + channel_name: 'general', + channel_id: 'C6029G78F', + token: token + + json = JSON.parse(response.body) + expect(json["attachments"].length).to eq(2) + expect(json["attachments"][0]["ts"]).to eq("1501615820.949638") + end end it 'deals with failed API calls correctly' do diff --git a/spec/lib/discourse_chat/provider/slack/slack_transcript_spec.rb b/spec/lib/discourse_chat/provider/slack/slack_transcript_spec.rb index 6b87414..c136d52 100644 --- a/spec/lib/discourse_chat/provider/slack/slack_transcript_spec.rb +++ b/spec/lib/discourse_chat/provider/slack/slack_transcript_spec.rb @@ -176,6 +176,11 @@ RSpec.describe DiscourseChat::Provider::SlackProvider::SlackTranscript do expect(transcript.last_message_number).to eq(2) end + it 'can guess the first message' do + expect(transcript.guess_first_message(skip_messages:1)).to eq(true) + expect(transcript.first_message.ts).to eq('1501801629.052212') + end + it 'handles usernames correctly' do expect(transcript.first_message.username).to eq('awesomeguy') # Normal user expect(transcript.messages[2].username).to eq(nil) # Unknown normal user