chore: voice call components working correctly
This commit is contained in:
@@ -9,18 +9,27 @@ module Voice
|
||||
begin
|
||||
find_inbox
|
||||
create_contact
|
||||
create_conversation
|
||||
create_voice_call_message
|
||||
|
||||
# Use a transaction to ensure the conversation and voice call message are created together
|
||||
# This ensures the voice call message is created before any auto-assignment activity messages
|
||||
ActiveRecord::Base.transaction do
|
||||
create_conversation
|
||||
create_voice_call_message
|
||||
end
|
||||
|
||||
# Create activity message separately, after the voice call message
|
||||
create_activity_message
|
||||
|
||||
twiml = generate_twiml_response
|
||||
|
||||
|
||||
Rails.logger.info("✅ INCOMING CALL: Successfully processed for call_sid=#{caller_info[:call_sid]}")
|
||||
return twiml
|
||||
twiml
|
||||
rescue StandardError => e
|
||||
Rails.logger.error("❌ INCOMING CALL ERROR: #{e.message}")
|
||||
Rails.logger.error("❌ INCOMING CALL BACKTRACE: #{e.backtrace[0..5].join("\n")}")
|
||||
|
||||
|
||||
# Return a simple error TwiML
|
||||
return error_twiml(e.message)
|
||||
error_twiml(e.message)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -37,25 +46,25 @@ module Voice
|
||||
def find_inbox
|
||||
# Find the inbox for this phone number
|
||||
@inbox = account.inboxes
|
||||
.where(channel_type: 'Channel::Voice')
|
||||
.joins('INNER JOIN channel_voice ON channel_voice.id = inboxes.channel_id')
|
||||
.where('channel_voice.phone_number = ?', caller_info[:to_number])
|
||||
.first
|
||||
|
||||
.where(channel_type: 'Channel::Voice')
|
||||
.joins('INNER JOIN channel_voice ON channel_voice.id = inboxes.channel_id')
|
||||
.where('channel_voice.phone_number = ?', caller_info[:to_number])
|
||||
.first
|
||||
|
||||
raise "Inbox not found for phone number #{caller_info[:to_number]}" unless @inbox.present?
|
||||
|
||||
|
||||
Rails.logger.info("📥 FOUND INBOX: inbox_id=#{@inbox.id} for phone=#{caller_info[:to_number]}")
|
||||
end
|
||||
|
||||
def create_contact
|
||||
# Normalize the phone number
|
||||
phone_number = caller_info[:from_number].strip
|
||||
|
||||
|
||||
# Find or create the contact
|
||||
@contact = account.contacts.find_or_create_by!(phone_number: phone_number) do |c|
|
||||
c.name = "Contact from #{phone_number}"
|
||||
end
|
||||
|
||||
|
||||
Rails.logger.info("👤 CONTACT: contact_id=#{@contact.id} name=#{@contact.name} phone=#{@contact.phone_number}")
|
||||
end
|
||||
|
||||
@@ -65,11 +74,11 @@ module Voice
|
||||
contact_id: @contact.id,
|
||||
inbox_id: @inbox.id
|
||||
)
|
||||
|
||||
|
||||
# Set source_id if not already set
|
||||
@contact_inbox.source_id ||= caller_info[:from_number]
|
||||
@contact_inbox.save!
|
||||
|
||||
|
||||
Rails.logger.info("📬 CONTACT INBOX: id=#{@contact_inbox.id} source_id=#{@contact_inbox.source_id}")
|
||||
|
||||
# Create a new conversation with call details
|
||||
@@ -117,17 +126,22 @@ module Voice
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Create the message
|
||||
|
||||
# Create the voice call message only - this ensures it appears first
|
||||
@voice_call_message = Messages::MessageBuilder.new(
|
||||
@contact,
|
||||
@conversation,
|
||||
message_params
|
||||
).perform
|
||||
|
||||
|
||||
Rails.logger.info("✉️ VOICE CALL MESSAGE: id=#{@voice_call_message.id} content_type=#{@voice_call_message.content_type}")
|
||||
|
||||
# Create an activity message for the incoming call
|
||||
|
||||
# Broadcast call notification
|
||||
broadcast_call_status
|
||||
end
|
||||
|
||||
# Create activity message separately after the voice call message
|
||||
def create_activity_message
|
||||
activity_message = Messages::MessageBuilder.new(
|
||||
nil,
|
||||
@conversation,
|
||||
@@ -136,11 +150,8 @@ module Voice
|
||||
message_type: :activity
|
||||
}
|
||||
).perform
|
||||
|
||||
|
||||
Rails.logger.info("📝 ACTIVITY MESSAGE: id=#{activity_message.id}")
|
||||
|
||||
# Broadcast call notification
|
||||
broadcast_call_status
|
||||
end
|
||||
|
||||
def broadcast_call_status
|
||||
@@ -159,19 +170,19 @@ module Voice
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
Rails.logger.info("📢 BROADCAST: Sent incoming_call notification")
|
||||
|
||||
Rails.logger.info('📢 BROADCAST: Sent incoming_call notification')
|
||||
end
|
||||
|
||||
def generate_twiml_response
|
||||
conference_name = @conversation.additional_attributes['conference_sid']
|
||||
|
||||
|
||||
response = Twilio::TwiML::VoiceResponse.new
|
||||
response.say(message: 'Thank you for calling. Please wait while we connect you with an agent.')
|
||||
|
||||
|
||||
callback_url = "#{base_url}/api/v1/accounts/#{account.id}/channels/voice/webhooks/conference_status"
|
||||
Rails.logger.info("🔗 CONFERENCE CALLBACK URL: #{callback_url}")
|
||||
|
||||
|
||||
response.dial do |dial|
|
||||
dial.conference(
|
||||
conference_name,
|
||||
@@ -186,7 +197,7 @@ module Voice
|
||||
participantLabel: "caller-#{caller_info[:call_sid].last(8)}"
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
Rails.logger.info("📞 TWIML: Generated conference TwiML for #{conference_name}")
|
||||
response.to_s
|
||||
end
|
||||
@@ -195,7 +206,7 @@ module Voice
|
||||
response = Twilio::TwiML::VoiceResponse.new
|
||||
response.say(message: 'We are experiencing technical difficulties with our phone system. Please try again later.')
|
||||
response.hangup
|
||||
|
||||
|
||||
Rails.logger.info("❌ ERROR TWIML: Generated error TwiML due to: #{message}")
|
||||
response.to_s
|
||||
end
|
||||
@@ -203,7 +214,7 @@ module Voice
|
||||
def base_url
|
||||
url = ENV.fetch('FRONTEND_URL', "https://#{params['host_with_port']}")
|
||||
Rails.logger.info("🌐 BASE URL: Using #{url}")
|
||||
url.gsub(/\/$/, '') # Remove trailing slash if present
|
||||
url.gsub(%r{/$}, '') # Remove trailing slash if present
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,9 +4,18 @@ module Voice
|
||||
|
||||
def process
|
||||
find_voice_inbox
|
||||
create_conversation
|
||||
initiate_call
|
||||
create_voice_call_message
|
||||
|
||||
# Create conversation and voice message in a single transaction
|
||||
# This ensures the voice call message is created before any auto-assignment activity messages
|
||||
ActiveRecord::Base.transaction do
|
||||
create_conversation
|
||||
initiate_call
|
||||
create_voice_call_message
|
||||
end
|
||||
|
||||
# Add the activity message separately, after the voice call message
|
||||
create_activity_message
|
||||
|
||||
broadcast_to_agent
|
||||
@conversation
|
||||
end
|
||||
@@ -15,8 +24,8 @@ module Voice
|
||||
|
||||
def find_voice_inbox
|
||||
@voice_inbox = account.inboxes.find_by(channel_type: 'Channel::Voice')
|
||||
raise "No Voice channel found" if @voice_inbox.blank?
|
||||
raise "Contact has no phone number" if contact.phone_number.blank?
|
||||
raise 'No Voice channel found' if @voice_inbox.blank?
|
||||
raise 'Contact has no phone number' if contact.phone_number.blank?
|
||||
end
|
||||
|
||||
def create_conversation
|
||||
@@ -28,7 +37,7 @@ module Voice
|
||||
inbox: @voice_inbox,
|
||||
call_sid: nil # This will be set after call is initiated
|
||||
).perform
|
||||
|
||||
|
||||
# Create conference name for outbound call
|
||||
@conference_name = @conversation.additional_attributes['conference_sid']
|
||||
end
|
||||
@@ -36,19 +45,19 @@ module Voice
|
||||
def initiate_call
|
||||
# Initiate the call using the channel's implementation
|
||||
@call_details = @voice_inbox.channel.initiate_call(
|
||||
to: contact.phone_number,
|
||||
to: contact.phone_number,
|
||||
conference_name: @conference_name,
|
||||
agent_id: user.id # Pass the agent ID to track who initiated the call
|
||||
)
|
||||
|
||||
|
||||
# Update conversation with call details
|
||||
updated_attributes = @conversation.additional_attributes.merge({
|
||||
'call_sid' => @call_details[:call_sid],
|
||||
'call_status' => 'in-progress',
|
||||
'requires_agent_join' => true,
|
||||
'agent_id' => user.id # Store the agent ID who initiated the call
|
||||
})
|
||||
|
||||
'call_sid' => @call_details[:call_sid],
|
||||
'call_status' => 'in-progress',
|
||||
'requires_agent_join' => true,
|
||||
'agent_id' => user.id # Store the agent ID who initiated the call
|
||||
})
|
||||
|
||||
@conversation.update!(additional_attributes: updated_attributes)
|
||||
end
|
||||
|
||||
@@ -75,24 +84,26 @@ module Voice
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Create the message
|
||||
|
||||
# Create just the voice call message - this ensures it appears first in the conversation
|
||||
@widget_message = Messages::MessageBuilder.new(
|
||||
user,
|
||||
@conversation,
|
||||
message_params
|
||||
).perform
|
||||
|
||||
# Create an activity message for the outgoing call
|
||||
|
||||
# Update last activity timestamp
|
||||
@conversation.update(last_activity_at: Time.current)
|
||||
end
|
||||
|
||||
# Create the activity message in a separate method
|
||||
def create_activity_message
|
||||
message_service = Voice::MessageUpdateService.new(
|
||||
conversation: @conversation,
|
||||
call_sid: @call_details[:call_sid]
|
||||
)
|
||||
|
||||
|
||||
message_service.create_activity_message("Outgoing call to #{contact.name || contact.phone_number}")
|
||||
|
||||
# Update last activity timestamp
|
||||
@conversation.update(last_activity_at: Time.current)
|
||||
end
|
||||
|
||||
def broadcast_to_agent
|
||||
@@ -116,7 +127,7 @@ module Voice
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
# Broadcast the conversation and message
|
||||
ActionCableBroadcastJob.perform_later(
|
||||
@conversation.account_id,
|
||||
@@ -128,4 +139,4 @@ module Voice
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user