FIX: Always use parent thread_ts for slack threads (#159)

Previously we were using the `ts` of the previous message we sent to the thread. While this did work under some situations, it's not recommended in the Slack API docs, and can lead to some unexpected behavior (e.g. when one of the threaded messages is deleted).

This commit updates our logic to always use Slack's returned `thread_ts`, which represents the thread's parent.
This commit is contained in:
David Taylor 2023-01-26 12:18:48 +00:00 committed by GitHub
parent bdc2f27a2a
commit 0522ad6414
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 6 additions and 5 deletions

View File

@ -144,7 +144,7 @@ module DiscourseChatIntegration::Provider::SlackProvider
} }
end end
ts = json["ts"] ts = json.dig("message", "thread_ts") || json["ts"]
set_slack_thread_ts(post.topic, channel, ts) if !ts.nil? && !post.nil? set_slack_thread_ts(post.topic, channel, ts) if !ts.nil? && !post.nil?
response response

View File

@ -99,6 +99,7 @@ RSpec.describe DiscourseChatIntegration::Provider::SlackProvider do
SiteSetting.chat_integration_slack_access_token = "magic" SiteSetting.chat_integration_slack_access_token = "magic"
@ts = "#{Time.now.to_i}.012345" @ts = "#{Time.now.to_i}.012345"
@ts2 = "#{Time.now.to_i}.012346" @ts2 = "#{Time.now.to_i}.012346"
@ts3 = "#{Time.now.to_i}.0123467"
@stub1 = @stub1 =
stub_request(:post, SiteSetting.chat_integration_slack_outbound_webhook_url).to_return( stub_request(:post, SiteSetting.chat_integration_slack_outbound_webhook_url).to_return(
body: "success", body: "success",
@ -116,17 +117,17 @@ RSpec.describe DiscourseChatIntegration::Provider::SlackProvider do
body: hash_including("thread_ts" => @ts), body: hash_including("thread_ts" => @ts),
).to_return( ).to_return(
body: body:
"{\"ok\":true, \"ts\": \"#{@ts}\", \"message\": {\"attachments\": [], \"username\":\"blah\", \"text\":\"blah2\"} }", "{\"ok\":true, \"ts\": \"#{@ts}\", \"message\": {\"attachments\": [], \"username\":\"blah\", \"text\":\"blah2\", \"thread_ts\":\"#{@ts}\"} }",
headers: { headers: {
"Content-Type" => "application/json", "Content-Type" => "application/json",
}, },
) )
@thread_stub2 = @thread_stub2 =
stub_request(:post, %r{https://slack.com/api/chat.postMessage}).with( stub_request(:post, %r{https://slack.com/api/chat.postMessage}).with(
body: hash_including("thread_ts" => @ts2), body: hash_including("thread_ts" => @ts),
).to_return( ).to_return(
body: body:
"{\"ok\":true, \"ts\": \"#{@ts2}\", \"message\": {\"attachments\": [], \"username\":\"blah\", \"text\":\"blah2\"} }", "{\"ok\":true, \"ts\": \"#{@ts3}\", \"message\": {\"attachments\": [], \"username\":\"blah\", \"text\":\"blah2\", \"thread_ts\":\"#{@ts}\"} }",
headers: { headers: {
"Content-Type" => "application/json", "Content-Type" => "application/json",
}, },
@ -176,7 +177,7 @@ RSpec.describe DiscourseChatIntegration::Provider::SlackProvider do
post.topic.reload post.topic.reload
expect(described_class.get_slack_thread_ts(post.topic, "#general")).to eq(@ts) expect(described_class.get_slack_thread_ts(post.topic, "#general")).to eq(@ts)
expect(described_class.get_slack_thread_ts(post.topic, "#random")).to eq(@ts2) expect(described_class.get_slack_thread_ts(post.topic, "#random")).to eq(@ts)
end end
it "recognizes slack thread ts in comment" do it "recognizes slack thread ts in comment" do