Files
leadchat/enterprise/app/services/voice/call_message_builder.rb
Sojan Jose 48627da0f9 feat: outbound voice call essentials (#12782)
- Enables outbound voice calls in voice channel . We are only caring
about wiring the logic to trigger outgoing calls to the call button
introduced in previous PRs. We will connect it to call component in
subsequent PRs

ref: #11602 

## Screens

<img width="2304" height="1202" alt="image"
src="https://github.com/user-attachments/assets/b91543a8-8d4e-4229-bd80-9727b42c7b0f"
/>

<img width="2304" height="1200" alt="image"
src="https://github.com/user-attachments/assets/1a1dad2a-8cb2-4aa2-9702-c062416556a7"
/>

---------

Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
Co-authored-by: iamsivin <iamsivin@gmail.com>
Co-authored-by: Vishnu Narayanan <vishnu@chatwoot.com>
2025-11-24 17:47:00 -08:00

91 lines
2.1 KiB
Ruby

class Voice::CallMessageBuilder
def self.perform!(conversation:, direction:, payload:, user: nil, timestamps: {})
new(
conversation: conversation,
direction: direction,
payload: payload,
user: user,
timestamps: timestamps
).perform!
end
def initialize(conversation:, direction:, payload:, user:, timestamps:)
@conversation = conversation
@direction = direction
@payload = payload
@user = user
@timestamps = timestamps
end
def perform!
validate_sender!
message = latest_message
message ? update_message!(message) : create_message!
end
private
attr_reader :conversation, :direction, :payload, :user, :timestamps
def latest_message
conversation.messages.voice_calls.order(created_at: :desc).first
end
def update_message!(message)
message.update!(
message_type: message_type,
content_attributes: { 'data' => base_payload },
sender: sender
)
end
def create_message!
params = {
content: 'Voice Call',
message_type: message_type,
content_type: 'voice_call',
content_attributes: { 'data' => base_payload }
}
Messages::MessageBuilder.new(sender, conversation, params).perform
end
def base_payload
@base_payload ||= begin
data = payload.slice(
:call_sid,
:status,
:call_direction,
:conference_sid,
:from_number,
:to_number
).stringify_keys
data['call_direction'] = direction
data['meta'] = {
'created_at' => timestamps[:created_at] || current_timestamp,
'ringing_at' => timestamps[:ringing_at] || current_timestamp
}.compact
data
end
end
def message_type
direction == 'outbound' ? 'outgoing' : 'incoming'
end
def sender
return user if direction == 'outbound'
conversation.contact
end
def validate_sender!
return unless direction == 'outbound'
raise ArgumentError, 'Agent sender required for outbound calls' unless user
end
def current_timestamp
@current_timestamp ||= Time.zone.now.to_i
end
end