feat: add WhatsApp Business App coexistence feature
This commit is contained in:
@@ -57,7 +57,8 @@ class Whatsapp::EmbeddedController < ApplicationController
|
||||
code: params[:code],
|
||||
business_id: params[:business_id],
|
||||
waba_id: params[:waba_id],
|
||||
phone_number_id: params[:phone_number_id]
|
||||
phone_number_id: params[:phone_number_id],
|
||||
is_business_app_onboarding: params[:is_business_app_onboarding]
|
||||
)
|
||||
|
||||
service.perform
|
||||
|
||||
@@ -122,9 +122,17 @@ export function useWhatsappEmbeddedSignup() {
|
||||
}
|
||||
|
||||
isProcessing.value = true;
|
||||
processingMessage.value = t(
|
||||
'INBOX_MGMT.ADD.WHATSAPP.EMBEDDED_SIGNUP.PROCESSING'
|
||||
);
|
||||
|
||||
// Show different processing messages based on the signup type
|
||||
if (businessDataParam.is_business_app_onboarding) {
|
||||
processingMessage.value = t(
|
||||
'INBOX_MGMT.ADD.WHATSAPP.EMBEDDED_SIGNUP.PROCESSING_BUSINESS_APP'
|
||||
);
|
||||
} else {
|
||||
processingMessage.value = t(
|
||||
'INBOX_MGMT.ADD.WHATSAPP.EMBEDDED_SIGNUP.PROCESSING_NEW_NUMBER'
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
// Send both auth code and business info together (synchronous flow)
|
||||
@@ -144,6 +152,8 @@ export function useWhatsappEmbeddedSignup() {
|
||||
business_id: businessDataParam.business_id,
|
||||
waba_id: businessDataParam.waba_id,
|
||||
phone_number_id: businessDataParam.phone_number_id,
|
||||
is_business_app_onboarding:
|
||||
businessDataParam.is_business_app_onboarding || false,
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -174,7 +184,10 @@ export function useWhatsappEmbeddedSignup() {
|
||||
// Message handling
|
||||
const handleEmbeddedSignupData = async data => {
|
||||
// Handle different embedded signup events per Facebook documentation
|
||||
if (data.event === 'FINISH') {
|
||||
if (
|
||||
data.event === 'FINISH' ||
|
||||
data.event === 'FINISH_WHATSAPP_BUSINESS_APP_ONBOARDING'
|
||||
) {
|
||||
// Facebook might send business data in different structures
|
||||
let businessDataLocal = data.data;
|
||||
|
||||
@@ -194,6 +207,9 @@ export function useWhatsappEmbeddedSignup() {
|
||||
businessDataLocal.phone_number_id ||
|
||||
businessDataLocal.phoneNumberId ||
|
||||
businessDataLocal.phone_id,
|
||||
// Indicate if this is an existing WhatsApp Business App onboarding (coexistence)
|
||||
is_business_app_onboarding:
|
||||
data.event === 'FINISH_WHATSAPP_BUSINESS_APP_ONBOARDING',
|
||||
};
|
||||
|
||||
// Store business data
|
||||
@@ -312,7 +328,7 @@ export function useWhatsappEmbeddedSignup() {
|
||||
override_default_response_type: true,
|
||||
extras: {
|
||||
setup: {},
|
||||
featureType: '', // Leave empty for default flow
|
||||
featureType: 'whatsapp_business_app_onboarding', // Enable WhatsApp Business App coexistence
|
||||
sessionInfoVersion: '3',
|
||||
},
|
||||
});
|
||||
|
||||
@@ -288,9 +288,12 @@
|
||||
"LOADING_SDK": "Loading Facebook SDK...",
|
||||
"CANCELLED": "WhatsApp Signup was cancelled",
|
||||
"SUCCESS_TITLE": "WhatsApp Business Account Connected!",
|
||||
"SUCCESS_TITLE_BUSINESS_APP": "WhatsApp Business App Connected!",
|
||||
"WAITING_FOR_AUTH": "Waiting for authentication...",
|
||||
"INVALID_BUSINESS_DATA": "Invalid business data received from Facebook. Please try again.",
|
||||
"SIGNUP_ERROR": "Signup error occurred",
|
||||
"PROCESSING_BUSINESS_APP": "Connecting your existing WhatsApp Business App...",
|
||||
"PROCESSING_NEW_NUMBER": "Setting up your new WhatsApp Business number...",
|
||||
"AUTH_NOT_COMPLETED": "Authentication not completed. Please restart the process.",
|
||||
"SUCCESS_FALLBACK": "WhatsApp Business Account has been successfully configured"
|
||||
},
|
||||
|
||||
@@ -10,6 +10,33 @@ class Webhooks::WhatsappEventsJob < ApplicationJob
|
||||
return
|
||||
end
|
||||
|
||||
# Handle different webhook event types
|
||||
if sync_event?(params)
|
||||
handle_sync_events(channel, params)
|
||||
else
|
||||
handle_message_events(channel, params)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def sync_event?(params)
|
||||
field = params.dig(:entry, 0, :changes, 0, :field)
|
||||
%w[smb_app_state_sync smb_message_echoes history].include?(field)
|
||||
end
|
||||
|
||||
def handle_sync_events(channel, params)
|
||||
field = params.dig(:entry, 0, :changes, 0, :field)
|
||||
|
||||
case field
|
||||
when 'smb_app_state_sync'
|
||||
Whatsapp::ContactSyncService.new(inbox: channel.inbox, params: params).perform
|
||||
when 'smb_message_echoes', 'history'
|
||||
Whatsapp::ConversationSyncService.new(inbox: channel.inbox, params: params).perform
|
||||
end
|
||||
end
|
||||
|
||||
def handle_message_events(channel, params)
|
||||
case channel.provider
|
||||
when 'whatsapp_cloud'
|
||||
Whatsapp::IncomingMessageWhatsappCloudService.new(inbox: channel.inbox, params: params).perform
|
||||
@@ -18,8 +45,6 @@ class Webhooks::WhatsappEventsJob < ApplicationJob
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def channel_is_inactive?(channel)
|
||||
return true if channel.blank?
|
||||
return true if channel.reauthorization_required?
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
class Whatsapp::ContactSyncService
|
||||
include Rails.application.routes.url_helpers
|
||||
|
||||
pattr_initialize [:inbox!, :params!]
|
||||
|
||||
def perform
|
||||
return unless valid_sync_event?
|
||||
|
||||
sync_contacts_from_webhook
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def valid_sync_event?
|
||||
return false unless params.dig(:entry, 0, :changes, 0, :field) == 'smb_app_state_sync'
|
||||
return false if params.dig(:entry, 0, :changes, 0, :value, :state_sync).blank?
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def sync_contacts_from_webhook
|
||||
state_sync_data = params.dig(:entry, 0, :changes, 0, :value, :state_sync)
|
||||
|
||||
state_sync_data.each do |sync_item|
|
||||
next unless sync_item[:type] == 'contact'
|
||||
|
||||
process_contact_sync(sync_item)
|
||||
end
|
||||
end
|
||||
|
||||
def process_contact_sync(sync_item)
|
||||
contact_data = sync_item[:contact]
|
||||
action = sync_item[:action]
|
||||
phone_number = contact_data[:phone_number]
|
||||
|
||||
case action
|
||||
when 'add'
|
||||
create_or_update_contact(contact_data, phone_number)
|
||||
when 'remove'
|
||||
remove_contact(phone_number)
|
||||
else
|
||||
Rails.logger.warn "[WHATSAPP] Unknown contact sync action: #{action}"
|
||||
end
|
||||
rescue StandardError => e
|
||||
Rails.logger.error "[WHATSAPP] Contact sync failed for #{phone_number}: #{e.message}"
|
||||
end
|
||||
|
||||
def create_or_update_contact(contact_data, phone_number)
|
||||
formatted_phone = format_phone_number(phone_number)
|
||||
|
||||
# Find existing contact or create new one
|
||||
contact_inbox = ::ContactInboxWithContactBuilder.new(
|
||||
source_id: phone_number, # WhatsApp uses phone number without + as source_id
|
||||
inbox: inbox,
|
||||
contact_attributes: {
|
||||
name: contact_data[:full_name] || contact_data[:first_name] || formatted_phone,
|
||||
phone_number: formatted_phone,
|
||||
additional_attributes: {
|
||||
whatsapp_contact_synced: true,
|
||||
whatsapp_contact_sync_timestamp: Time.current.to_i,
|
||||
whatsapp_contact_first_name: contact_data[:first_name],
|
||||
whatsapp_contact_full_name: contact_data[:full_name]
|
||||
}
|
||||
}
|
||||
).perform
|
||||
|
||||
Rails.logger.info "[WHATSAPP] Contact synced: #{contact_data[:full_name]} (#{formatted_phone})"
|
||||
contact_inbox
|
||||
end
|
||||
|
||||
def remove_contact(phone_number)
|
||||
# Find the contact inbox for this phone number
|
||||
contact_inbox = inbox.contact_inboxes.find_by(source_id: phone_number)
|
||||
|
||||
if contact_inbox
|
||||
# Mark contact as removed from WhatsApp Business App (don't delete to preserve conversation history)
|
||||
contact = contact_inbox.contact
|
||||
contact.additional_attributes ||= {}
|
||||
contact.additional_attributes[:whatsapp_contact_removed] = true
|
||||
contact.additional_attributes[:whatsapp_contact_removed_timestamp] = Time.current.to_i
|
||||
contact.save!
|
||||
|
||||
Rails.logger.info "[WHATSAPP] Contact marked as removed: #{contact.name} (#{contact.phone_number})"
|
||||
else
|
||||
Rails.logger.warn "[WHATSAPP] Contact not found for removal: #{phone_number}"
|
||||
end
|
||||
end
|
||||
|
||||
def format_phone_number(phone_number)
|
||||
# Ensure phone number starts with + for consistency
|
||||
phone_number.start_with?('+') ? phone_number : "+#{phone_number}"
|
||||
end
|
||||
|
||||
def account
|
||||
@account ||= inbox.account
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,288 @@
|
||||
class Whatsapp::ConversationSyncService
|
||||
include Rails.application.routes.url_helpers
|
||||
include ::Whatsapp::IncomingMessageServiceHelpers
|
||||
|
||||
pattr_initialize [:inbox!, :params!]
|
||||
|
||||
def perform
|
||||
return unless valid_sync_event?
|
||||
|
||||
if history_sync_event?
|
||||
process_history_sync
|
||||
elsif message_echo_event?
|
||||
process_message_echo
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def valid_sync_event?
|
||||
# Check for history sync or message echo events
|
||||
history_sync_event? || message_echo_event?
|
||||
end
|
||||
|
||||
def history_sync_event?
|
||||
params.dig(:entry, 0, :changes, 0, :field) == 'history'
|
||||
end
|
||||
|
||||
def message_echo_event?
|
||||
params.dig(:entry, 0, :changes, 0, :field) == 'smb_message_echoes'
|
||||
end
|
||||
|
||||
def process_history_sync
|
||||
history_data = params.dig(:entry, 0, :changes, 0, :value, :history)
|
||||
|
||||
return handle_history_sync_error if history_data&.dig(0, :errors).present?
|
||||
|
||||
history_data.each do |history_item|
|
||||
next if history_item[:data].blank?
|
||||
|
||||
sync_historical_data(history_item[:data])
|
||||
end
|
||||
end
|
||||
|
||||
def handle_history_sync_error
|
||||
error_info = params.dig(:entry, 0, :changes, 0, :value, :history, 0, :errors, 0)
|
||||
Rails.logger.warn "[WHATSAPP] History sync declined or failed: #{error_info[:message]}"
|
||||
end
|
||||
|
||||
def sync_historical_data(data)
|
||||
contacts = data[:contacts] || []
|
||||
messages = data[:messages] || []
|
||||
|
||||
# First, ensure contacts exist
|
||||
contacts.each { |contact_data| create_contact_from_history(contact_data) }
|
||||
|
||||
# Then, sync historical messages
|
||||
messages.each { |message_data| create_message_from_history(message_data) }
|
||||
end
|
||||
|
||||
def create_contact_from_history(contact_data)
|
||||
phone_number = contact_data[:wa_id]
|
||||
contact_name = contact_data.dig(:profile, :name) || phone_number
|
||||
|
||||
::ContactInboxWithContactBuilder.new(
|
||||
source_id: phone_number,
|
||||
inbox: inbox,
|
||||
contact_attributes: {
|
||||
name: contact_name,
|
||||
phone_number: format_phone_number(phone_number),
|
||||
additional_attributes: {
|
||||
whatsapp_contact_synced: true,
|
||||
whatsapp_history_synced: true,
|
||||
whatsapp_history_sync_timestamp: Time.current.to_i
|
||||
}
|
||||
}
|
||||
).perform
|
||||
rescue StandardError => e
|
||||
Rails.logger.error "[WHATSAPP] Failed to create contact from history: #{e.message}"
|
||||
end
|
||||
|
||||
def create_message_from_history(message_data)
|
||||
return unless valid_message_data?(message_data)
|
||||
|
||||
phone_number = message_data[:from]
|
||||
contact_inbox = find_or_create_contact_inbox(phone_number)
|
||||
return unless contact_inbox
|
||||
|
||||
conversation = find_or_create_conversation(contact_inbox)
|
||||
return unless conversation
|
||||
|
||||
create_historical_message(message_data, conversation, contact_inbox.contact)
|
||||
rescue StandardError => e
|
||||
Rails.logger.error "[WHATSAPP] Failed to create historical message: #{e.message}"
|
||||
end
|
||||
|
||||
def process_message_echo
|
||||
message_echoes = params.dig(:entry, 0, :changes, 0, :value, :message_echoes) || []
|
||||
|
||||
message_echoes.each do |echo_data|
|
||||
create_echo_message(echo_data)
|
||||
end
|
||||
end
|
||||
|
||||
def create_echo_message(echo_data)
|
||||
return unless valid_echo_data?(echo_data)
|
||||
|
||||
to_phone_number = echo_data[:to]
|
||||
echo_data[:from]
|
||||
|
||||
# Find the contact this message was sent to
|
||||
contact_inbox = find_contact_inbox_by_phone(to_phone_number)
|
||||
return unless contact_inbox
|
||||
|
||||
conversation = find_or_create_conversation(contact_inbox)
|
||||
return unless conversation
|
||||
|
||||
# Create outgoing message (sent from business via WhatsApp Business App)
|
||||
create_echo_message_record(echo_data, conversation, contact_inbox.contact)
|
||||
rescue StandardError => e
|
||||
Rails.logger.error "[WHATSAPP] Failed to create echo message: #{e.message}"
|
||||
end
|
||||
|
||||
def valid_message_data?(message_data)
|
||||
message_data[:id].present? &&
|
||||
message_data[:from].present? &&
|
||||
message_data[:timestamp].present? &&
|
||||
message_data[:type].present?
|
||||
end
|
||||
|
||||
def valid_echo_data?(echo_data)
|
||||
echo_data[:id].present? &&
|
||||
echo_data[:to].present? &&
|
||||
echo_data[:from].present? &&
|
||||
echo_data[:timestamp].present? &&
|
||||
echo_data[:type].present?
|
||||
end
|
||||
|
||||
def find_or_create_contact_inbox(phone_number)
|
||||
contact_inbox = inbox.contact_inboxes.find_by(source_id: phone_number)
|
||||
return contact_inbox if contact_inbox
|
||||
|
||||
# Create contact if not exists
|
||||
::ContactInboxWithContactBuilder.new(
|
||||
source_id: phone_number,
|
||||
inbox: inbox,
|
||||
contact_attributes: {
|
||||
name: format_phone_number(phone_number),
|
||||
phone_number: format_phone_number(phone_number),
|
||||
additional_attributes: {
|
||||
whatsapp_history_synced: true
|
||||
}
|
||||
}
|
||||
).perform
|
||||
end
|
||||
|
||||
def find_contact_inbox_by_phone(phone_number)
|
||||
# For echo messages, we need to find contact by their WhatsApp ID (without +)
|
||||
inbox.contact_inboxes.find_by(source_id: phone_number)
|
||||
end
|
||||
|
||||
def find_or_create_conversation(contact_inbox)
|
||||
# Look for existing conversation or create new one
|
||||
conversation = if inbox.lock_to_single_conversation
|
||||
contact_inbox.conversations.last
|
||||
else
|
||||
contact_inbox.conversations.where.not(status: :resolved).last
|
||||
end
|
||||
|
||||
return conversation if conversation
|
||||
|
||||
::Conversation.create!(
|
||||
account_id: inbox.account_id,
|
||||
inbox_id: inbox.id,
|
||||
contact_id: contact_inbox.contact_id,
|
||||
contact_inbox_id: contact_inbox.id,
|
||||
additional_attributes: {
|
||||
whatsapp_history_synced: true
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
def create_historical_message(message_data, conversation, contact)
|
||||
# Skip if message already exists
|
||||
return if conversation.messages.find_by(source_id: message_data[:id])
|
||||
|
||||
message_content = extract_message_content(message_data)
|
||||
external_timestamp = Time.zone.at(message_data[:timestamp].to_i)
|
||||
|
||||
message = conversation.messages.build(
|
||||
content: message_content,
|
||||
account_id: inbox.account_id,
|
||||
inbox_id: inbox.id,
|
||||
message_type: :incoming,
|
||||
sender: contact,
|
||||
source_id: message_data[:id],
|
||||
created_at: external_timestamp,
|
||||
content_attributes: {
|
||||
external_created_at: external_timestamp.iso8601,
|
||||
whatsapp_history_synced: true
|
||||
}
|
||||
)
|
||||
|
||||
# Handle different message types
|
||||
case message_data[:type]
|
||||
when 'image', 'audio', 'video', 'document'
|
||||
attach_media_from_history(message, message_data)
|
||||
when 'location'
|
||||
attach_location_from_history(message, message_data)
|
||||
end
|
||||
|
||||
message.save!
|
||||
Rails.logger.info "[WHATSAPP] Historical message synced: #{message_data[:id]}"
|
||||
end
|
||||
|
||||
def create_echo_message_record(echo_data, conversation, _contact)
|
||||
# Skip if message already exists
|
||||
return if conversation.messages.find_by(source_id: echo_data[:id])
|
||||
|
||||
message_content = extract_message_content(echo_data)
|
||||
external_timestamp = Time.zone.at(echo_data[:timestamp].to_i)
|
||||
|
||||
message = conversation.messages.build(
|
||||
content: message_content,
|
||||
account_id: inbox.account_id,
|
||||
inbox_id: inbox.id,
|
||||
message_type: :outgoing, # This is a message sent by the business
|
||||
sender: nil, # Business messages don't have a sender contact
|
||||
source_id: echo_data[:id],
|
||||
created_at: external_timestamp,
|
||||
content_attributes: {
|
||||
external_created_at: external_timestamp.iso8601,
|
||||
whatsapp_echo_message: true
|
||||
}
|
||||
)
|
||||
|
||||
message.save!
|
||||
Rails.logger.info "[WHATSAPP] Echo message synced: #{echo_data[:id]}"
|
||||
end
|
||||
|
||||
def extract_message_content(message_data)
|
||||
case message_data[:type]
|
||||
when 'text'
|
||||
message_data.dig(:text, :body)
|
||||
when 'image', 'audio', 'video', 'document'
|
||||
message_data.dig(message_data[:type].to_sym, :caption) || message_data[:type].humanize
|
||||
when 'location'
|
||||
location = message_data[:location]
|
||||
"Location: #{location[:name] || 'Shared location'}"
|
||||
else
|
||||
message_data[:type].humanize
|
||||
end
|
||||
end
|
||||
|
||||
def attach_media_from_history(message, message_data)
|
||||
# NOTE: Historical media might not be available for download
|
||||
# We'll just record the media info in content_attributes
|
||||
media_data = message_data[message_data[:type].to_sym] || {}
|
||||
|
||||
message.content_attributes[:media_info] = {
|
||||
type: message_data[:type],
|
||||
caption: media_data[:caption],
|
||||
filename: media_data[:filename],
|
||||
mime_type: media_data[:mime_type],
|
||||
sha256: media_data[:sha256],
|
||||
id: media_data[:id]
|
||||
}
|
||||
end
|
||||
|
||||
def attach_location_from_history(message, message_data)
|
||||
location = message_data[:location] || {}
|
||||
|
||||
message.content_attributes[:location_info] = {
|
||||
latitude: location[:latitude],
|
||||
longitude: location[:longitude],
|
||||
name: location[:name],
|
||||
address: location[:address],
|
||||
url: location[:url]
|
||||
}
|
||||
end
|
||||
|
||||
def format_phone_number(phone_number)
|
||||
phone_number.start_with?('+') ? phone_number : "+#{phone_number}"
|
||||
end
|
||||
|
||||
def account
|
||||
@account ||= inbox.account
|
||||
end
|
||||
end
|
||||
@@ -1,12 +1,13 @@
|
||||
class Whatsapp::EmbeddedSignupService
|
||||
include Rails.application.routes.url_helpers
|
||||
|
||||
def initialize(account:, code:, business_id:, waba_id:, phone_number_id:)
|
||||
def initialize(account:, code:, business_id:, waba_id:, phone_number_id:, is_business_app_onboarding: false)
|
||||
@account = account
|
||||
@code = code
|
||||
@business_id = business_id
|
||||
@waba_id = waba_id
|
||||
@phone_number_id = phone_number_id
|
||||
@is_business_app_onboarding = is_business_app_onboarding
|
||||
end
|
||||
|
||||
def perform
|
||||
@@ -27,7 +28,12 @@ class Whatsapp::EmbeddedSignupService
|
||||
|
||||
waba_info = { waba_id: @waba_id, business_name: phone_info[:business_name] }
|
||||
|
||||
create_or_update_channel(waba_info, phone_info, access_token)
|
||||
channel = create_or_update_channel(waba_info, phone_info, access_token)
|
||||
|
||||
# Enable sync features for WhatsApp Business App coexistence
|
||||
enable_sync_features(channel, access_token) if channel
|
||||
|
||||
channel
|
||||
rescue StandardError => e
|
||||
Rails.logger.error("[WHATSAPP] Signup failed: #{e.message}")
|
||||
raise e
|
||||
@@ -90,7 +96,11 @@ class Whatsapp::EmbeddedSignupService
|
||||
raise "Channel already exists: #{existing_channel.phone_number}"
|
||||
else
|
||||
channel = create_new_channel(channel_attributes, phone_info)
|
||||
register_phone_number(phone_info[:phone_number_id], access_token)
|
||||
|
||||
# Skip phone number registration for WhatsApp Business App onboarding (coexistence)
|
||||
# as the number is already registered in the WhatsApp Business App
|
||||
register_phone_number(phone_info[:phone_number_id], access_token) unless @is_business_app_onboarding
|
||||
|
||||
override_waba_webhook(waba_info[:waba_id], channel, access_token)
|
||||
channel
|
||||
end
|
||||
@@ -200,7 +210,9 @@ class Whatsapp::EmbeddedSignupService
|
||||
},
|
||||
body: {
|
||||
override_callback_uri: callback_url,
|
||||
verify_token: verify_token
|
||||
verify_token: verify_token,
|
||||
# Enable sync features for WhatsApp Business App coexistence
|
||||
webhook_fields: %w[messages smb_app_state_sync smb_message_echoes]
|
||||
}.to_json
|
||||
}
|
||||
)
|
||||
@@ -210,4 +222,61 @@ class Whatsapp::EmbeddedSignupService
|
||||
Rails.logger.error("[WHATSAPP] Webhook override failed: #{response.body}")
|
||||
raise "Webhook override failed: #{response.body}"
|
||||
end
|
||||
|
||||
# Enable sync features for WhatsApp Business App coexistence
|
||||
def enable_sync_features(channel, access_token)
|
||||
# Initialize contact sync for existing WhatsApp Business App contacts
|
||||
sync_contacts(channel, access_token)
|
||||
|
||||
# Request conversation history sync (if business allows)
|
||||
request_conversation_history_sync(channel, access_token)
|
||||
end
|
||||
|
||||
def sync_contacts(channel, access_token)
|
||||
Rails.logger.info("[WHATSAPP] Initiating contact sync for channel #{channel.id}")
|
||||
|
||||
# Make API call to sync contacts from WhatsApp Business App
|
||||
response = HTTParty.post(
|
||||
"https://graph.facebook.com/#{whatsapp_api_version}/#{channel.provider_config['phone_number_id']}/request_sync",
|
||||
{
|
||||
headers: {
|
||||
'Authorization' => "Bearer #{access_token}",
|
||||
'Content-Type' => 'application/json'
|
||||
},
|
||||
body: {
|
||||
sync_type: 'contact'
|
||||
}.to_json
|
||||
}
|
||||
)
|
||||
|
||||
if response.success?
|
||||
Rails.logger.info("[WHATSAPP] Contact sync initiated successfully for channel #{channel.id}")
|
||||
else
|
||||
Rails.logger.warn("[WHATSAPP] Contact sync failed for channel #{channel.id}: #{response.body}")
|
||||
end
|
||||
end
|
||||
|
||||
def request_conversation_history_sync(channel, access_token)
|
||||
Rails.logger.info("[WHATSAPP] Initiating conversation history sync for channel #{channel.id}")
|
||||
|
||||
# Make API call to sync conversation history from WhatsApp Business App
|
||||
response = HTTParty.post(
|
||||
"https://graph.facebook.com/#{whatsapp_api_version}/#{channel.provider_config['phone_number_id']}/request_sync",
|
||||
{
|
||||
headers: {
|
||||
'Authorization' => "Bearer #{access_token}",
|
||||
'Content-Type' => 'application/json'
|
||||
},
|
||||
body: {
|
||||
sync_type: 'history'
|
||||
}.to_json
|
||||
}
|
||||
)
|
||||
|
||||
if response.success?
|
||||
Rails.logger.info("[WHATSAPP] Conversation history sync initiated successfully for channel #{channel.id}")
|
||||
else
|
||||
Rails.logger.warn("[WHATSAPP] Conversation history sync failed for channel #{channel.id}: #{response.body}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user