diff --git a/app/models/bot/smooch.rb b/app/models/bot/smooch.rb index 014b291eda..7f98916df1 100644 --- a/app/models/bot/smooch.rb +++ b/app/models/bot/smooch.rb @@ -726,7 +726,7 @@ def self.store_sent_tipline_message(uid, external_id, sent_at, payload_json, tea tm.payload = payload tm.team_id = team_id tm.skip_check_ability = true - tm.save! + tm.save_ignoring_duplicate! end def self.create_project_media_from_message(message) diff --git a/app/models/tipline_message.rb b/app/models/tipline_message.rb index dea6f55432..d648d8a3ca 100644 --- a/app/models/tipline_message.rb +++ b/app/models/tipline_message.rb @@ -6,6 +6,14 @@ class TiplineMessage < ApplicationRecord validates_presence_of :team, :uid, :platform, :language, :direction, :sent_at, :payload, :state validates_inclusion_of :state, in: ['sent', 'received', 'delivered'] + def save_ignoring_duplicate! + begin + self.save! + rescue ActiveRecord::RecordNotUnique + Rails.logger.info("[Smooch Bot] Not storing tipline message because it already exists. ID: #{self.external_id}. State: #{self.state}.") + end + end + class << self def from_smooch_payload(msg, payload, event = nil, language = nil) msg = msg.with_indifferent_access diff --git a/app/workers/smooch_tipline_message_worker.rb b/app/workers/smooch_tipline_message_worker.rb index 0b22292622..c4516ae334 100644 --- a/app/workers/smooch_tipline_message_worker.rb +++ b/app/workers/smooch_tipline_message_worker.rb @@ -27,7 +27,7 @@ def perform(message_json, payload_json) end tm = TiplineMessage.from_smooch_payload(message_json, payload_json, event, language) - tm.save + tm.save_ignoring_duplicate! User.current = nil end diff --git a/test/models/tipline_message_test.rb b/test/models/tipline_message_test.rb index a616d95d49..943f91e53e 100644 --- a/test/models/tipline_message_test.rb +++ b/test/models/tipline_message_test.rb @@ -149,4 +149,53 @@ def setup create_tipline_message state: 'invalid' end end + + test "should ignore duplicate when saving" do + id = random_string + data = { + uid: random_string, + team_id: create_team.id, + language: 'en', + platform: 'WhatsApp', + sent_at: DateTime.now, + payload: {'foo' => 'bar'} + } + assert_nothing_raised do + assert_difference 'TiplineMessage.count' do + tm = TiplineMessage.new(data) + tm.direction = :outgoing + tm.external_id = id + tm.state = 'sent' + tm.save_ignoring_duplicate! + end + assert_difference 'TiplineMessage.count' do + tm = TiplineMessage.new(data) + tm.direction = :outgoing + tm.external_id = id + tm.state = 'delivered' + tm.save_ignoring_duplicate! + end + assert_difference 'TiplineMessage.count' do + tm = TiplineMessage.new(data) + tm.direction = :incoming + tm.external_id = random_string + tm.state = 'received' + tm.save_ignoring_duplicate! + end + assert_no_difference 'TiplineMessage.count' do + tm = TiplineMessage.new(data) + tm.direction = :outgoing + tm.external_id = id + tm.state = 'sent' + tm.save_ignoring_duplicate! + end + assert_no_difference 'TiplineMessage.count' do + tm = TiplineMessage.new(data) + tm.direction = :outgoing + tm.external_id = id + tm.state = 'delivered' + tm.save_ignoring_duplicate! + end + end + end end