feat: Add the ability to receive contact(vCard) on a WhatsApp inbox (#6330)
Co-authored-by: Pranav Raj S <pranav@chatwoot.com>
This commit is contained in:
@@ -55,33 +55,29 @@ class Whatsapp::IncomingMessageBaseService
|
||||
def create_messages
|
||||
return if unprocessable_message_type?(message_type)
|
||||
|
||||
@message = @conversation.messages.build(
|
||||
content: message_content(@processed_params[:messages].first),
|
||||
account_id: @inbox.account_id,
|
||||
inbox_id: @inbox.id,
|
||||
message_type: :incoming,
|
||||
sender: @contact,
|
||||
source_id: @processed_params[:messages].first[:id].to_s
|
||||
)
|
||||
message = @processed_params[:messages].first
|
||||
if message_type == 'contacts'
|
||||
create_contact_messages(message)
|
||||
else
|
||||
create_regular_message(message)
|
||||
end
|
||||
end
|
||||
|
||||
def create_contact_messages(message)
|
||||
message['contacts'].each do |contact|
|
||||
create_message(contact)
|
||||
attach_contact(contact)
|
||||
@message.save!
|
||||
end
|
||||
end
|
||||
|
||||
def create_regular_message(message)
|
||||
create_message(message)
|
||||
attach_files
|
||||
attach_location if message_type == 'location'
|
||||
@message.save!
|
||||
end
|
||||
|
||||
def processed_params
|
||||
@processed_params ||= params
|
||||
end
|
||||
|
||||
def message_content(message)
|
||||
# TODO: map interactive messages back to button messages in chatwoot
|
||||
message.dig(:text, :body) || message.dig(:button, :text) || message.dig(:interactive, :button_reply, :title) ||
|
||||
message.dig(:interactive, :list_reply, :title)
|
||||
end
|
||||
|
||||
def account
|
||||
@account ||= inbox.account
|
||||
end
|
||||
|
||||
def set_contact
|
||||
contact_params = @processed_params[:contacts]&.first
|
||||
return if contact_params.blank?
|
||||
@@ -96,15 +92,6 @@ class Whatsapp::IncomingMessageBaseService
|
||||
@contact = contact_inbox.contact
|
||||
end
|
||||
|
||||
def conversation_params
|
||||
{
|
||||
account_id: @inbox.account_id,
|
||||
inbox_id: @inbox.id,
|
||||
contact_id: @contact.id,
|
||||
contact_inbox_id: @contact_inbox.id
|
||||
}
|
||||
end
|
||||
|
||||
def set_conversation
|
||||
@conversation = @contact_inbox.conversations.last
|
||||
return if @conversation
|
||||
@@ -112,12 +99,8 @@ class Whatsapp::IncomingMessageBaseService
|
||||
@conversation = ::Conversation.create!(conversation_params)
|
||||
end
|
||||
|
||||
def message_type
|
||||
@processed_params[:messages].first[:type]
|
||||
end
|
||||
|
||||
def attach_files
|
||||
return if %w[text button interactive location].include?(message_type)
|
||||
return if %w[text button interactive location contacts].include?(message_type)
|
||||
|
||||
attachment_payload = @processed_params[:messages].first[message_type.to_sym]
|
||||
@message.content ||= attachment_payload[:caption]
|
||||
@@ -136,10 +119,6 @@ class Whatsapp::IncomingMessageBaseService
|
||||
)
|
||||
end
|
||||
|
||||
def download_attachment_file(attachment_payload)
|
||||
Down.download(inbox.channel.media_url(attachment_payload[:id]), headers: inbox.channel.api_headers)
|
||||
end
|
||||
|
||||
def attach_location
|
||||
location = @processed_params[:messages].first['location']
|
||||
location_name = location['name'] ? "#{location['name']}, #{location['address']}" : ''
|
||||
@@ -152,4 +131,28 @@ class Whatsapp::IncomingMessageBaseService
|
||||
external_url: location['url']
|
||||
)
|
||||
end
|
||||
|
||||
def create_message(message)
|
||||
@message = @conversation.messages.build(
|
||||
content: message_content(message),
|
||||
account_id: @inbox.account_id,
|
||||
inbox_id: @inbox.id,
|
||||
message_type: :incoming,
|
||||
sender: @contact,
|
||||
source_id: message[:id].to_s
|
||||
)
|
||||
end
|
||||
|
||||
def attach_contact(contact)
|
||||
phones = contact[:phones]
|
||||
phones = [{ phone: 'Phone number is not available' }] if phones.blank?
|
||||
|
||||
phones.each do |phone|
|
||||
@message.attachments.new(
|
||||
account_id: @message.account_id,
|
||||
file_type: file_content_type(message_type),
|
||||
fallback_title: phone[:phone].to_s
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,14 +1,49 @@
|
||||
module Whatsapp::IncomingMessageServiceHelpers
|
||||
def download_attachment_file(attachment_payload)
|
||||
Down.download(inbox.channel.media_url(attachment_payload[:id]), headers: inbox.channel.api_headers)
|
||||
end
|
||||
|
||||
def conversation_params
|
||||
{
|
||||
account_id: @inbox.account_id,
|
||||
inbox_id: @inbox.id,
|
||||
contact_id: @contact.id,
|
||||
contact_inbox_id: @contact_inbox.id
|
||||
}
|
||||
end
|
||||
|
||||
def processed_params
|
||||
@processed_params ||= params
|
||||
end
|
||||
|
||||
def account
|
||||
@account ||= inbox.account
|
||||
end
|
||||
|
||||
def message_type
|
||||
@processed_params[:messages].first[:type]
|
||||
end
|
||||
|
||||
def message_content(message)
|
||||
# TODO: map interactive messages back to button messages in chatwoot
|
||||
message.dig(:text, :body) ||
|
||||
message.dig(:button, :text) ||
|
||||
message.dig(:interactive, :button_reply, :title) ||
|
||||
message.dig(:interactive, :list_reply, :title) ||
|
||||
message.dig(:name, :formatted_name)
|
||||
end
|
||||
|
||||
def file_content_type(file_type)
|
||||
return :image if %w[image sticker].include?(file_type)
|
||||
return :audio if %w[audio voice].include?(file_type)
|
||||
return :video if ['video'].include?(file_type)
|
||||
return :location if ['location'].include?(file_type)
|
||||
return :contact if ['contacts'].include?(file_type)
|
||||
|
||||
:file
|
||||
end
|
||||
|
||||
def unprocessable_message_type?(message_type)
|
||||
%w[reaction contacts ephemeral unsupported].include?(message_type)
|
||||
%w[reaction ephemeral unsupported].include?(message_type)
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user