feat(whatsapp-call): add call recording, transcription, beforeunload termination and documentation

This commit is contained in:
Tanmay Deep Sharma
2026-03-24 13:13:49 +05:30
parent d6eb945d25
commit 504a32214e
19 changed files with 1943 additions and 193 deletions
@@ -1,13 +1,28 @@
class Api::V1::Accounts::WhatsappCallsController < Api::V1::Accounts::BaseController
before_action :ensure_whatsapp_call_enabled
before_action :set_whatsapp_call, only: [:accept, :reject, :terminate]
before_action :set_whatsapp_call, only: [:show, :accept, :reject, :terminate, :upload_recording]
def show
render json: {
id: @whatsapp_call.id,
call_id: @whatsapp_call.call_id,
status: @whatsapp_call.status,
direction: @whatsapp_call.direction,
conversation_id: @whatsapp_call.conversation_id,
inbox_id: @whatsapp_call.inbox_id,
message_id: @whatsapp_call.message_id,
sdp_offer: @whatsapp_call.ringing? ? @whatsapp_call.sdp_offer : nil,
ice_servers: @whatsapp_call.ice_servers,
caller: caller_info
}
end
def accept
sdp_answer = params[:sdp_answer]
return render json: { error: 'sdp_answer is required' }, status: :unprocessable_entity if sdp_answer.blank?
wa_call = Whatsapp::CallService.new(wa_call: @whatsapp_call, agent: current_user).pre_accept_and_accept(sdp_answer)
render json: { id: wa_call.id, status: wa_call.status }
render json: { id: wa_call.id, status: wa_call.status, message_id: wa_call.message_id }
rescue Whatsapp::CallErrors::NotRinging, Whatsapp::CallErrors::AlreadyAccepted => e
render json: { error: e.message }, status: :unprocessable_entity
rescue StandardError => e
@@ -31,13 +46,26 @@ class Api::V1::Accounts::WhatsappCallsController < Api::V1::Accounts::BaseContro
render json: { error: 'Failed to terminate call' }, status: :internal_server_error
end
def upload_recording
return render json: { error: 'No recording file provided' }, status: :unprocessable_entity if params[:recording].blank?
return render json: { error: 'Call is not ended' }, status: :unprocessable_entity unless @whatsapp_call.terminal?
attach_recording_and_enqueue_transcription
render json: { id: @whatsapp_call.id, status: 'uploaded' }
rescue StandardError => e
Rails.logger.error "[WHATSAPP CALL] upload_recording failed: #{e.message}"
render json: { error: 'Failed to upload recording' }, status: :internal_server_error
end
def initiate
conversation = current_account.conversations.find(params[:conversation_id])
error = validate_whatsapp_calling(conversation)
return render json: { error: error }, status: :unprocessable_entity if error
wa_call = create_outbound_call(conversation)
render json: { status: 'calling', call_id: wa_call.call_id, id: wa_call.id }
message = Whatsapp::CallMessageBuilder.create!(conversation: conversation, wa_call: wa_call, user: current_user)
wa_call.update!(message_id: message.id)
render json: { status: 'calling', call_id: wa_call.call_id, id: wa_call.id, message_id: message.id }
rescue Whatsapp::CallErrors::NoCallPermission
handle_no_call_permission(conversation)
rescue ActiveRecord::RecordNotFound
@@ -96,4 +124,17 @@ class Api::V1::Accounts::WhatsappCallsController < Api::V1::Accounts::BaseContro
rescue ActiveRecord::RecordNotFound
render json: { error: 'Call not found' }, status: :not_found
end
def attach_recording_and_enqueue_transcription
@whatsapp_call.recording.attach(params[:recording])
Whatsapp::CallMessageBuilder.update_recording_url!(wa_call: @whatsapp_call)
Whatsapp::CallTranscriptionJob.perform_later(@whatsapp_call.id)
end
def caller_info
contact = @whatsapp_call.conversation&.contact
return {} unless contact
{ name: contact.name, phone: contact.phone_number, avatar: contact.avatar_url }
end
end