fix: only subscribe calls webhook field when voice calling enabled (#14718)
## Description Solves issue https://github.com/chatwoot/chatwoot/issues/14690 ## Type of change - [ ] Bug fix (non-breaking change which fixes an issue) ## How has this been tested? - UI flows ## Checklist: - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules --------- Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
This commit is contained in:
co-authored by
Muhsin Keloth
parent
c041fde3a2
commit
e055cead35
@@ -69,8 +69,10 @@ class Channel::Whatsapp < ApplicationRecord
|
||||
end
|
||||
end
|
||||
|
||||
# Enables voice: turns calling on at Meta (idempotent), subscribes the `calls`
|
||||
# webhook field, and sets calling_enabled. Raises on Meta failure.
|
||||
# Enables voice: turns calling on at Meta (idempotent), then re-registers webhooks
|
||||
# with the in-memory calling_enabled flag so the `calls` field is subscribed. The
|
||||
# flag is persisted only after registration succeeds, so a webhook failure can't
|
||||
# leave the inbox reporting voice_enabled? while the WABA isn't subscribed to calls.
|
||||
# Saved with validate: false to skip validate_provider_config's remote credential
|
||||
# re-check, which could spuriously fail and desync the flag from Meta.
|
||||
def enable_voice_calling!
|
||||
@@ -78,21 +80,21 @@ class Channel::Whatsapp < ApplicationRecord
|
||||
raise 'WhatsApp calling requires the channel_voice feature' unless account.feature_enabled?('channel_voice')
|
||||
|
||||
provider_service.update_calling_status('ENABLED')
|
||||
webhook_setup_service.register_callback
|
||||
self.provider_config = provider_config.merge('calling_enabled' => true)
|
||||
webhook_setup_service.register_callback
|
||||
save!(validate: false)
|
||||
end
|
||||
|
||||
# Disables voice: unsets calling_enabled (gates the call subsystem) and drops
|
||||
# `calls` from the webhook subscription (best-effort, so a Meta outage can't
|
||||
# trap admins). Leaves Meta's WABA calling.status untouched.
|
||||
# Disables voice: unsets calling_enabled (gates the call subsystem) and re-registers
|
||||
# webhooks, which drops `calls` from the subscription (best-effort, so a Meta outage
|
||||
# can't trap admins). Leaves Meta's WABA calling.status untouched.
|
||||
def disable_voice_calling!
|
||||
raise 'WhatsApp calling requires a whatsapp_cloud inbox' unless voice_calling_supported?
|
||||
|
||||
self.provider_config = provider_config.merge('calling_enabled' => false)
|
||||
save!(validate: false)
|
||||
begin
|
||||
webhook_setup_service.register_callback(subscribed_fields: %w[messages smb_message_echoes])
|
||||
webhook_setup_service.register_callback
|
||||
rescue StandardError => e
|
||||
Rails.logger.warn "[WHATSAPP CALL] disable webhook re-subscribe failed: #{e.message}"
|
||||
end
|
||||
|
||||
@@ -60,7 +60,7 @@ class Whatsapp::FacebookApiClient
|
||||
data['code_verification_status'] == 'VERIFIED'
|
||||
end
|
||||
|
||||
WEBHOOK_DEFAULT_FIELDS = %w[messages smb_message_echoes calls].freeze
|
||||
WEBHOOK_DEFAULT_FIELDS = %w[messages smb_message_echoes].freeze
|
||||
|
||||
def subscribe_waba_webhook(waba_id, callback_url, verify_token, subscribed_fields: WEBHOOK_DEFAULT_FIELDS)
|
||||
# Step 1: Subscribe app to WABA first (required before override)
|
||||
|
||||
@@ -17,9 +17,9 @@ class Whatsapp::WebhookSetupService
|
||||
setup_webhook
|
||||
end
|
||||
|
||||
def register_callback(subscribed_fields: nil)
|
||||
def register_callback
|
||||
validate_parameters!
|
||||
setup_webhook(subscribed_fields: subscribed_fields)
|
||||
setup_webhook
|
||||
end
|
||||
|
||||
private
|
||||
@@ -55,21 +55,23 @@ class Whatsapp::WebhookSetupService
|
||||
@channel.save!
|
||||
end
|
||||
|
||||
def setup_webhook(subscribed_fields: nil)
|
||||
def setup_webhook
|
||||
callback_url = build_callback_url
|
||||
verify_token = @channel.provider_config['webhook_verify_token']
|
||||
|
||||
args = [@waba_id, callback_url, verify_token]
|
||||
if subscribed_fields
|
||||
@api_client.subscribe_waba_webhook(*args, subscribed_fields: subscribed_fields)
|
||||
else
|
||||
@api_client.subscribe_waba_webhook(*args)
|
||||
end
|
||||
@api_client.subscribe_waba_webhook(@waba_id, callback_url, verify_token, subscribed_fields: subscribed_fields)
|
||||
rescue StandardError => e
|
||||
Rails.logger.error("[WHATSAPP] Webhook setup failed: #{e.message}")
|
||||
raise "Webhook setup failed: #{e.message}"
|
||||
end
|
||||
|
||||
# Subscribe to `calls` only when voice calling is enabled on the inbox
|
||||
def subscribed_fields
|
||||
fields = %w[messages smb_message_echoes]
|
||||
fields << 'calls' if @channel.provider_config['calling_enabled']
|
||||
fields
|
||||
end
|
||||
|
||||
def build_callback_url
|
||||
frontend_url = ENV.fetch('FRONTEND_URL', nil)
|
||||
phone_number = @channel.phone_number
|
||||
|
||||
Reference in New Issue
Block a user