fix(voice): preserve duration when agents hang up active WhatsApp calls
finalize_call wasn't writing duration_seconds or end_reason, and the Meta terminate webhook that would have filled them in is suppressed by the terminal-state idempotency guard in IncomingCallService#handle_terminate. The result was completed-call bubbles with no duration. Compute the duration from started_at at agent-hangup time and stamp end_reason locally instead of waiting for a webhook that won't apply. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
2e6b415826
commit
f0119b3f2b
@@ -30,8 +30,16 @@ class Whatsapp::CallService
|
||||
next if call.terminal?
|
||||
|
||||
invoke_provider!(:terminate_call)
|
||||
# Agent hangs up before contact picks up → no_answer; mirrors the webhook terminate path.
|
||||
finalize_call(call.in_progress? ? 'completed' : 'no_answer')
|
||||
# Compute duration from started_at locally — the webhook arrives after the
|
||||
# call is already terminal and the idempotency guard there bails before it
|
||||
# can fill these fields, so we have to record them here.
|
||||
if call.in_progress?
|
||||
duration = call.started_at ? (Time.current - call.started_at).to_i : nil
|
||||
finalize_call('completed', duration_seconds: duration, end_reason: 'agent_hangup')
|
||||
else
|
||||
# Agent hangs up before contact picks up → no_answer; mirrors the webhook terminate path.
|
||||
finalize_call('no_answer', end_reason: 'agent_hangup')
|
||||
end
|
||||
end
|
||||
call
|
||||
end
|
||||
@@ -73,16 +81,16 @@ class Whatsapp::CallService
|
||||
raise Voice::CallErrors::CallFailed, "Meta #{method} failed"
|
||||
end
|
||||
|
||||
def finalize_call(status)
|
||||
def finalize_call(status, **attrs)
|
||||
meta = (call.meta || {}).merge('ended_at' => Time.zone.now.to_i)
|
||||
call.update!(status: status, meta: meta)
|
||||
update_message_status(status)
|
||||
call.update!(status: status, meta: meta, **attrs)
|
||||
update_message_status(status, duration_seconds: attrs[:duration_seconds])
|
||||
update_conversation_call_status(call.display_status)
|
||||
broadcast(:ended, status: call.display_status)
|
||||
end
|
||||
|
||||
def update_message_status(status)
|
||||
Voice::CallMessageBuilder.new(call).update_status!(status: status, agent: agent)
|
||||
def update_message_status(status, duration_seconds: nil)
|
||||
Voice::CallMessageBuilder.new(call).update_status!(status: status, agent: agent, duration_seconds: duration_seconds)
|
||||
end
|
||||
|
||||
def update_conversation_call_status(status)
|
||||
|
||||
Reference in New Issue
Block a user