Skip to content

Commit

Permalink
feat: whatsapp duplicate message (chatwoot#7004)
Browse files Browse the repository at this point in the history
  • Loading branch information
tejaswinichile authored May 3, 2023
1 parent 0d014d5 commit b081fe0
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 6 deletions.
11 changes: 5 additions & 6 deletions app/services/whatsapp/incoming_message_base_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ def perform

def process_messages
# message allready exists so we don't need to process
return if find_message_by_source_id(@processed_params[:messages].first[:id])
return if find_message_by_source_id(@processed_params[:messages].first[:id]) || message_under_process?

cache_message_source_id_in_redis
set_contact
return unless @contact

set_conversation
create_messages
clear_message_source_id_from_redis
end

def process_statuses
Expand All @@ -53,11 +55,8 @@ def create_messages
log_error(message) && return if error_webhook_event?(message)

process_in_reply_to(message)
if message_type == 'contacts'
create_contact_messages(message)
else
create_regular_message(message)
end

message_type == 'contacts' ? create_contact_messages(message) : create_regular_message(message)
end

def create_contact_messages(message)
Expand Down
17 changes: 17 additions & 0 deletions app/services/whatsapp/incoming_message_service_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,21 @@ def find_message_by_source_id(source_id)

@message = Message.find_by(source_id: source_id)
end

def message_under_process?
key = format(Redis::RedisKeys::MESSAGE_SOURCE_KEY, id: @processed_params[:messages].first[:id])
Redis::Alfred.get(key)
end

def cache_message_source_id_in_redis
return if @processed_params.try(:[], :messages).blank?

key = format(Redis::RedisKeys::MESSAGE_SOURCE_KEY, id: @processed_params[:messages].first[:id])
::Redis::Alfred.setex(key, true)
end

def clear_message_source_id_from_redis
key = format(Redis::RedisKeys::MESSAGE_SOURCE_KEY, id: @processed_params[:messages].first[:id])
::Redis::Alfred.delete(key)
end
end
2 changes: 2 additions & 0 deletions lib/redis/redis_keys.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,6 @@ module Redis::RedisKeys
## Internal Installation related keys
CHATWOOT_INSTALLATION_ONBOARDING = 'CHATWOOT_INSTALLATION_ONBOARDING'.freeze
LATEST_CHATWOOT_VERSION = 'LATEST_CHATWOOT_VERSION'.freeze
# Check if a message create with same source-id is in progress?
MESSAGE_SOURCE_KEY = 'MESSAGE_SOURCE_KEY::%<id>s'.freeze
end
31 changes: 31 additions & 0 deletions spec/services/whatsapp/incoming_message_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -308,5 +308,36 @@
end
end
end

describe 'when message processing is in progress' do
it 'ignores the current message creation request' do
params = { 'contacts' => [{ 'profile' => { 'name' => 'Kedar' }, 'wa_id' => '919746334593' }],
'messages' => [{ 'from' => '919446284490',
'id' => 'wamid.SDFADSf23sfasdafasdfa',
'timestamp' => '1675823265',
'type' => 'contacts',
'contacts' => [
{
'name' => { 'formatted_name' => 'Apple Inc.' },
'phones' => [{ 'phone' => '+911800', 'type' => 'MAIN' }]
},
{ 'name' => { 'first_name' => 'Chatwoot', 'formatted_name' => 'Chatwoot' },
'phones' => [{ 'phone' => '+1 (415) 341-8386' }] }
] }] }.with_indifferent_access

expect(Message.find_by(source_id: 'wamid.SDFADSf23sfasdafasdfa')).not_to be_present
key = format(Redis::RedisKeys::MESSAGE_SOURCE_KEY, id: 'wamid.SDFADSf23sfasdafasdfa')

::Redis::Alfred.setex(key, true)
expect(::Redis::Alfred.get(key)).to be_truthy

described_class.new(inbox: whatsapp_channel.inbox, params: params).perform
expect(whatsapp_channel.inbox.messages.count).to eq(0)
expect(Message.find_by(source_id: 'wamid.SDFADSf23sfasdafasdfa')).not_to be_present

expect(::Redis::Alfred.get(key)).to be_truthy
::Redis::Alfred.delete(key)
end
end
end
end

0 comments on commit b081fe0

Please sign in to comment.