From b081fe08b8ca9d9a768f98371d252a2a99475fef Mon Sep 17 00:00:00 2001 From: Tejaswini Chile Date: Wed, 3 May 2023 15:18:20 +0530 Subject: [PATCH] feat: whatsapp duplicate message (#7004) --- .../whatsapp/incoming_message_base_service.rb | 11 +++---- .../incoming_message_service_helpers.rb | 17 ++++++++++ lib/redis/redis_keys.rb | 2 ++ .../whatsapp/incoming_message_service_spec.rb | 31 +++++++++++++++++++ 4 files changed, 55 insertions(+), 6 deletions(-) diff --git a/app/services/whatsapp/incoming_message_base_service.rb b/app/services/whatsapp/incoming_message_base_service.rb index 15357f75b..4bbc2f206 100644 --- a/app/services/whatsapp/incoming_message_base_service.rb +++ b/app/services/whatsapp/incoming_message_base_service.rb @@ -20,13 +20,15 @@ class Whatsapp::IncomingMessageBaseService 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 @@ -53,11 +55,8 @@ class Whatsapp::IncomingMessageBaseService 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) diff --git a/app/services/whatsapp/incoming_message_service_helpers.rb b/app/services/whatsapp/incoming_message_service_helpers.rb index a5226fbab..ad2fccd03 100644 --- a/app/services/whatsapp/incoming_message_service_helpers.rb +++ b/app/services/whatsapp/incoming_message_service_helpers.rb @@ -104,4 +104,21 @@ module Whatsapp::IncomingMessageServiceHelpers @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 diff --git a/lib/redis/redis_keys.rb b/lib/redis/redis_keys.rb index 13c24cdb4..67e709e52 100644 --- a/lib/redis/redis_keys.rb +++ b/lib/redis/redis_keys.rb @@ -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::%s'.freeze end diff --git a/spec/services/whatsapp/incoming_message_service_spec.rb b/spec/services/whatsapp/incoming_message_service_spec.rb index b2bd87d18..c141f869e 100644 --- a/spec/services/whatsapp/incoming_message_service_spec.rb +++ b/spec/services/whatsapp/incoming_message_service_spec.rb @@ -308,5 +308,36 @@ describe Whatsapp::IncomingMessageService do 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