mirror of
https://github.com/lingble/chatwoot.git
synced 2025-10-30 02:32:29 +00:00
fix: Avoid processing reactions, ephemeral, request_welcome or unsupported messages (#8780)
Currently, we do not support reactions, ephemeral messages, or the request_welcome event for the WhatsApp channel. However, if this is the first event we receive in Chatwoot (i.e., there is no previous conversation or contact in Chatwoot), it will create a contact and a conversation without any messages. This confuses our customer, as it may appear that Chatwoot has missed some messages. There are multiple cases where this might be the first event we receive in Chatwoot. One quick example is when the user has sent an outbound campaign from another tool and their customers reacted to the message. Another event like this is request_welcome event. WhatsApp has a concept for welcome messages. You can send an outbound message even though the user has not send a message. You can receive notifications through a webhook whenever a WhatsApp user initiates a chat with you for the first time. (Read the Welcome message section: https://developers.facebook.com/docs/whatsapp/cloud-api/phone-numbers/conversational-components/ ). Although this can help the business send a pro-active message to the user, we don't have it scoped in our feature set. For now, I'm ignoring this event. Fixes https://linear.app/chatwoot/issue/CW-3018/whatsapp-handle-request-welcome-case-properly Fixes https://linear.app/chatwoot/issue/CW-3017/whatsapp-handle-reactions-properly
This commit is contained in:
@@ -19,7 +19,13 @@ class Whatsapp::IncomingMessageBaseService
|
||||
private
|
||||
|
||||
def process_messages
|
||||
# message allready exists so we don't need to process
|
||||
# We don't support reactions & ephemeral message now, we need to skip processing the message
|
||||
# if the webhook event is a reaction or an ephermal message or an unsupported message.
|
||||
return if unprocessable_message_type?(message_type)
|
||||
|
||||
# Multiple webhook event can be received against the same message due to misconfigurations in the Meta
|
||||
# business manager account. While we have not found the core reason yet, the following line ensure that
|
||||
# there are no duplicate messages created.
|
||||
return if find_message_by_source_id(@processed_params[:messages].first[:id]) || message_under_process?
|
||||
|
||||
cache_message_source_id_in_redis
|
||||
@@ -49,8 +55,6 @@ class Whatsapp::IncomingMessageBaseService
|
||||
end
|
||||
|
||||
def create_messages
|
||||
return if unprocessable_message_type?(message_type)
|
||||
|
||||
message = @processed_params[:messages].first
|
||||
log_error(message) && return if error_webhook_event?(message)
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ module Whatsapp::IncomingMessageServiceHelpers
|
||||
end
|
||||
|
||||
def unprocessable_message_type?(message_type)
|
||||
%w[reaction ephemeral unsupported].include?(message_type)
|
||||
%w[reaction ephemeral unsupported request_welcome].include?(message_type)
|
||||
end
|
||||
|
||||
def brazil_phone_number?(phone_number)
|
||||
|
||||
@@ -146,6 +146,61 @@ RSpec.describe Webhooks::WhatsappEventsJob do
|
||||
end.not_to change(Message, :count)
|
||||
end
|
||||
|
||||
it 'ignore reaction type message, would not create contact if the reaction is the first event' do
|
||||
other_channel = create(:channel_whatsapp, phone_number: '+1987654', provider: 'whatsapp_cloud', sync_templates: false,
|
||||
validate_provider_config: false)
|
||||
wb_params = {
|
||||
phone_number: channel.phone_number,
|
||||
object: 'whatsapp_business_account',
|
||||
entry: [{
|
||||
changes: [{
|
||||
value: {
|
||||
contacts: [{ profile: { name: 'Test Test' }, wa_id: '1111981136571' }],
|
||||
messages: [{
|
||||
from: '1111981136571', reaction: { emoji: '👍' }, timestamp: '1664799904', type: 'reaction'
|
||||
}],
|
||||
metadata: {
|
||||
phone_number_id: other_channel.provider_config['phone_number_id'],
|
||||
display_phone_number: other_channel.phone_number.delete('+')
|
||||
}
|
||||
}
|
||||
}]
|
||||
}]
|
||||
}.with_indifferent_access
|
||||
expect do
|
||||
Whatsapp::IncomingMessageWhatsappCloudService.new(inbox: other_channel.inbox, params: wb_params).perform
|
||||
end.not_to change(Contact, :count)
|
||||
end
|
||||
|
||||
it 'ignore request_welcome type message, would not create contact or conversation' do
|
||||
other_channel = create(:channel_whatsapp, phone_number: '+1987654', provider: 'whatsapp_cloud', sync_templates: false,
|
||||
validate_provider_config: false)
|
||||
wb_params = {
|
||||
phone_number: channel.phone_number,
|
||||
object: 'whatsapp_business_account',
|
||||
entry: [{
|
||||
changes: [{
|
||||
value: {
|
||||
messages: [{
|
||||
from: '1111981136571', timestamp: '1664799904', type: 'request_welcome'
|
||||
}],
|
||||
metadata: {
|
||||
phone_number_id: other_channel.provider_config['phone_number_id'],
|
||||
display_phone_number: other_channel.phone_number.delete('+')
|
||||
}
|
||||
}
|
||||
}]
|
||||
}]
|
||||
}.with_indifferent_access
|
||||
expect do
|
||||
Whatsapp::IncomingMessageWhatsappCloudService.new(inbox: other_channel.inbox, params: wb_params).perform
|
||||
end.not_to change(Contact, :count)
|
||||
|
||||
expect do
|
||||
Whatsapp::IncomingMessageWhatsappCloudService.new(inbox: other_channel.inbox, params: wb_params).perform
|
||||
end.not_to change(Conversation, :count)
|
||||
end
|
||||
|
||||
it 'will not enque Whatsapp::IncomingMessageWhatsappCloudService when invalid phone number id' do
|
||||
other_channel = create(:channel_whatsapp, phone_number: '+1987654', provider: 'whatsapp_cloud', sync_templates: false,
|
||||
validate_provider_config: false)
|
||||
|
||||
@@ -81,7 +81,7 @@ describe Whatsapp::IncomingMessageService do
|
||||
end
|
||||
|
||||
context 'when unsupported message types' do
|
||||
it 'ignores type ephemeral' do
|
||||
it 'ignores type ephemeral and does not create ghost conversation' do
|
||||
params = {
|
||||
'contacts' => [{ 'profile' => { 'name' => 'Sojan Jose' }, 'wa_id' => '2423423243' }],
|
||||
'messages' => [{ 'from' => '2423423243', 'id' => 'SDFADSf23sfasdafasdfa', 'text' => { 'body' => 'Test' },
|
||||
@@ -89,12 +89,12 @@ describe Whatsapp::IncomingMessageService do
|
||||
}.with_indifferent_access
|
||||
|
||||
described_class.new(inbox: whatsapp_channel.inbox, params: params).perform
|
||||
expect(whatsapp_channel.inbox.conversations.count).not_to eq(0)
|
||||
expect(Contact.all.first.name).to eq('Sojan Jose')
|
||||
expect(whatsapp_channel.inbox.conversations.count).to eq(0)
|
||||
expect(Contact.count).to eq(0)
|
||||
expect(whatsapp_channel.inbox.messages.count).to eq(0)
|
||||
end
|
||||
|
||||
it 'ignores type unsupported' do
|
||||
it 'ignores type unsupported and does not create ghost conversation' do
|
||||
params = {
|
||||
'contacts' => [{ 'profile' => { 'name' => 'Sojan Jose' }, 'wa_id' => '2423423243' }],
|
||||
'messages' => [{
|
||||
@@ -105,8 +105,8 @@ describe Whatsapp::IncomingMessageService do
|
||||
}.with_indifferent_access
|
||||
|
||||
described_class.new(inbox: whatsapp_channel.inbox, params: params).perform
|
||||
expect(whatsapp_channel.inbox.conversations.count).not_to eq(0)
|
||||
expect(Contact.all.first.name).to eq('Sojan Jose')
|
||||
expect(whatsapp_channel.inbox.conversations.count).to eq(0)
|
||||
expect(Contact.count).to eq(0)
|
||||
expect(whatsapp_channel.inbox.messages.count).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user