feat: Add unified Call model for voice calling (#14026)
Adds a Call model to track voice call state across providers (Twilio, WhatsApp). This replaces storing call data in conversation.additional_attributes and provides a foundation for call analytics multi-call-per-conversation support, and future voice providers. --------- Co-authored-by: Muhsin <12408980+muhsin-k@users.noreply.github.com>
This commit is contained in:
55
enterprise/app/models/call.rb
Normal file
55
enterprise/app/models/call.rb
Normal file
@@ -0,0 +1,55 @@
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: calls
|
||||
#
|
||||
# id :bigint not null, primary key
|
||||
# direction :integer not null
|
||||
# duration_seconds :integer
|
||||
# end_reason :string
|
||||
# meta :jsonb
|
||||
# provider :integer default("twilio"), not null
|
||||
# started_at :datetime
|
||||
# status :string default("ringing"), not null
|
||||
# transcript :text
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# accepted_by_agent_id :bigint
|
||||
# account_id :bigint not null
|
||||
# contact_id :bigint not null
|
||||
# conversation_id :bigint not null
|
||||
# inbox_id :bigint not null
|
||||
# message_id :bigint
|
||||
# provider_call_id :string not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_calls_on_account_id_and_contact_id (account_id,contact_id)
|
||||
# index_calls_on_account_id_and_conversation_id (account_id,conversation_id)
|
||||
# index_calls_on_message_id (message_id)
|
||||
# index_calls_on_provider_and_provider_call_id (provider,provider_call_id) UNIQUE
|
||||
#
|
||||
class Call < ApplicationRecord
|
||||
# All valid call statuses
|
||||
STATUSES = %w[ringing in_progress completed no_answer failed].freeze
|
||||
# Statuses where the call is finished and won't change again
|
||||
TERMINAL_STATUSES = %w[completed no_answer failed].freeze
|
||||
|
||||
enum :provider, { twilio: 0, whatsapp: 1 }
|
||||
enum :direction, { incoming: 0, outgoing: 1 }
|
||||
|
||||
belongs_to :account
|
||||
belongs_to :inbox
|
||||
belongs_to :conversation
|
||||
belongs_to :contact
|
||||
belongs_to :message, optional: true
|
||||
belongs_to :accepted_by_agent, class_name: 'User', optional: true
|
||||
|
||||
has_one_attached :recording
|
||||
|
||||
validates :provider_call_id, presence: true
|
||||
validates :provider, presence: true
|
||||
validates :direction, presence: true
|
||||
validates :status, presence: true, inclusion: { in: STATUSES }
|
||||
|
||||
scope :active, -> { where.not(status: TERMINAL_STATUSES) }
|
||||
end
|
||||
@@ -17,6 +17,7 @@ module Enterprise::Concerns::Account
|
||||
has_many :copilot_threads, dependent: :destroy_async
|
||||
has_many :companies, dependent: :destroy_async
|
||||
has_many :voice_channels, dependent: :destroy_async, class_name: '::Channel::Voice'
|
||||
has_many :calls, dependent: :destroy_async
|
||||
|
||||
has_one :saml_settings, dependent: :destroy_async, class_name: 'AccountSamlSettings'
|
||||
end
|
||||
|
||||
@@ -5,6 +5,7 @@ module Enterprise::Concerns::Conversation
|
||||
belongs_to :sla_policy, optional: true
|
||||
has_one :applied_sla, dependent: :destroy_async
|
||||
has_many :sla_events, dependent: :destroy_async
|
||||
has_many :calls, dependent: :destroy_async
|
||||
has_many :captain_responses, class_name: 'Captain::AssistantResponse', dependent: :nullify, as: :documentable
|
||||
before_validation :validate_sla_policy, if: -> { sla_policy_id_changed? }
|
||||
around_save :ensure_applied_sla_is_created, if: -> { sla_policy_id_changed? }
|
||||
|
||||
@@ -7,5 +7,6 @@ module Enterprise::Concerns::Inbox
|
||||
through: :captain_inbox,
|
||||
class_name: 'Captain::Assistant'
|
||||
has_many :inbox_capacity_limits, dependent: :destroy
|
||||
has_many :calls, dependent: :destroy_async
|
||||
end
|
||||
end
|
||||
|
||||
7
enterprise/app/models/enterprise/concerns/message.rb
Normal file
7
enterprise/app/models/enterprise/concerns/message.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
module Enterprise::Concerns::Message
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
has_one :call, dependent: :nullify
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user