release: v2.8.21
This commit is contained in:
parent
9b662c3f1a
commit
4058451565
@ -732,7 +732,8 @@ async def mission_telefoni_ringing(event: MissionCallEvent, request: Request, to
|
|||||||
|
|
||||||
timestamp = event.timestamp or datetime.utcnow()
|
timestamp = event.timestamp or datetime.utcnow()
|
||||||
context = MissionService.resolve_contact_context(event.caller_number)
|
context = MissionService.resolve_contact_context(event.caller_number)
|
||||||
queue_name = _display_destination(event)
|
queue_name = (event.queue_name or "Ukendt kø").strip()
|
||||||
|
recipient_name = _display_destination(event)
|
||||||
|
|
||||||
execute_query(
|
execute_query(
|
||||||
"""
|
"""
|
||||||
@ -753,7 +754,13 @@ async def mission_telefoni_ringing(event: MissionCallEvent, request: Request, to
|
|||||||
answered_at = NULL,
|
answered_at = NULL,
|
||||||
started_at = LEAST(mission_call_state.started_at, EXCLUDED.started_at),
|
started_at = LEAST(mission_call_state.started_at, EXCLUDED.started_at),
|
||||||
updated_at = NOW(),
|
updated_at = NOW(),
|
||||||
last_payload = EXCLUDED.last_payload
|
last_payload = jsonb_set(
|
||||||
|
EXCLUDED.last_payload,
|
||||||
|
'{ringing_phones}',
|
||||||
|
COALESCE(mission_call_state.last_payload->'ringing_phones', '[]'::jsonb)
|
||||||
|
|| COALESCE(EXCLUDED.last_payload->'ringing_phones', '[]'::jsonb),
|
||||||
|
true
|
||||||
|
)
|
||||||
""",
|
""",
|
||||||
(
|
(
|
||||||
event.call_id,
|
event.call_id,
|
||||||
@ -763,7 +770,7 @@ async def mission_telefoni_ringing(event: MissionCallEvent, request: Request, to
|
|||||||
context.get("company_name"),
|
context.get("company_name"),
|
||||||
context.get("customer_tag"),
|
context.get("customer_tag"),
|
||||||
timestamp,
|
timestamp,
|
||||||
json.dumps(event.model_dump(mode="json")),
|
json.dumps({**event.model_dump(mode="json"), "ringing_phones": [recipient_name]}),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -786,6 +793,7 @@ async def mission_telefoni_ringing(event: MissionCallEvent, request: Request, to
|
|||||||
"queue_name": queue_name,
|
"queue_name": queue_name,
|
||||||
"caller_number": event.caller_number,
|
"caller_number": event.caller_number,
|
||||||
"recipient_extension": event.recipient_extension,
|
"recipient_extension": event.recipient_extension,
|
||||||
|
"ringing_phones": [recipient_name],
|
||||||
**context,
|
**context,
|
||||||
"timestamp": timestamp,
|
"timestamp": timestamp,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,12 +26,10 @@ class MissionService:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_ring_timeout_seconds() -> int:
|
def get_ring_timeout_seconds() -> int:
|
||||||
raw = MissionService.get_setting_value("mission_call_ring_timeout_seconds", "180") or "180"
|
# A Yealink "Incoming call" event has no matching event when the
|
||||||
try:
|
# caller abandons the call. Keep it briefly, then remove it from the
|
||||||
value = int(raw)
|
# live boards so stale ringing phones cannot remain visible.
|
||||||
except (TypeError, ValueError):
|
return 30
|
||||||
value = 180
|
|
||||||
return max(30, min(value, 3600))
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def expire_stale_ringing_calls() -> None:
|
def expire_stale_ringing_calls() -> None:
|
||||||
@ -216,7 +214,8 @@ class MissionService:
|
|||||||
MissionService.expire_stale_ringing_calls()
|
MissionService.expire_stale_ringing_calls()
|
||||||
rows = execute_query(
|
rows = execute_query(
|
||||||
"""
|
"""
|
||||||
SELECT call_id, queue_name, caller_number, contact_name, company_name, customer_tag, state, started_at, answered_at, ended_at, updated_at
|
SELECT call_id, queue_name, caller_number, contact_name, company_name, customer_tag, state, started_at, answered_at, ended_at, updated_at,
|
||||||
|
COALESCE(last_payload->'ringing_phones', jsonb_build_array(queue_name)) AS ringing_phones
|
||||||
FROM mission_call_state
|
FROM mission_call_state
|
||||||
WHERE state = 'ringing'
|
WHERE state = 'ringing'
|
||||||
ORDER BY started_at DESC
|
ORDER BY started_at DESC
|
||||||
|
|||||||
@ -2956,8 +2956,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const call = state.activeCalls[0];
|
const call = state.activeCalls[0];
|
||||||
|
const phones = [...new Set((Array.isArray(call.ringing_phones) ? call.ringing_phones : [call.queue_name]).filter(Boolean))];
|
||||||
title.textContent = `${call.queue_name || 'Ukendt kø'} - ${call.caller_number || 'Ukendt nummer'}`;
|
title.textContent = `${call.queue_name || 'Ukendt kø'} - ${call.caller_number || 'Ukendt nummer'}`;
|
||||||
const parts = [];
|
const parts = [];
|
||||||
|
if (phones.length) parts.push(`Ringer hos: ${phones.join(' · ')}`);
|
||||||
if (call.contact_name) parts.push(call.contact_name);
|
if (call.contact_name) parts.push(call.contact_name);
|
||||||
if (call.company_name) parts.push(call.company_name);
|
if (call.company_name) parts.push(call.company_name);
|
||||||
parts.push(`Start: ${formatDate(call.started_at)}`);
|
parts.push(`Start: ${formatDate(call.started_at)}`);
|
||||||
@ -2973,16 +2975,20 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
list.innerHTML = state.activeCalls.map((call) => `
|
list.innerHTML = state.activeCalls.map((call) => {
|
||||||
|
const phones = [...new Set((Array.isArray(call.ringing_phones) ? call.ringing_phones : [call.queue_name]).filter(Boolean))];
|
||||||
|
return `
|
||||||
<div class="mc-feed-item">
|
<div class="mc-feed-item">
|
||||||
<div class="mc-feed-title">${escapeHtml(call.queue_name || 'Ukendt kø')} - ${escapeHtml(call.caller_number || '-')}</div>
|
<div class="mc-feed-title">${escapeHtml(call.queue_name || 'Ukendt kø')} - ${escapeHtml(call.caller_number || '-')}</div>
|
||||||
<div class="mc-feed-meta">
|
<div class="mc-feed-meta">
|
||||||
|
${phones.length ? `Ringer hos: ${escapeHtml(phones.join(' · '))} • ` : ''}
|
||||||
${escapeHtml(call.contact_name || 'Ukendt kontakt')}
|
${escapeHtml(call.contact_name || 'Ukendt kontakt')}
|
||||||
${call.company_name ? ` • ${escapeHtml(call.company_name)}` : ''}
|
${call.company_name ? ` • ${escapeHtml(call.company_name)}` : ''}
|
||||||
${call.started_at ? ` • ${escapeHtml(formatDate(call.started_at))}` : ''}
|
${call.started_at ? ` • ${escapeHtml(formatDate(call.started_at))}` : ''}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`).join('');
|
`;
|
||||||
|
}).join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderCallHistory() {
|
function renderCallHistory() {
|
||||||
|
|||||||
@ -338,13 +338,16 @@ function renderLiveCalls(calls) {
|
|||||||
|
|
||||||
list.innerHTML = calls.map((call) => {
|
list.innerHTML = calls.map((call) => {
|
||||||
const caller = escapeHtml(normalizeDisplayNumber(call.caller_number) || call.caller_number || 'Ukendt nummer');
|
const caller = escapeHtml(normalizeDisplayNumber(call.caller_number) || call.caller_number || 'Ukendt nummer');
|
||||||
const recipient = escapeHtml(call.queue_name || 'Ukendt telefon');
|
const phones = [...new Set((Array.isArray(call.ringing_phones) ? call.ringing_phones : [call.queue_name]).filter(Boolean))];
|
||||||
|
const recipient = escapeHtml(phones.join(' · ') || 'Ukendt telefon');
|
||||||
|
const queue = escapeHtml(call.queue_name || 'Ukendt kø');
|
||||||
const contactParts = [call.contact_name, call.company_name].filter(Boolean).map(escapeHtml);
|
const contactParts = [call.contact_name, call.company_name].filter(Boolean).map(escapeHtml);
|
||||||
const contact = contactParts.length ? ` <span class="text-muted">· ${contactParts.join(' · ')}</span>` : '';
|
const contact = contactParts.length ? ` <span class="text-muted">· ${contactParts.join(' · ')}</span>` : '';
|
||||||
return `<div class="d-flex align-items-center flex-wrap gap-2 py-1">
|
return `<div class="d-flex align-items-center flex-wrap gap-2 py-1">
|
||||||
<span class="badge text-bg-danger">RINGER</span>
|
<span class="badge text-bg-danger">RINGER</span>
|
||||||
<strong>${recipient}</strong>
|
<strong>${recipient}</strong>
|
||||||
<span>fra ${caller}</span>${contact}
|
<span>fra ${caller}</span>
|
||||||
|
<span class="badge text-bg-light border">${queue}</span>${contact}
|
||||||
</div>`;
|
</div>`;
|
||||||
}).join('');
|
}).join('');
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user