fix: restore missing functionality to enterprise voice model
Add back critical methods that were missing from enterprise voice model: - initiate_call: Core functionality for making calls - initiate_twilio_call: Twilio-specific call logic with conference support - twilio_client: Twilio client initialization - provider_config_hash: Config parsing utilities - Rails routes inclusion for URL helpers This ensures the enterprise model has complete functionality from the original. 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
#
|
||||
class Channel::Voice < ApplicationRecord
|
||||
include Channelable
|
||||
include Rails.application.routes.url_helpers
|
||||
|
||||
self.table_name = 'channel_voice'
|
||||
|
||||
@@ -41,6 +42,18 @@ class Channel::Voice < ApplicationRecord
|
||||
false
|
||||
end
|
||||
|
||||
def initiate_call(to:, conference_name: nil, agent_id: nil)
|
||||
case provider
|
||||
when 'twilio'
|
||||
initiate_twilio_call(to, conference_name, agent_id)
|
||||
# Add more providers as needed
|
||||
# when 'other_provider'
|
||||
# initiate_other_provider_call(to)
|
||||
else
|
||||
raise "Unsupported voice provider: #{provider}"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def validate_provider_config
|
||||
@@ -60,5 +73,97 @@ class Channel::Voice < ApplicationRecord
|
||||
errors.add(:provider_config, "#{key} is required for Twilio provider") if config[key].blank?
|
||||
end
|
||||
end
|
||||
|
||||
def initiate_twilio_call(to, conference_name = nil, agent_id = nil)
|
||||
config = provider_config_hash
|
||||
|
||||
# Generate a public URL for Twilio to request TwiML (must set FRONTEND_URL)
|
||||
host = ENV.fetch('FRONTEND_URL')
|
||||
|
||||
# Use the simplest possible TwiML endpoint
|
||||
callback_url = "#{host}/twilio/voice/simple"
|
||||
|
||||
# Start building query parameters
|
||||
query_params = []
|
||||
|
||||
# Make sure conference_name is URL-safe and correctly formatted
|
||||
if conference_name.present?
|
||||
# Check format - it should be like 'conf_account_123_conv_456'
|
||||
if !conference_name.match?(/^conf_account_\d+_conv_\d+$/)
|
||||
# If format is wrong, log an error and try to fix it
|
||||
Rails.logger.error("🚨 MALFORMED CONFERENCE NAME: '#{conference_name}'")
|
||||
|
||||
# Try to extract account_id and conversation_id from the string if possible
|
||||
if conference_name.include?('_account_') && conference_name.include?('_conv_')
|
||||
# It has the parts but wrong format, let's try to keep it
|
||||
Rails.logger.info("🔄 Using conference name as-is: '#{conference_name}'")
|
||||
else
|
||||
# Can't salvage it, generate a placeholder with timestamp to avoid collisions
|
||||
timestamp = Time.now.to_i
|
||||
Rails.logger.warn("🚨 GENERATING PLACEHOLDER CONFERENCE NAME with timestamp #{timestamp}")
|
||||
conference_name = "conf_placeholder_#{timestamp}"
|
||||
end
|
||||
else
|
||||
# Format looks good, continue
|
||||
Rails.logger.info("✅ VALIDATED CONFERENCE NAME: '#{conference_name}'")
|
||||
end
|
||||
|
||||
# Add URL-encoded conference name as a parameter
|
||||
query_params << "conference_name=#{CGI.escape(conference_name)}"
|
||||
else
|
||||
# No conference name provided, log this as a warning
|
||||
Rails.logger.warn("⚠️ NO CONFERENCE NAME PROVIDED for outgoing call to #{to}")
|
||||
end
|
||||
|
||||
# Add agent ID as a parameter if provided
|
||||
query_params << "agent_id=#{agent_id}" if agent_id.present?
|
||||
|
||||
# Append query parameters to URL if any exist
|
||||
if query_params.any?
|
||||
callback_url += "?#{query_params.join('&')}"
|
||||
Rails.logger.info("📞 OUTBOUND CALL: Using callback URL with params: #{callback_url}")
|
||||
end
|
||||
|
||||
# Parameters including status callbacks for call progress tracking
|
||||
params = {
|
||||
from: phone_number,
|
||||
to: to,
|
||||
url: callback_url,
|
||||
status_callback: "#{host}/twilio/voice/status_callback",
|
||||
status_callback_event: %w[initiated ringing answered completed failed busy no-answer canceled],
|
||||
status_callback_method: 'POST'
|
||||
}
|
||||
|
||||
# Log the full parameters for debugging
|
||||
Rails.logger.info("📞 OUTBOUND CALL PARAMS: to=#{to}, from=#{phone_number}, conference=#{conference_name}")
|
||||
|
||||
# Create the call
|
||||
call = twilio_client(config).calls.create(**params)
|
||||
|
||||
# Return info needed to properly route and track the call
|
||||
{
|
||||
provider: 'twilio',
|
||||
call_sid: call.sid,
|
||||
status: call.status,
|
||||
call_direction: 'outbound', # CRITICAL: Tag as outbound so webhooks know to prompt agent
|
||||
requires_agent_join: true, # Flag that agent should join immediately
|
||||
agent_id: agent_id, # Include agent_id for tracking who initiated the call
|
||||
conference_name: conference_name # Include the conference name in the return value for debugging
|
||||
}
|
||||
end
|
||||
|
||||
def twilio_client(config)
|
||||
Twilio::REST::Client.new(config['account_sid'], config['auth_token'])
|
||||
end
|
||||
|
||||
def provider_config_hash
|
||||
if provider_config.is_a?(Hash)
|
||||
provider_config
|
||||
else
|
||||
JSON.parse(provider_config.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
public :provider_config_hash
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user