3CX Holiday Prompt Globally

User3Inc

Premier Customer
Joined
May 6, 2022
Messages
51
Reaction score
4
Hi,

Is there a way to globally set a holiday prompt for all queues instead of going into each queue manually?

Thanks!
 
Hi,

Maybe the solution for you is to go to Integrations > Call scripts > Add from store and click on holiday.cs.
Then run the script upon receiving a call on a trunk and then select the trunk.

after this you can go to office hours > office holidays and configure the holiday there with the prompt.
Now the system will look at this holiday, and play this prompt.
 
You can modify the holiday.cs file (and upload your sound file "VACATION.wav" along with the script), this will play VACATION.wav if you did not provide another audio in the settings for the holiday:

C#:
#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)
                    {
                            if (!string.IsNullOrWhiteSpace(timeBasedroute.holiday?.HolidayPrompt))
                            {
                                await MyCall.AssureMedia()
                                    .ContinueWith(x => MyCall.PlayPrompt(null, [timeBasedroute.holiday?.HolidayPrompt], PlayPromptOptions.Blocked))
                                    .Unwrap();
                                MyCall.Info($"timeBasedroute holiday PromptPlayed");
                            }
                            else
                            {
                                await MyCall.AssureMedia()
                                    .ContinueWith(x => MyCall.PlayPrompt(null, new[] {"VACATION.wav"}, PlayPromptOptions.Blocked))
                                    .Unwrap();
                                MyCall.Info($"VACATION.wav PromptPlayed");
                                // return true;  // <<<=== STOP default routing procedure !!
                            }
                    }
                }
            }
            return false;//we always return false to continue default trunk routing procedure.
        }
    }
}
 
Hello @User3Inc

As mentioned above,

You can configure the Holidays per department by navigating to Admin > Office Hours > select Department > Office Holidays.
There you can upload different prompts for each holiday configured.
In order for the prompt to play you will have to configure the script by navigating to Admin > Integrations > Call Scripts > Add from store > holiday.

This script will check if it is a holiday and play the prompt configured for the specific holiday configured in the office hours.

See also our guide Call Flow Script: Play Custom Holiday Message Based On Date
 
Hang on, they are talking about queues: "set a holiday prompt for all queues". While it is related to setting up holidays, that does not help with changing the intro prompt for all queues. Maybe I'm misunderstanding the question and everyone else understands we are talking about holidays? While it would be possible to change the assigned intro prompt for multiple queues via the Call Control API, I cannot think of a way to do it any other way.

If we are talking about setting up departmental holidays, you may want to take a look at our free 3CX Holiday Importer tool.
1747945127100.png
With our tool, you select the country and year and it will display all the national and religious holidays for your country and then you simply choose which holidays to add. Note that there is a "Department" field that allows you to select different holidays for each department.

I would like to also bring to your attention the "OpenAI" settings section. In this part of the tool you can use AI to generate your holiday prompts using text-to-speech. And for those of you that think text-to-speech results in a robotic voice, you have not been paying attention. Speaking for myself, I literally cannot tell that the generated prompt is not made by a human. It is truly amazing.

Here is a little secret....

You can use this tool to create prompts for your IVRs, queue intro prompts, etc. It automatically creates 3CX compatible prompts so no conversion is necessary. Just copy the resulting .wav file and use it anywhere you need a awesome AI generated prompt in 3CX and it is free. Well, you do have to add your OpenAI key, but you needed that for 3CX anyway. And the cost-per-prompt is fractions of a penny, so knock yourself out!
 

Latest Posts

Forum statistics

Threads
111,962
Messages
589,995
Members
164,867
Latest member
swegner