@@ -528,6 +528,7 @@ pub struct IvrNodeEntered {
528528 pub app_id : String , pub entry_time : String ,
529529 pub caller_name : Option < String > , pub callee_name : Option < String > ,
530530 pub routing_target : Option < String > , pub previous_node_id : Option < String > ,
531+ pub extra : Option < serde_json:: Value > ,
531532}
532533rwi_event ! ( IvrNodeEntered , "ivr_node_entered" ) ;
533534
@@ -537,6 +538,7 @@ pub struct IvrNodeExited {
537538 pub result_value : Option < String > , pub duration_ms : u32 , pub exit_time : String ,
538539 pub next_node_id : Option < String > , pub hangup_reason : Option < String > ,
539540 pub call_result : Option < String > ,
541+ pub extra : Option < serde_json:: Value > ,
540542}
541543rwi_event ! ( IvrNodeExited , "ivr_node_exited" ) ;
542544
@@ -546,6 +548,7 @@ pub struct IvrFlowCompleted {
546548 pub total_nodes_traversed : u32 , pub total_duration_ms : u32 ,
547549 pub final_result : String , pub completion_time : String ,
548550 pub final_routing_target : Option < String > ,
551+ pub extra : Option < serde_json:: Value > ,
549552}
550553rwi_event ! ( IvrFlowCompleted , "ivr_flow_completed" ) ;
551554
@@ -564,3 +567,60 @@ pub struct IvrStepTrace {
564567 pub sip_headers : Option < std:: collections:: HashMap < String , String > > ,
565568}
566569rwi_event ! ( IvrStepTrace , "ivr_step_trace" ) ;
570+
571+ #[ cfg( test) ]
572+ mod tests {
573+ use super :: * ;
574+
575+ #[ test]
576+ fn ivr_events_serialize_extra_field ( ) {
577+ let entered = to_flat_payload (
578+ & IvrNodeEntered {
579+ call_id : "call-1" . into ( ) ,
580+ node_id : "root" . into ( ) ,
581+ node_name : "Root" . into ( ) ,
582+ node_type : "menu" . into ( ) ,
583+ app_id : "ivr-main" . into ( ) ,
584+ entry_time : "2026-01-01T00:00:00Z" . into ( ) ,
585+ caller_name : None ,
586+ callee_name : None ,
587+ routing_target : None ,
588+ previous_node_id : None ,
589+ extra : None ,
590+ } ,
591+ None ,
592+ ) ;
593+ let exited = to_flat_payload (
594+ & IvrNodeExited {
595+ call_id : "call-1" . into ( ) ,
596+ node_id : "root" . into ( ) ,
597+ node_name : "Root" . into ( ) ,
598+ result_value : None ,
599+ duration_ms : 10 ,
600+ exit_time : "2026-01-01T00:00:01Z" . into ( ) ,
601+ next_node_id : None ,
602+ hangup_reason : None ,
603+ call_result : None ,
604+ extra : None ,
605+ } ,
606+ None ,
607+ ) ;
608+ let completed = to_flat_payload (
609+ & IvrFlowCompleted {
610+ call_id : "call-1" . into ( ) ,
611+ app_id : "ivr-main" . into ( ) ,
612+ total_nodes_traversed : 1 ,
613+ total_duration_ms : 10 ,
614+ final_result : "completed" . into ( ) ,
615+ completion_time : "2026-01-01T00:00:02Z" . into ( ) ,
616+ final_routing_target : None ,
617+ extra : None ,
618+ } ,
619+ None ,
620+ ) ;
621+
622+ assert ! ( entered. get( "extra" ) . is_some( ) ) ;
623+ assert ! ( exited. get( "extra" ) . is_some( ) ) ;
624+ assert ! ( completed. get( "extra" ) . is_some( ) ) ;
625+ }
626+ }
0 commit comments