chore: preserve terminal statuses; skip early in-progress
This commit is contained in:
@@ -9,6 +9,7 @@ class Voice::CallStatus::Manager
|
||||
|
||||
current_status = conversation.additional_attributes&.dig('call_status')
|
||||
return if current_status == status
|
||||
return if preserve_existing_terminal_status?(current_status, status)
|
||||
|
||||
apply_status(status, duration: duration, timestamp: timestamp)
|
||||
update_message(status)
|
||||
@@ -82,4 +83,9 @@ class Voice::CallStatus::Manager
|
||||
data['data']['meta'].delete('duration')
|
||||
end
|
||||
end
|
||||
|
||||
def preserve_existing_terminal_status?(current_status, next_status)
|
||||
TERMINAL_STATUSES.include?(current_status) &&
|
||||
TERMINAL_STATUSES.include?(next_status)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -21,6 +21,7 @@ class Voice::StatusUpdateService
|
||||
|
||||
conversation = account.conversations.find_by(identifier: call_sid)
|
||||
return unless conversation
|
||||
return if ignore_premature_in_progress?(conversation, normalized_status)
|
||||
|
||||
Voice::CallStatus::Manager.new(
|
||||
conversation: conversation,
|
||||
@@ -57,4 +58,10 @@ class Voice::StatusUpdateService
|
||||
rescue ArgumentError
|
||||
nil
|
||||
end
|
||||
|
||||
def ignore_premature_in_progress?(conversation, normalized_status)
|
||||
normalized_status == 'in-progress' &&
|
||||
conversation.additional_attributes&.dig('call_direction') == 'inbound' &&
|
||||
!conversation.additional_attributes&.dig('agent_joined')
|
||||
end
|
||||
end
|
||||
|
||||
@@ -75,6 +75,43 @@ RSpec.describe Voice::StatusUpdateService do
|
||||
expect(message.content_attributes.dig('data', 'status')).to eq('no-answer')
|
||||
end
|
||||
|
||||
it 'does not overwrite no-answer with a later completed callback' do
|
||||
conversation.update!(additional_attributes: { 'call_direction' => 'inbound', 'call_status' => 'no-answer' })
|
||||
message.update!(content_attributes: { data: { call_sid: call_sid, status: 'no-answer' } })
|
||||
|
||||
described_class.new(
|
||||
account: account,
|
||||
call_sid: call_sid,
|
||||
call_status: 'completed',
|
||||
payload: { 'CallDuration' => '4' }
|
||||
).perform
|
||||
|
||||
conversation.reload
|
||||
message.reload
|
||||
|
||||
expect(conversation.additional_attributes['call_status']).to eq('no-answer')
|
||||
expect(message.content_attributes.dig('data', 'status')).to eq('no-answer')
|
||||
expect(message.content_attributes.dig('data', 'meta', 'duration')).to be_nil
|
||||
end
|
||||
|
||||
it 'ignores inbound in-progress callbacks before any agent joins' do
|
||||
conversation
|
||||
message
|
||||
|
||||
described_class.new(
|
||||
account: account,
|
||||
call_sid: call_sid,
|
||||
call_status: 'in-progress'
|
||||
).perform
|
||||
|
||||
conversation.reload
|
||||
message.reload
|
||||
|
||||
expect(conversation.additional_attributes['call_status']).to eq('ringing')
|
||||
expect(conversation.additional_attributes['call_started_at']).to be_nil
|
||||
expect(message.content_attributes.dig('data', 'status')).to eq('ringing')
|
||||
end
|
||||
|
||||
it 'no-ops when conversation not found' do
|
||||
expect do
|
||||
described_class.new(account: account, call_sid: 'UNKNOWN', call_status: 'busy').perform
|
||||
|
||||
Reference in New Issue
Block a user