581 routing.CentreID = destination 582 } 583 if groupID := stringField(decision, "destination_group_id"); groupID != "" { 584 routing.CommercialGroupID = groupID 585 } 586 routing.MatchSource = appendMatchReason(routing.MatchSource, "smart_routing_decision") 587 return routing, nil 588} 589 590func routingDeliveryConfirmed(payload ringoverPayload, commercialID string) bool { 591 // Ringover can mark the root IVR leg as answered even though no agent ever 592 // picked up. A routed delivery only exists when the provider event can be 593 // tied to the commercial that actually answered. 594 if strings.TrimSpace(commercialID) == "" { 595 return false 596 } 597 event := strings.ToLower(strings.TrimSpace(payload.Event)) 598 if event == "answered" { 599 return true 600 } 601 if !isTerminalCallEvent(event) { 602 return false 603 } 604 if firstTime(payload.Data, "answered_at", "answer_time", "answered_date_time_atom") != "" { 605 return true 606 } 607 talk := firstNumber(payload.Data, "talk_duration", "talk_duration_seconds", "conversation_duration") 608 return talk != nil 609} 610 611func isUnattributedIVRAnswer(payload ringoverPayload, commercialID string) bool { 612 if strings.TrimSpace(commercialID) != "" || !truthy(payload.Data["is_ivr"]) { 613 return false 614 } 615 event := strings.ToLower(strings.TrimSpace(payload.Event)) 616 if event == "answered" { 617 return true 618 } 619 return isTerminalCallEvent(event) && (firstTime(payload.Data, "answered_at", "answer_time", "answered_date_time_atom") != "" || 620 firstNumber(payload.Data, "talk_duration", "talk_duration_seconds", "conversation_duration") != nil) 621} 622 623func confirmRoutingDecisionDelivery(ctx *Context, callID, centreID, commercialID, now string) error { 624 callID = strings.TrimSpace(callID) 625 centreID = strings.TrimSpace(centreID) 626 commercialID = strings.TrimSpace(commercialID) 627 if callID == "" || centreID == "" || commercialID == "" { 628 return nil 629 } 630 rows, err := search(ctx, "call_routing_decisions", []any{ 631 map[string]any{"col": "provider_call_id", "op": "eq", "value": callID}, 632 map[string]any{"col": "status", "op": "eq", "value": "routed"}, 633 }, 5) 634 if err != nil { 635 return err 636 } 637 for _, decision := range rows.Rows { 638 if truthyField(decision, "repeated") { 639 continue 640 } 641 id := rowIDInt(decision)