Динамическая маршрутизация входящих вызовов на основе Caller ID, DID и времени суток
Данный скрипт позволяет перенаправлять входящие вызовы на основе заданных критериев, таких как время суток, Caller ID или DID. Динамическая маршрутизация срабатывает при поступлении вызова на транк и направляет абонента на настроенное направление / сотруднику.
Настройка скрипта маршрутизации вызовов по времени
- Перейдите в Console > Integrations > Call Scripts.
- Нажмите Add from Store и выберите “Time Based Call Routing”.
- Для удобства, дайте скрипту название.
- Запустите скрипт при получении вызова на транке.
- Выберите транк, на котором будут перехватываться входящие вызовы.
- По умолчанию скрипт имеет предустановленное расписание, которое можно изменить, указав значения в переменной
schedule. Например:{ DayOfWeek.Monday, new Schedule.PeriodOfDay(TimeSpan.FromHours(17.5), TimeSpan.FromHours(24)) }. - Скрипт также принимает вызовы со всех DID/Caller ID, поскольку переменные
DIDs/Callersсодержат символ*, который можно заменить на конкретные DID и Caller ID. - Измените
801в строкеconst string DestinationDN = "801";на выбранное вами направление.
Для чего используется динамическая маршрутизация
- Маршрутизация вызовов с учетом времени: Автоматическое перенаправление вызовов на определенные направления / сотрудникам в зависимости от рабочего времени.
- Обработка вызовов от определенных абонентов: Создание уникальных правил маршрутизации для важных Caller ID или DID.
- Эффективное управление вызовами: Сокращение ручного вмешательства – автоматизация маршрутизации вызовов в нерабочее время или по определенным критериям.
Код скрипта
ВНИМАНИЕ! Код скрипта приведен только для справки. Актуальную версию можно скачать из Магазина 3CX.
Script: Intercept Inbound Calls
/*
* Time Base Call Routing - Use code with caution!
* Calls will be intercepted and redirected to the specified DestinationDN during the following times:
* Monday to Sunday: 5:30 PM to 7:00 AM
* The current destination DN is set to "801" modify destination to any system extension or extension you want.
*
* INSTRUCTIONS
* - Configure Date & Time (Line 31)
* - Change the destination DN, and modify the value of the constant DestinationDN to any destination you want to route call (Line 26).
*/
#nullable disable
using CallFlow;
using System;
using System.Threading;
using System.Threading.Tasks;
using TCX.Configuration;
using TCX.PBXAPI;
using System.Collections.Generic;
using System.Linq;
using CallFlow.CFD;
namespace interceptcall
{
public class InterceptInboundCall : ScriptBase
{
// The destination DN to which the call will be redirected
const string DestinationDN = "801";
// Define a schedule for when calls should be intercepted
static readonly Schedule schedule = new Schedule(RuleHoursType.SpecificHours)
{
{ DayOfWeek.Monday, new Schedule.PeriodOfDay(TimeSpan.FromHours(17.5), TimeSpan.FromHours(24)) },
{ DayOfWeek.Monday, new Schedule.PeriodOfDay(TimeSpan.FromHours(0), TimeSpan.FromHours(7)) },
{ DayOfWeek.Tuesday, new Schedule.PeriodOfDay(TimeSpan.FromHours(17.5), TimeSpan.FromHours(24)) },
{ DayOfWeek.Tuesday, new Schedule.PeriodOfDay(TimeSpan.FromHours(0), TimeSpan.FromHours(7)) },
{ DayOfWeek.Wednesday, new Schedule.PeriodOfDay(TimeSpan.FromHours(17.5), TimeSpan.FromHours(24)) },
{ DayOfWeek.Wednesday, new Schedule.PeriodOfDay(TimeSpan.FromHours(0), TimeSpan.FromHours(7)) },
{ DayOfWeek.Thursday, new Schedule.PeriodOfDay(TimeSpan.FromHours(17.5), TimeSpan.FromHours(24)) },
{ DayOfWeek.Thursday, new Schedule.PeriodOfDay(TimeSpan.FromHours(0), TimeSpan.FromHours(7)) },
{ DayOfWeek.Friday, new Schedule.PeriodOfDay(TimeSpan.FromHours(17.5), TimeSpan.FromHours(24)) },
{ DayOfWeek.Friday, new Schedule.PeriodOfDay(TimeSpan.FromHours(0), TimeSpan.FromHours(7)) },
{ DayOfWeek.Saturday, new Schedule.PeriodOfDay(TimeSpan.FromHours(17.5), TimeSpan.FromHours(24)) },
{ DayOfWeek.Saturday, new Schedule.PeriodOfDay(TimeSpan.FromHours(0), TimeSpan.FromHours(7)) },
{ DayOfWeek.Sunday, new Schedule.PeriodOfDay(TimeSpan.FromHours(17.5), TimeSpan.FromHours(24)) },
{ DayOfWeek.Sunday, new Schedule.PeriodOfDay(TimeSpan.FromHours(0), TimeSpan.FromHours(7)) }
};
public override async void Start()
{
// Handle calls as a detached task, catching all exceptions.
try
{
await Task.Run(async () =>
{
try
{
MyCall.Debug($"Script start delay: {DateTime.UtcNow - MyCall.LastChangeStatus}");
MyCall.Debug($"Incoming connection {MyCall} from {MyCall.Caller}");
bool intercepted = false;
var ps = MyCall.PS as PhoneSystem;
if (MyCall.Caller.DN is ExternalLine externalLine)
{
var DIDNumber = MyCall.Caller["inbound_did"];
var CallerID = MyCall.Caller.CallerID;
var currentTime = externalLine.Now(out var utc, out var timezone, out var groupmode);
// Intercept calls during the specified schedule
if (schedule.IsActiveTime(currentTime))
{
string[] DIDs = { "*" }; // Allow all DIDs
string[] Callers = { "*" }; // Allow all Callers
var destination_struct = new DestinationStruct(ps.GetDNByNumber(DestinationDN));
// Check if the call's DID and CallerID match the interception criteria
if ((DIDs.Contains(DIDNumber) || DIDs.Contains("*")) &&
(Callers.Contains(CallerID) || Callers.Contains("*")))
{
try
{
var result = await MyCall.RouteToAsync(destination_struct);
MyCall.Info($"{CallerID} -> {DIDNumber} has been redirected to {DestinationDN} ({result})");
intercepted = true;
}
catch (Exception ex)
{
MyCall.Info($"{CallerID} -> {DIDNumber}: interception failed. '{DestinationDN}' is not reachable: {ex}");
}
}
else
{
MyCall.Info($"{CallerID} -> {DIDNumber}@{currentTime}: Default CallerID/DID based routing will be applied");
}
}
}
MyCall.Return(intercepted);
}
catch (Exception ex)
{
MyCall.Error($"Script execution failed: {ex}");
MyCall.Return(false);
}
});
}
catch (Exception ex)
{
MyCall.Error($"Task execution failed: {ex}");
MyCall.Return(false);
}
}
}
}



