From 3f7575ee4267c7d4006aa93080d316522aefcc8a Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Mon, 21 Jun 2021 18:05:16 +0200 Subject: [PATCH] Improve CallRingGroup --- .../Activities/CallRingGroup.cs | 132 ++++++++++-------- 1 file changed, 75 insertions(+), 57 deletions(-) diff --git a/src/activities/Elsa.Activities.Telnyx/Activities/CallRingGroup.cs b/src/activities/Elsa.Activities.Telnyx/Activities/CallRingGroup.cs index 2cf383292..ee7e4d5b5 100644 --- a/src/activities/Elsa.Activities.Telnyx/Activities/CallRingGroup.cs +++ b/src/activities/Elsa.Activities.Telnyx/Activities/CallRingGroup.cs @@ -8,7 +8,6 @@ using Elsa.Activities.Telnyx.Client.Models; using Elsa.Activities.Telnyx.Client.Services; using Elsa.Activities.Telnyx.Models; using Elsa.Activities.Telnyx.Services; -using Elsa.Activities.Telnyx.Webhooks.Models; using Elsa.Activities.Telnyx.Webhooks.Payloads.Call; using Elsa.Activities.Temporal; using Elsa.Attributes; @@ -151,45 +150,57 @@ namespace Elsa.Activities.Telnyx.Activities set => SetState(value); } + private bool CallerHangup + { + get => GetState(); + set => SetState(value); + } + public override void Build(ICompositeActivityBuilder builder) { // Root. builder - .If(() => IntroMusic != null, @if => + .Then(fork => fork.WithBranches("Call", "Hangup"), fork => { - @if.When(OutcomeNames.True) - .Then(playAudio => playAudio.WithAudioUrl(() => IntroMusic), playAudio => - { - playAudio.When(TelnyxOutcomeNames.CallPlaybackEnded).ThenNamed("If1"); - }); - - @if.When(OutcomeNames.False).ThenNamed("If1"); - }) - .Add(@if => @if.WithCondition(() => MusicOnHold != null), @if => - { - @if - .When(OutcomeNames.True) - .Then(playAudio => playAudio.WithAudioUrl(() => MusicOnHold).WithLoop("infinity")) - .ThenNamed("MainFork"); - - @if - .When(OutcomeNames.False) - .ThenNamed("MainFork"); - }).WithName("If1") - .Add(fork => fork.WithBranches("Ring", "Queue Timeout"), fork => - { - fork.When("Ring") - .While(true, iterate => iterate - .Switch(cases => - { - cases.Add(RingGroupStrategy.PrioritizedHunt.ToString(), () => Strategy == RingGroupStrategy.PrioritizedHunt, BuildPrioritizedHuntFlow); - cases.Add(RingGroupStrategy.RingAll.ToString(), () => Strategy == RingGroupStrategy.RingAll, BuildRingAllFlow); - })) + fork.When("Hangup") + .ThenTypeNamed(CallHangupPayload.ActivityTypeName) + .Then(() => CallerHangup = true) .ThenNamed("ExitWithNoResponse"); - fork.When("Queue Timeout") - .IfFalse(() => IsNullOrZero(MaxQueueWaitTime), ifFalse => ifFalse.StartIn(() => MaxQueueWaitTime!.Value).ThenNamed("ExitWithNoResponse")); - }).WithName("MainFork"); + fork.When("Call") + .If(() => IntroMusic != null, @if => + { + @if.When(OutcomeNames.True) + .Then(playAudio => playAudio.WithAudioUrl(() => IntroMusic), playAudio => { playAudio.When(TelnyxOutcomeNames.CallPlaybackEnded).ThenNamed("If1"); }); + + @if.When(OutcomeNames.False).ThenNamed("If1"); + }) + .Add(@if => @if.WithCondition(() => MusicOnHold != null), @if => + { + @if + .When(OutcomeNames.True) + .Then(playAudio => playAudio.WithAudioUrl(() => MusicOnHold).WithLoop("infinity")) + .ThenNamed("InnerFork"); + + @if + .When(OutcomeNames.False) + .ThenNamed("InnerFork"); + }).WithName("If1") + .Add(fork => fork.WithBranches("Ring", "Queue Timeout"), fork => + { + fork.When("Ring") + .While(() => !CallerHangup, iterate => iterate + .Switch(cases => + { + cases.Add(RingGroupStrategy.PrioritizedHunt.ToString(), () => Strategy == RingGroupStrategy.PrioritizedHunt, BuildPrioritizedHuntFlow); + cases.Add(RingGroupStrategy.RingAll.ToString(), () => Strategy == RingGroupStrategy.RingAll, BuildRingAllFlow); + })) + .ThenNamed("ExitWithNoResponse"); + + fork.When("Queue Timeout") + .IfFalse(() => IsNullOrZero(MaxQueueWaitTime), ifFalse => ifFalse.StartIn(() => MaxQueueWaitTime!.Value).ThenNamed("ExitWithNoResponse")); + }).WithName("InnerFork"); + }); // No Response exit node. builder.Add(@if => @if.WithCondition(() => MusicOnHold != null), @if => @@ -224,31 +235,38 @@ namespace Elsa.Activities.Telnyx.Activities private void BuildPrioritizedHuntFlow(IOutcomeBuilder builder) => builder .ForEach(() => Extensions, iterate => iterate - .Then(dial => dial - .WithConnectionId(() => CallControlAppId) - .WithTo(ResolveExtensionAsync) - .WithTimeoutSecs(() => (int) RingTime.TotalSeconds) - .WithFrom(() => From) - .WithFromDisplayName(() => FromDisplayName), - dial => - { - dial - .When(TelnyxOutcomeNames.Answered) - .If(() => MusicOnHold != null, @if => - { - @if.When(OutcomeNames.True) - .Then(stopAudioPlayback => stopAudioPlayback - .When(TelnyxOutcomeNames.CallPlaybackEnded) - .ThenNamed("BridgeCalls1")); + .If(() => CallerHangup, @if => + { + @if.When(OutcomeNames.True) + .Break(); - @if.When(OutcomeNames.False) - .ThenNamed("BridgeCalls1"); - }) - .Add(branch: bridgeCalls => - bridgeCalls.When(TelnyxOutcomeNames.Bridged) - .Finish(activity => activity.WithOutcome(TelnyxOutcomeNames.Connected).WithOutput(context => context.GetInput()))).WithName("BridgeCalls1"); - } - ) + @if.When(OutcomeNames.False) + .Then(dial => dial + .WithConnectionId(() => CallControlAppId) + .WithTo(ResolveExtensionAsync) + .WithTimeoutSecs(() => (int) RingTime.TotalSeconds) + .WithFrom(() => From) + .WithFromDisplayName(() => FromDisplayName), + dial => + { + dial + .When(TelnyxOutcomeNames.Answered) + .If(() => MusicOnHold != null, @if => + { + @if.When(OutcomeNames.True) + .Then(stopAudioPlayback => stopAudioPlayback + .When(TelnyxOutcomeNames.CallPlaybackEnded) + .ThenNamed("BridgeCalls1")); + + @if.When(OutcomeNames.False) + .ThenNamed("BridgeCalls1"); + }) + .Add(branch: bridgeCalls => + bridgeCalls.When(TelnyxOutcomeNames.Bridged) + .Finish(activity => activity.WithOutcome(TelnyxOutcomeNames.Connected).WithOutput(context => context.GetInput()))).WithName("BridgeCalls1"); + } + ); + }) ) // If we don't have a queue wait time, then break out of outer loop. .IfTrue(() => IsNullOrZero(MaxQueueWaitTime), @if => @if.Break());