- Joined
- Jun 26, 2024
- Messages
- 42
- Reaction score
- 17
The CFDesigner currently doesn't support the latest v20 stuff like departments and all. It would need to be a manual script.Can you provide me of any sort of example script that I can build upon?
Would it be easier to do this through the Call Flow Designer, and just import the script into the 3CX client after it is generated?
This is exactly what I'm looking for as well. The default holiday script and timebasedcallscript don't cover this very basic scenario. Has anybody put together a working script? I guess it has to be a combination of the 2 earlier mentioned scripts?Hello everyone,
I am trying to set up routing in V20 to fit this general dialplan:
View attachment 45263
There are sometimes up to 50 users in the 3cx system, and it would be nice if this can be set up without using CFD if possible.
Any help is welcome
Thanks
#nullable disable
using CallFlow;
using System;
using System.Threading;
using System.Linq;
using System.Threading.Tasks;
using TCX.Configuration;
using TCX.PBXAPI;
using System.Collections.Generic;
namespace dummy
{
//this handler plays holiday prompt as specified for destination
public class PlayDestinationHolidayPromptBeforeRouting : ScriptBase<PlayDestinationHolidayPromptBeforeRouting>
{
//reference implementation of trunk routing.
DestinationStruct FindDefaultDestination(ExternalLine trunk, string callerID, string DID)
{
DestinationStruct retval = new();
string[] range;
foreach (var a in trunk.RoutingRules)
{
bool match = (a.Conditions.Condition.Type == RuleConditionType.BasedOnDID &&
(
a.Data == DID
|| (a.Data.StartsWith('*') && DID.EndsWith(a.Data[1..]))
))
||
(
a.Conditions.Condition.Type == RuleConditionType.BasedOnCallerID &&
a.Data.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
.Any
(x =>
x == "*"
|| x == callerID
|| x.StartsWith('*') && callerID.EndsWith(x[1..])
|| x.EndsWith('*') && callerID.StartsWith(x[..^1])
|| x.StartsWith('*') && x.EndsWith('*') && callerID.Contains(x[1..^1])
|| ((range = x.Split("-", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)).Length == 2 ?
(range[0].Length == callerID.Length && range[1].Length == callerID.Length) && (range[0].CompareTo(callerID) <= 0 && range[1].CompareTo(callerID) >= 0) : false)
)
)
||
(a.Conditions.Condition.Type == RuleConditionType.ForwardAll);
if (match)
{
retval.CopyFrom(a.ForwardDestinations.OfficeHoursDestination);
break;
}
}
return retval;
}
public override async Task<bool> StartAsync()
{
if(MyCall.Caller.DN is ExternalLine externalLine && MyCall.IsInbound) //only from trunk
{
//get the inbound target
var defaultDestination = FindDefaultDestination(externalLine, MyCall.Caller.CallerID, MyCall.Caller.CalledNumber).Internal;
//if the destination is Internal
if (defaultDestination != null)
{
var timeBasedroute = defaultDestination.GetTimeBasedRoutingInfo();
//if destination is currently "on holiday" and holiday prompt is defined, we play it
//if (timeBasedroute.reason == CallControlAPI.DivertReason.Holiday && !string.IsNullOrWhiteSpace(timeBasedroute.holiday?.HolidayPrompt))
// MODIFIED - REQUIRES UPLOAD OF "VACATION.wav"
if (timeBasedroute.reason == CallControlAPI.DivertReason.Holiday)
{
await MyCall.AssureMedia()
.ContinueWith(x => MyCall.PlayPrompt(null, new[] {"VACATION.wav"}, PlayPromptOptions.Blocked))
.Unwrap();
return true; // <<<=== STOP default routing procedure !!
}
var currentTime = externalLine.Now(out var utc, out var timezone, out var groupmode);
var g = ps.GetAll<TCX.Configuration.Group>().FirstOrDefault(grp => grp.Number == defaultDestination.Number);
// Intercept calls during the specified schedule
if (CommonRoutingExtensions.IsOutOfOffice(g,currentTime))
{
await MyCall.AssureMedia()
.ContinueWith(x => MyCall.PlayPrompt(null, new[] {"OFFICE_CLOSED.wav"}, PlayPromptOptions.Blocked))
.Unwrap();
return true; // <<<=== STOP default routing procedure !!
}
}
}
return false;//we always return false to continue default trunk routing procedure.
}
}
}
if (timeBasedroute.reason == CallControlAPI.DivertReason.Holiday)
if (timeBasedroute.reason == CallControlAPI.DivertReason.Holiday || timeBasedroute.reason == CallControlAPI.DivertReason.OutOfOfficeHours)
(...)
// MODIFIED - REQUIRES UPLOAD OF "VACATION.wav"
if (timeBasedroute.reason == CallControlAPI.DivertReason.Holiday)
{
await MyCall.AssureMedia()
.ContinueWith(x => MyCall.PlayPrompt(null, new[] {"VACATION.wav"}, PlayPromptOptions.Blocked))
.Unwrap();
return true; // <<<=== STOP default routing procedure !!
}
// Intercept calls during the specified schedule
if (timeBasedroute.reason == CallControlAPI.DivertReason.OutOfOfficeHours)
{
await MyCall.AssureMedia()
.ContinueWith(x => MyCall.PlayPrompt(null, new[] {"OFFICE_CLOSED.wav"}, PlayPromptOptions.Blocked))
.Unwrap();
return true; // <<<=== STOP default routing procedure !!
}
(...)
Founded in 2005, when VoIP was an emerging technology, 3CX has gone on to establish itself as a global leader in business communications.