chatwoot-develop/app/services/whatsapp/incoming_message_wuzapi_service.rb

86 lines
2.7 KiB
Ruby

module Whatsapp
class IncomingMessageWuzapiService < IncomingMessageBaseService
def perform
parser = Whatsapp::Providers::Wuzapi::PayloadParser.new(params)
# 1. V1 Scope: Ignore Groups
if parser.group_message?
Rails.logger.info "WuzAPI: Ignoring group message (ID: #{parser.external_id})"
return
end
# 2. Strong Dedupe (Critical for Sync)
if Message.exists?(source_id: parser.external_id, inbox_id: inbox.id)
Rails.logger.info "WuzAPI: Ignoring duplicate message (ID: #{parser.external_id})"
return
end
# 3. Message Type Check (V1: Text Only)
return unless parser.message_type == :text
# 4. Process
Rails.logger.info "WuzAPI: Processing message from #{parser.sender_phone_number}"
ActiveRecord::Base.transaction do
@contact = find_or_create_contact(parser)
Rails.logger.info "WuzAPI: Contact found/created: #{@contact.id}"
@conversation = find_or_create_conversation(@contact)
Rails.logger.info "WuzAPI: Conversation found/created: #{@conversation.id}"
message = create_message(parser, @conversation)
Rails.logger.info "WuzAPI: Message created: #{message.id}"
end
rescue StandardError => e
Rails.logger.error "WuzAPI Error: #{e.message}"
Rails.logger.error e.backtrace.join("\n")
raise e
end
private
def find_or_create_contact(parser)
# Normalize phone
phone = parser.sender_phone_number
normalized_phone = "+#{phone}"
contact_inbox = ::ContactInboxWithContactBuilder.new(
source_id: phone,
inbox: inbox,
contact_attributes: {
name: parser.push_name || phone,
phone_number: normalized_phone
}
).perform
contact_inbox.contact
end
def find_or_create_conversation(contact)
conversation = inbox.conversations.where(contact_id: contact.id)
.where.not(status: :resolved)
.last
conversation || ::Conversation.create!(
account_id: inbox.account_id,
inbox_id: inbox.id,
contact_id: contact.id,
contact_inbox_id: ContactInbox.find_by(contact_id: contact.id, inbox_id: inbox.id)&.id
)
end
def create_message(parser, conversation)
is_outgoing = parser.from_me?
conversation.messages.create!(
content: parser.text_content,
account_id: inbox.account_id,
inbox_id: inbox.id,
message_type: is_outgoing ? :outgoing : :incoming,
sender: is_outgoing ? nil : @contact,
source_id: parser.external_id,
created_at: parser.timestamp
)
end
end
end