iachat/app/services/leads/attribution_matcher_service.rb
Rodrigo Borba 118f52e239 feat: lead attribution tracking - landing page origin detection
- Cria modelo LeadClick para registrar cliques das landing pages
- Cria modelo LandingHost para mapear hostname → inbox_id
- Endpoint público POST /track/click para receber eventos de clique
- Leads::AttributionMatcherService para correlacionar clique com conversa
- Integração com IncomingMessageWuzapiService para atribuição automática
- API REST para gerenciar LandingHosts por inbox (index/create/destroy)
- UI: nova aba 'Landing Pages' nas configurações da caixa de entrada
- Dashboard API client dedicado (landingHosts.js)
- RuboCop: refatora shift_signature_name, TrackingController, AttributionMatcherService e WuzapiService
2026-03-02 14:40:35 -03:00

67 lines
1.7 KiB
Ruby

class Leads::AttributionMatcherService
def initialize(conversation, inbound_ip = nil)
@conversation = conversation
@contact = conversation.contact
@inbox_id = conversation.inbox_id
@inbound_ip = inbound_ip
end
def perform
return unless valid_for_matching?
click = find_matching_click
return unless click
apply_attribution(click)
end
private
def valid_for_matching?
@conversation.present? && @contact.present? &&
@conversation.custom_attributes['link_de_origem'].blank?
end
def find_matching_click
base_query = LeadClick
.where(status: :clicked, inbox_id: @inbox_id)
.where('created_at > ?', 10.minutes.ago)
return base_query.where(ip: @inbound_ip).order(created_at: :desc).first if @inbound_ip.present?
base_query.order(created_at: :desc).first
end
def attribution_attrs(click)
{
'link_de_origem' => click.source,
'campanha' => click.campanha,
'lp_hostname' => click.hostname,
'click_id' => click.id.to_s
}
end
def apply_attribution(click)
ActiveRecord::Base.transaction do
click.update!(status: :converted, conversation_id: @conversation.id, contact_id: @contact.id)
update_contact(click)
update_conversation(click)
apply_labels(click)
end
end
def update_contact(click)
@contact.update!(custom_attributes: @contact.custom_attributes.to_h.merge(attribution_attrs(click)))
end
def update_conversation(click)
@conversation.update!(
custom_attributes: @conversation.custom_attributes.to_h.merge(attribution_attrs(click))
)
end
def apply_labels(click)
@conversation.add_labels(['lead_meta']) if click.source.to_s.downcase.include?('meta')
end
end