einige ( wenige) Zeilen aus Datenschutz/Sicherheitsgründen gekürzt oder gelöscht.
using CallFlow.CFD;
using CallFlow;
using MimeKit;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks.Dataflow;
using System.Threading.Tasks;
using System.Threading;
using System;
using TCX.Configuration;
namespace Heimwegtelefon_cfd
{
public class Main : ScriptBase<Main>, ICallflow, ICallflowProcessor
{
private bool executionStarted;
private bool executionFinished;
private bool disconnectFlowPending;
private BufferBlock<AbsEvent> eventBuffer;
private int currentComponentIndex;
private List<AbsComponent> mainFlowComponentList;
private List<AbsComponent> disconnectFlowComponentList;
private List<AbsComponent> errorFlowComponentList;
private List<AbsComponent> currentFlowComponentList;
private LogFormatter logFormatter;
private TimerManager timerManager;
private Dictionary<string, Variable> variableMap;
private TempWavFileManager tempWavFileManager;
private PromptQueue promptQueue;
private OnlineServices onlineServices;
private void DisconnectCallAndExitCallflow()
{
if (currentFlowComponentList == disconnectFlowComponentList)
logFormatter.Trace("Callflow finished...");
else
{
logFormatter.Trace("Callflow finished, disconnecting call...");
MyCall.Terminate();
}
}
private async Task ExecuteErrorFlow()
{
if (currentFlowComponentList == errorFlowComponentList)
{
logFormatter.Trace("Error during error handler flow, exiting callflow...");
DisconnectCallAndExitCallflow();
}
else if (currentFlowComponentList == disconnectFlowComponentList)
{
logFormatter.Trace("Error during disconnect handler flow, exiting callflow...");
executionFinished = true;
}
else
{
currentFlowComponentList = errorFlowComponentList;
currentComponentIndex = 0;
if (errorFlowComponentList.Count > 0)
{
logFormatter.Trace("Start executing error handler flow...");
await ProcessStart();
}
else
{
logFormatter.Trace("Error handler flow is empty...");
DisconnectCallAndExitCallflow();
}
}
}
private async Task ExecuteDisconnectFlow()
{
currentFlowComponentList = disconnectFlowComponentList;
currentComponentIndex = 0;
disconnectFlowPending = false;
if (disconnectFlowComponentList.Count > 0)
{
logFormatter.Trace("Start executing disconnect handler flow...");
await ProcessStart();
}
else
{
logFormatter.Trace("Disconnect handler flow is empty...");
executionFinished = true;
}
}
private EventResults CheckEventResult(EventResults eventResult)
{
if (eventResult == EventResults.MoveToNextComponent && ++currentComponentIndex == currentFlowComponentList.Count)
{
DisconnectCallAndExitCallflow();
return EventResults.Exit;
}
else if (eventResult == EventResults.Exit)
DisconnectCallAndExitCallflow();
return eventResult;
}
private void InitializeVariables(string callID)
{
// Call variables
variableMap["session.ani"] = new Variable(MyCall.Caller.CallerID);
variableMap["session.callid"] = new Variable(callID);
variableMap["session.dnis"] = new Variable(MyCall.DN.Number);
variableMap["session.did"] = new Variable(MyCall.Caller.CalledNumber);
variableMap["session.audioFolder"] = new Variable(Path.Combine(RecordingManager.Instance.AudioFolder, promptQueue.ProjectAudioFolder));
variableMap["session.transferingExtension"] = new Variable(MyCall["onbehlfof"] ?? string.Empty);
// Standard variables
variableMap["RecordResult.NothingRecorded"] = new Variable(RecordComponent.RecordResults.NothingRecorded);
variableMap["RecordResult.StopDigit"] = new Variable(RecordComponent.RecordResults.StopDigit);
variableMap["RecordResult.Completed"] = new Variable(RecordComponent.RecordResults.Completed);
variableMap["MenuResult.Timeout"] = new Variable(MenuComponent.MenuResults.Timeout);
variableMap["MenuResult.InvalidOption"] = new Variable(MenuComponent.MenuResults.InvalidOption);
variableMap["MenuResult.ValidOption"] = new Variable(MenuComponent.MenuResults.ValidOption);
variableMap["UserInputResult.Timeout"] = new Variable(UserInputComponent.UserInputResults.Timeout);
variableMap["UserInputResult.InvalidDigits"] = new Variable(UserInputComponent.UserInputResults.InvalidDigits);
variableMap["UserInputResult.ValidDigits"] = new Variable(UserInputComponent.UserInputResults.ValidDigits);
variableMap["VoiceInputResult.Timeout"] = new Variable(VoiceInputComponent.VoiceInputResults.Timeout);
variableMap["VoiceInputResult.InvalidInput"] = new Variable(VoiceInputComponent.VoiceInputResults.InvalidInput);
variableMap["VoiceInputResult.ValidInput"] = new Variable(VoiceInputComponent.VoiceInputResults.ValidInput);
variableMap["VoiceInputResult.ValidDtmfInput"] = new Variable(VoiceInputComponent.VoiceInputResults.ValidDtmfInput);
// User variables
variableMap["callflow$.lastCallTime"] = new Variable("");
variableMap["callflow$.lastCallDuration"] = new Variable("");
variableMap["callflow$.lastDestination"] = new Variable("");
variableMap["RecordResult.NothingRecorded"] = new Variable(RecordComponent.RecordResults.NothingRecorded);
variableMap["RecordResult.StopDigit"] = new Variable(RecordComponent.RecordResults.StopDigit);
variableMap["RecordResult.Completed"] = new Variable(RecordComponent.RecordResults.Completed);
variableMap["MenuResult.Timeout"] = new Variable(MenuComponent.MenuResults.Timeout);
variableMap["MenuResult.InvalidOption"] = new Variable(MenuComponent.MenuResults.InvalidOption);
variableMap["MenuResult.ValidOption"] = new Variable(MenuComponent.MenuResults.ValidOption);
variableMap["UserInputResult.Timeout"] = new Variable(UserInputComponent.UserInputResults.Timeout);
variableMap["UserInputResult.InvalidDigits"] = new Variable(UserInputComponent.UserInputResults.InvalidDigits);
variableMap["UserInputResult.ValidDigits"] = new Variable(UserInputComponent.UserInputResults.ValidDigits);
variableMap["VoiceInputResult.Timeout"] = new Variable(VoiceInputComponent.VoiceInputResults.Timeout);
variableMap["VoiceInputResult.InvalidInput"] = new Variable(VoiceInputComponent.VoiceInputResults.InvalidInput);
variableMap["VoiceInputResult.ValidInput"] = new Variable(VoiceInputComponent.VoiceInputResults.ValidInput);
variableMap["VoiceInputResult.ValidDtmfInput"] = new Variable(VoiceInputComponent.VoiceInputResults.ValidDtmfInput);
}
private void InitializeComponents(ICallflow callflow, ICall myCall, string logHeader)
{
{
ConditionalComponent AbfrageAnonym = new ConditionalComponent("AbfrageAnonym", callflow, myCall, logHeader);
mainFlowComponentList.Add(AbfrageAnonym);
AbfrageAnonym.ConditionList.Add(() => { return Convert.ToBoolean(CFDFunctions.CONTAINS(Convert.ToString(variableMap["session.ani"].Value),Convert.ToString("nonymous"))); });
AbfrageAnonym.ContainerList.Add(new SequenceContainerComponent("Anonymous", callflow, myCall, logHeader));
PromptPlaybackComponent DuRufstMitUnterdrückter = new PromptPlaybackComponent("DuRufstMitUnterdrückter", callflow, myCall, logHeader);
DuRufstMitUnterdrückter.AllowDtmfInput = false;
DuRufstMitUnterdrückter.Prompts.Add(new AudioFilePrompt(() => { return "converted_VoiceMessage2020HWTTest01hiddennumberMP3 (1).wav"; }));
AbfrageAnonym.ContainerList[0].ComponentList.Add(DuRufstMitUnterdrückter);
DisconnectCallComponent disconnectCallComponent4 = new DisconnectCallComponent("disconnectCallComponent4", callflow, myCall, logHeader);
AbfrageAnonym.ContainerList[0].ComponentList.Add(disconnectCallComponent4);
AbfrageAnonym.ConditionList.Add(() => { return Convert.ToBoolean(true); });
AbfrageAnonym.ContainerList.Add(new SequenceContainerComponent("mitNummer", callflow, myCall, logHeader));
WebInteractionComponent NinoxGesperrt = new WebInteractionComponent("NinoxGesperrt", callflow, myCall, logHeader);
NinoxGesperrt.HttpMethod = System.Net.Http.HttpMethod.Get;
NinoxGesperrt.ContentType = "application/json";
NinoxGesperrt.Timeout = 30000;
NinoxGesperrt.UriHandler = () => { return Convert.ToString(CFDFunctions.CONCATENATE(Convert.ToString(***={\"fields\":{\"Gesperrte Nummer\":\""),Convert.ToString(variableMap["session.ani"].Value),Convert.ToString("\"}}&perPage=1"))); };
NinoxGesperrt.ContentHandler = () => { return Convert.ToString(""); };
NinoxGesperrt.Headers.Add(new CallFlow.CFD.Parameter("Authorization", () => { return "Bearer 1498d2f0-bbfa-11eb-b95f-45215cef1c5e"; }));
mainFlowComponentList.Add(NinoxGesperrt);
ConditionalComponent AbrfrageGesperrt = new ConditionalComponent("AbrfrageGesperrt", callflow, myCall, logHeader);
mainFlowComponentList.Add(AbrfrageGesperrt);
AbrfrageGesperrt.ConditionList.Add(() => { return Convert.ToBoolean(CFDFunctions.NOT_EQUAL(NinoxGesperrt.ResponseContent,"[]")); });
AbrfrageGesperrt.ContainerList.Add(new SequenceContainerComponent("Gesperrt", callflow, myCall, logHeader));
PromptPlaybackComponent DeineNummerIstGesperrt = new PromptPlaybackComponent("DeineNummerIstGesperrt", callflow, myCall, logHeader);
DeineNummerIstGesperrt.AllowDtmfInput = false;
DeineNummerIstGesperrt.Prompts.Add(new AudioFilePrompt(() => { return "Gesperrte Rufnummer.wav"; }));
AbrfrageGesperrt.ContainerList[0].ComponentList.Add(DeineNummerIstGesperrt);
DisconnectCallComponent DisconnectCall3 = new DisconnectCallComponent("DisconnectCall3", callflow, myCall, logHeader);
AbrfrageGesperrt.ContainerList[0].ComponentList.Add(DisconnectCall3);
AbrfrageGesperrt.ConditionList.Add(() => { return Convert.ToBoolean(true); });
AbrfrageGesperrt.ContainerList.Add(new SequenceContainerComponent("NichtGesperrt", callflow, myCall, logHeader));
getLastCallLogin621206913ECCComponent getLastCallLogin = new getLastCallLogin621206913ECCComponent("getLastCallLogin", callflow, myCall, logHeader);
mainFlowComponentList.Add(getLastCallLogin);
WebInteractionComponent AnrufVerlauf = new WebInteractionComponent("AnrufVerlauf", callflow, myCall, logHeader);
AnrufVerlauf.HttpMethod = System.Net.Http.HttpMethod.Get;
AnrufVerlauf.ContentType = "application/json";
AnrufVerlauf.Timeout = 30000;
AnrufVerlauf.UriHandler = () => { return Convert.ToString(CFDFunctions.CONCATENATE(Convert.ToString****(variableMap["session.ani"].Value),Convert.ToString("&fromFilterType=MatchNumber&numberOfRows=1&searchFilter=&startRow=0&toFilter=&toFilterType=Any"))); };
AnrufVerlauf.ContentHandler = () => { return Convert.ToString(""); };
AnrufVerlauf.Headers.Add(new CallFlow.CFD.Parameter("Cookie", () => { return getLastCallLogin.ReturnValue; }));
mainFlowComponentList.Add(AnrufVerlauf);
TextAnalyzerComponent JsonXmlParser1 = new TextAnalyzerComponent("JsonXmlParser1", callflow, myCall, logHeader);
JsonXmlParser1.TextType = TextAnalyzerComponent.TextTypes.JSON;
JsonXmlParser1.TextHandler = () => { return Convert.ToString(AnrufVerlauf.ResponseContent); };
JsonXmlParser1.Mappings.Add("CallLogRows[0].CallTime", "callflow$.lastCallTime");
JsonXmlParser1.Mappings.Add("CallLogRows[0].Duration", "callflow$.lastCallDuration");
JsonXmlParser1.Mappings.Add("CallLogRows[0].Destination", "callflow$.lastDestination");
mainFlowComponentList.Add(JsonXmlParser1);
hatSchonAngerufen1460785109ECCComponent hatSchonAngerufen = new hatSchonAngerufen1460785109ECCComponent("hatSchonAngerufen", callflow, myCall, logHeader);
hatSchonAngerufen.Parameters.Add(new CallFlow.CFD.Parameter("lastCallDuration", () => { return variableMap["callflow$.lastCallDuration"].Value; }));
hatSchonAngerufen.Parameters.Add(new CallFlow.CFD.Parameter("lastCallTime", () => { return variableMap["callflow$.lastCallTime"].Value; }));
hatSchonAngerufen.Parameters.Add(new CallFlow.CFD.Parameter("now", () => { return CFDFunctions.NOW(); }));
mainFlowComponentList.Add(hatSchonAngerufen);
ConditionalComponent ruftWiederAn = new ConditionalComponent("ruftWiederAn", callflow, myCall, logHeader);
mainFlowComponentList.Add(ruftWiederAn);
ruftWiederAn.ConditionList.Add(() => { return Convert.ToBoolean(hatSchonAngerufen.ReturnValue); });
ruftWiederAn.ContainerList.Add(new SequenceContainerComponent("kleiner10Min", callflow, myCall, logHeader));
getAgentNumber1473127788ECCComponent getAgentNumber = new getAgentNumber1473127788ECCComponent("getAgentNumber", callflow, myCall, logHeader);
getAgentNumber.Parameters.Add(new CallFlow.CFD.Parameter("agent", () => { return variableMap["callflow$.lastDestination"].Value; }));
ruftWiederAn.ContainerList[0].ComponentList.Add(getAgentNumber);
ConditionalComponent warBeiAgent = new ConditionalComponent("warBeiAgent", callflow, myCall, logHeader);
ruftWiederAn.ContainerList[0].ComponentList.Add(warBeiAgent);
warBeiAgent.ConditionList.Add(() => { return Convert.ToBoolean(CFDFunctions.NOT_EQUAL(getAgentNumber.ReturnValue,"")); });
warBeiAgent.ContainerList.Add(new SequenceContainerComponent("wahr", callflow, myCall, logHeader));
TcxGetExtensionStatusComponent AgentStatus = new TcxGetExtensionStatusComponent("AgentStatus", callflow, myCall, logHeader);
AgentStatus.ExtensionHandler = () => { return Convert.ToString(getAgentNumber.ReturnValue); };
warBeiAgent.ContainerList[0].ComponentList.Add(AgentStatus);
LoggerComponent loggerComponent2 = new LoggerComponent("loggerComponent2", callflow, myCall, logHeader);
loggerComponent2.Level = LoggerComponent.LogLevels.Error;
loggerComponent2.TextHandler = () => { return Convert.ToString(AgentStatus.CurrentProfile); };
warBeiAgent.ContainerList[0].ComponentList.Add(loggerComponent2);
ConditionalComponent agentVerfügbar = new ConditionalComponent("agentVerfügbar", callflow, myCall, logHeader);
warBeiAgent.ContainerList[0].ComponentList.Add(agentVerfügbar);
agentVerfügbar.ConditionList.Add(() => { return Convert.ToBoolean(CFDFunctions.EQUAL(AgentStatus.CurrentProfileName,"Available")); });
agentVerfügbar.ContainerList.Add(new SequenceContainerComponent("istVerfügbar", callflow, myCall, logHeader));
TransferComponent zumLetztenAgenten = new TransferComponent("zumLetztenAgenten", callflow, myCall, logHeader);
zumLetztenAgenten.DestinationHandler = () => { return Convert.ToString(getAgentNumber.ReturnValue); };
zumLetztenAgenten.DelayMilliseconds = 500;
agentVerfügbar.ContainerList[0].ComponentList.Add(zumLetztenAgenten);
agentVerfügbar.ConditionList.Add(() => { return Convert.ToBoolean(true); });
agentVerfügbar.ContainerList.Add(new SequenceContainerComponent("nichtVerfügbar", callflow, myCall, logHeader));
TransferComponent Rückruf = new TransferComponent("Rückruf", callflow, myCall, logHeader);
Rückruf.DestinationHandler = () => { return Convert.ToString(809); };
Rückruf.DelayMilliseconds = 500;
warBeiAgent.ContainerList[0].ComponentList.Add(Rückruf);
warBeiAgent.ConditionList.Add(() => { return Convert.ToBoolean(true); });
warBeiAgent.ContainerList.Add(new SequenceContainerComponent("falsch", callflow, myCall, logHeader));
ruftWiederAn.ConditionList.Add(() => { return Convert.ToBoolean(true); });
ruftWiederAn.ContainerList.Add(new SequenceContainerComponent("mehrAls10Min", callflow, myCall, logHeader));
ConditionalComponent Abfrage_Öffnungszeit = new ConditionalComponent("Abfrage_Öffnungszeit", callflow, myCall, logHeader);
mainFlowComponentList.Add(Abfrage_Öffnungszeit);
Abfrage_Öffnungszeit.ConditionList.Add(() => { return Convert.ToBoolean(((DateTime.Now.DayOfWeek == DayOfWeek.Sunday || DateTime.Now.DayOfWeek == DayOfWeek.Monday || DateTime.Now.DayOfWeek == DayOfWeek.Tuesday || DateTime.Now.DayOfWeek == DayOfWeek.Wednesday || DateTime.Now.DayOfWeek == DayOfWeek.Thursday || DateTime.Now.DayOfWeek == DayOfWeek.Friday || DateTime.Now.DayOfWeek == DayOfWeek.Saturday) && (DateTime.Now.Hour > 20 || DateTime.Now.Hour == 20 && DateTime.Now.Minute >= 0) && (DateTime.Now.Hour < 23 || DateTime.Now.Hour == 23 && DateTime.Now.Minute <= 59) || (DateTime.Now.DayOfWeek == DayOfWeek.Sunday || DateTime.Now.DayOfWeek == DayOfWeek.Saturday) && (DateTime.Now.Hour > 0 || DateTime.Now.Hour == 0 && DateTime.Now.Minute >= 0) && (DateTime.Now.Hour < 3 || DateTime.Now.Hour == 3 && DateTime.Now.Minute <= 0))); });
Abfrage_Öffnungszeit.ContainerList.Add(new SequenceContainerComponent("Abfrage_Öffnungszeit_0", callflow, myCall, logHeader));
MenuComponent Menu1 = new MenuComponent("Menu1", callflow, myCall, logHeader);
Menu1.AllowDtmfInput = true;
Menu1.MaxRetryCount = 2;
Menu1.Timeout = 5000;
Menu1.ValidOptionList.AddRange(new char[] { '1', '2' });
Menu1.InitialPrompts.Add(new AudioFilePrompt(() => { return "converted_Menu.wav"; }));
Menu1.SubsequentPrompts.Add(new AudioFilePrompt(() => { return "converted_VoiceMessage2021_vielen-dank-durchgestellt_29-03-2021 (1).wav"; }));
Abfrage_Öffnungszeit.ContainerList[0].ComponentList.Add(Menu1);
ConditionalComponent Menu1_Conditional = new ConditionalComponent("Menu1_Conditional", callflow, myCall, logHeader);
Abfrage_Öffnungszeit.ContainerList[0].ComponentList.Add(Menu1_Conditional);
Menu1_Conditional.ConditionList.Add(() => { return Menu1.Result == MenuComponent.MenuResults.ValidOption && Menu1.SelectedOption == '1'; });
Menu1_Conditional.ContainerList.Add(new SequenceContainerComponent("Menu1_Conditional_Option1", callflow, myCall, logHeader));
PromptPlaybackComponent PromptPlayback3 = new PromptPlaybackComponent("PromptPlayback3", callflow, myCall, logHeader);
PromptPlayback3.AllowDtmfInput = true;
PromptPlayback3.Prompts.Add(new AudioFilePrompt(() => { return "Infos0105.wav"; }));
Menu1_Conditional.ContainerList[0].ComponentList.Add(PromptPlayback3);
Menu1_Conditional.ConditionList.Add(() => { return Menu1.Result == MenuComponent.MenuResults.ValidOption && Menu1.SelectedOption == '2'; });
Menu1_Conditional.ContainerList.Add(new SequenceContainerComponent("Menu1_Conditional_Option2", callflow, myCall, logHeader));
TransferComponent HWT800_1 = new TransferComponent("HWT800_1", callflow, myCall, logHeader);
HWT800_1.DestinationHandler = () => { return Convert.ToString(800); };
HWT800_1.DelayMilliseconds = 500;
Menu1_Conditional.ContainerList[1].ComponentList.Add(HWT800_1);
Menu1_Conditional.ConditionList.Add(() => { return Menu1.Result == MenuComponent.MenuResults.InvalidOption || Menu1.Result == MenuComponent.MenuResults.Timeout; });
Menu1_Conditional.ContainerList.Add(new SequenceContainerComponent("Menu1_Conditional_TimeoutOrInvalidOption", callflow, myCall, logHeader));
TransferComponent HWT800_2 = new TransferComponent("HWT800_2", callflow, myCall, logHeader);
HWT800_2.DestinationHandler = () => { return Convert.ToString(800); };
HWT800_2.DelayMilliseconds = 500;
Menu1_Conditional.ContainerList[2].ComponentList.Add(HWT800_2);
Abfrage_Öffnungszeit.ConditionList.Add(() => { return Convert.ToBoolean((!IsServerOfficeHourActive(myCall))); });
Abfrage_Öffnungszeit.ContainerList.Add(new SequenceContainerComponent("Abfrage_Öffnungszeit_1", callflow, myCall, logHeader));
PromptPlaybackComponent PromptPlayback4 = new PromptPlaybackComponent("PromptPlayback4", callflow, myCall, logHeader);
PromptPlayback4.AllowDtmfInput = true;
PromptPlayback4.Prompts.Add(new AudioFilePrompt(() => { return "outofoffice20Uhr.wav"; }));
Abfrage_Öffnungszeit.ContainerList[1].ComponentList.Add(PromptPlayback4);
DisconnectCallComponent DisconnectCall1 = new DisconnectCallComponent("DisconnectCall1", callflow, myCall, logHeader);
mainFlowComponentList.Add(DisconnectCall1);
}
{
}
{
}
// Add a final DisconnectCall component to the main and error handler flows, in order to complete pending prompt playbacks...
DisconnectCallComponent mainAutoAddedFinalDisconnectCall = new DisconnectCallComponent("mainAutoAddedFinalDisconnectCall", callflow, myCall, logHeader);
DisconnectCallComponent errorHandlerAutoAddedFinalDisconnectCall = new DisconnectCallComponent("errorHandlerAutoAddedFinalDisconnectCall", callflow, myCall, logHeader);
mainFlowComponentList.Add(mainAutoAddedFinalDisconnectCall);
errorFlowComponentList.Add(errorHandlerAutoAddedFinalDisconnectCall);
}
private bool IsServerInHoliday(ICall myCall)
{
Tenant tenant = myCall.PS.GetTenant();
return tenant != null && tenant.IsHoliday(new DateTimeOffset(DateTime.Now));
}
private bool IsServerOfficeHourActive(ICall myCall)
{
Tenant tenant = myCall.PS.GetTenant();
if (tenant == null) return false;
string overrideOfficeTime = tenant.GetPropertyValue("OVERRIDEOFFICETIME");
if (!String.IsNullOrEmpty(overrideOfficeTime))
{
if (overrideOfficeTime == "1") // Forced to in office hours
return true;
else if (overrideOfficeTime == "2") // Forced to out of office hours
return false;
}
DateTime nowDt = DateTime.Now;
if (tenant.IsHoliday(new DateTimeOffset(nowDt))) return false;
Schedule officeHours = tenant.Hours;
Nullable<bool> result = officeHours.IsActiveTime(nowDt);
return result.GetValueOrDefault(false);
}
public Main()
{
this.executionStarted = false;
this.executionFinished = false;
this.disconnectFlowPending = false;
this.eventBuffer = new BufferBlock<AbsEvent>();
this.currentComponentIndex = 0;
this.mainFlowComponentList = new List<AbsComponent>();
this.disconnectFlowComponentList = new List<AbsComponent>();
this.errorFlowComponentList = new List<AbsComponent>();
this.currentFlowComponentList = mainFlowComponentList;
this.timerManager = new TimerManager();
this.timerManager.OnTimeout += (state) => eventBuffer.Post(new TimeoutEvent(state));
this.variableMap = new Dictionary<string, Variable>();
AbsTextToSpeechEngine textToSpeechEngine = null;
AbsSpeechToTextEngine speechToTextEngine = null;
this.onlineServices = new OnlineServices(textToSpeechEngine, speechToTextEngine);
}
public override void Start()
{
MyCall.SetBackgroundAudio(false, new string[] { });
string callID = MyCall?.Caller["chid"] ?? "Unknown";
string logHeader = $"Heimwegtelefon_cfd - CallID {callID}";
this.logFormatter = new LogFormatter(MyCall, logHeader, "Callflow");
this.promptQueue = new PromptQueue(this, MyCall, "Heimwegtelefon_cfd", logHeader);
this.tempWavFileManager = new TempWavFileManager(logFormatter);
this.timerManager.CallStarted();
InitializeComponents(this, MyCall, logHeader);
InitializeVariables(callID);
MyCall.OnTerminated += () => eventBuffer.Post(new CallTerminatedEvent());
MyCall.OnDTMFInput += x => eventBuffer.Post(new DTMFReceivedEvent(x));
logFormatter.Trace("Start executing main flow...");
eventBuffer.Post(new StartEvent());
Task.Run(() => EventProcessingLoop());
}
public void PostStartEvent()
{
eventBuffer.Post(new StartEvent());
}
public void PostDTMFReceivedEvent(char digit)
{
eventBuffer.Post(new DTMFReceivedEvent(digit));
}
public void PostPromptPlayedEvent()
{
eventBuffer.Post(new PromptPlayedEvent());
}
public void PostTransferFailedEvent()
{
eventBuffer.Post(new TransferFailedEvent());
}
public void PostMakeCallResultEvent(bool result)
{
eventBuffer.Post(new MakeCallResultEvent(result));
}
public void PostCallTerminatedEvent()
{
eventBuffer.Post(new CallTerminatedEvent());
}
public void PostTimeoutEvent(object state)
{
eventBuffer.Post(new TimeoutEvent(state));
}
private async Task EventProcessingLoop()
{
executionStarted = true;
while (!executionFinished)
{
AbsEvent evt = await eventBuffer.ReceiveAsync();
await evt?.ProcessEvent(this);
}
}
public async Task ProcessStart()
{
try
{
EventResults eventResult;
do
{
AbsComponent currentComponent = currentFlowComponentList[currentComponentIndex];
logFormatter.Trace("Start executing component '" + currentComponent.Name + "'");
eventResult = await currentComponent.Start(timerManager, variableMap, tempWavFileManager, promptQueue);
}
while (CheckEventResult(eventResult) == EventResults.MoveToNextComponent);
if (eventResult == EventResults.Exit) executionFinished = true;
}
catch (Exception exc)
{
logFormatter.Error("Error executing last component: " + exc.ToString());
await ExecuteErrorFlow();
}
}
public async Task ProcessDTMFReceived(char digit)
{
try
{
AbsComponent currentComponent = currentFlowComponentList[currentComponentIndex];
logFormatter.Trace("OnDTMFReceived for component '" + currentComponent.Name + "' - Digit: '" + digit + "'");
EventResults eventResult = CheckEventResult(await currentComponent.OnDTMFReceived(timerManager, variableMap, tempWavFileManager, promptQueue, digit));
if (eventResult == EventResults.MoveToNextComponent)
{
if (disconnectFlowPending)
await ExecuteDisconnectFlow();
else
await ProcessStart();
}
else if (eventResult == EventResults.Exit)
executionFinished = true;
}
catch (Exception exc)
{
logFormatter.Error("Error executing last component: " + exc.ToString());
await ExecuteErrorFlow();
}
}
public async Task ProcessPromptPlayed()
{
try
{
promptQueue.NotifyPlayFinished();
AbsComponent currentComponent = currentFlowComponentList[currentComponentIndex];
logFormatter.Trace("OnPromptPlayed for component '" + currentComponent.Name + "'");
EventResults eventResult = CheckEventResult(await currentComponent.OnPromptPlayed(timerManager, variableMap, tempWavFileManager, promptQueue));
if (eventResult == EventResults.MoveToNextComponent)
{
if (disconnectFlowPending)
await ExecuteDisconnectFlow();
else
await ProcessStart();
}
else if (eventResult == EventResults.Exit)
executionFinished = true;
}
catch (Exception exc)
{
logFormatter.Error("Error executing last component: " + exc.ToString());
await ExecuteErrorFlow();
}
}
public async Task ProcessTransferFailed()
{
try
{
AbsComponent currentComponent = currentFlowComponentList[currentComponentIndex];
logFormatter.Trace("OnTransferFailed for component '" + currentComponent.Name + "'");
EventResults eventResult = CheckEventResult(await currentComponent.OnTransferFailed(timerManager, variableMap, tempWavFileManager, promptQueue));
if (eventResult == EventResults.MoveToNextComponent)
{
if (disconnectFlowPending)
await ExecuteDisconnectFlow();
else
await ProcessStart();
}
else if (eventResult == EventResults.Exit)
executionFinished = true;
}
catch (Exception exc)
{
logFormatter.Error("Error executing last component: " + exc.ToString());
await ExecuteErrorFlow();
}
}
public async Task ProcessMakeCallResult(bool result)
{
try
{
AbsComponent currentComponent = currentFlowComponentList[currentComponentIndex];
logFormatter.Trace("OnMakeCallResult for component '" + currentComponent.Name + "' - Result: '" + result + "'");
EventResults eventResult = CheckEventResult(await currentComponent.OnMakeCallResult(timerManager, variableMap, tempWavFileManager, promptQueue, result));
if (eventResult == EventResults.MoveToNextComponent)
{
if (disconnectFlowPending)
await ExecuteDisconnectFlow();
else
await ProcessStart();
}
else if (eventResult == EventResults.Exit)
executionFinished = true;
}
catch (Exception exc)
{
logFormatter.Error("Error executing last component: " + exc.ToString());
await ExecuteErrorFlow();
}
}
public async Task ProcessCallTerminated()
{
try
{
if (executionStarted)
{
// First notify the call termination to the current component
AbsComponent currentComponent = currentFlowComponentList[currentComponentIndex];
logFormatter.Trace("OnCallTerminated for component '" + currentComponent.Name + "'");
// Don't wrap around CheckEventResult, because the call has been already disconnected,
// and the following action to execute depends on the returned value.
EventResults eventResult = await currentComponent.OnCallTerminated(timerManager, variableMap, tempWavFileManager, promptQueue);
if (eventResult == EventResults.MoveToNextComponent)
{
// Next, if the current component has completed its job, execute the disconnect flow
await ExecuteDisconnectFlow();
}
else if (eventResult == EventResults.Wait)
{
// If the user component needs more events, wait for it to finish, and signal here that we need to execute
// the disconnect handler flow of the callflow next...
disconnectFlowPending = true;
}
else if (eventResult == EventResults.Exit)
executionFinished = true;
}
}
catch (Exception exc)
{
logFormatter.Error("Error executing last component: " + exc.ToString());
await ExecuteErrorFlow();
}
finally
{
// Finally, delete temporary files
tempWavFileManager.DeleteFilesAndFolders();
}
}
public async Task ProcessTimeout(object state)
{
try
{
AbsComponent currentComponent = currentFlowComponentList[currentComponentIndex];
logFormatter.Trace("OnTimeout for component '" + currentComponent.Name + "'");
EventResults eventResult = CheckEventResult(await currentComponent.OnTimeout(timerManager, variableMap, tempWavFileManager, promptQueue, state));
if (eventResult == EventResults.MoveToNextComponent)
{
if (disconnectFlowPending)
await ExecuteDisconnectFlow();
else
await ProcessStart();
}
else if (eventResult == EventResults.Exit)
executionFinished = true;
}
catch (Exception exc)
{
logFormatter.Error("Error executing last component: " + exc.ToString());
await ExecuteErrorFlow();
}
}
public class getLastCallLogin621206913ECCComponent : ExternalCodeExecutionComponent
{
public List<CallFlow.CFD.Parameter> Parameters { get; } = new List<CallFlow.CFD.Parameter>();
public getLastCallLogin621206913ECCComponent(string name, ICallflow callflow, ICall myCall, string projectName) : base(name, callflow, myCall, projectName) {}
protected override object ExecuteCode()
{
return getLastCall();
}
private object getLastCall()
{
System.Net.Http.HttpClientHandler handler = new System.Net.Http.HttpClientHandler();
var values = "{\"Username\": \"***
var content = new System.Net.Http.StringContent(values, System.Text.Encoding.UTF8, "application/json");
System.Net.Http.HttpClient client = new System.Net.Http.HttpClient(handler);
System.Net.Http.HttpResponseMessage response = client.PostAsync("
https://heimwegtelefon-ev.my3cx.de:5001/api/login", content).Result;
IEnumerable<string> cookieValues = response.Headers.GetValues("Set-Cookie");
foreach (string cookieValue in cookieValues)
{
return cookieValue;
}
return "ERROR - Login Failed";
}
}
public class hatSchonAngerufen1460785109ECCComponent : ExternalCodeExecutionComponent
{
public List<CallFlow.CFD.Parameter> Parameters { get; } = new List<CallFlow.CFD.Parameter>();
public hatSchonAngerufen1460785109ECCComponent(string name, ICallflow callflow, ICall myCall, string projectName) : base(name, callflow, myCall, projectName) {}
protected override object ExecuteCode()
{
return vor10Min(Convert.ToString(Parameters[0].Value), Convert.ToString(Parameters[1].Value), Convert.ToString(Parameters[2].Value));
}
private object vor10Min(string lastCallDuration, string lastCallTime, string now)
{
try
{
var callTime = DateTime.Parse(lastCallTime);
var callDuration = TimeSpan.Parse(lastCallDuration);
System.TimeSpan timeout = new System.TimeSpan(0, 0, 10, 0);
callTime = callTime.Add(timeout);
callTime = callTime.Add(callDuration);
return callTime.CompareTo(DateTime.Now) >= 0;
}
catch {
return false;
} }
}
public class getAgentNumber1473127788ECCComponent : ExternalCodeExecutionComponent
{
public List<CallFlow.CFD.Parameter> Parameters { get; } = new List<CallFlow.CFD.Parameter>();
public getAgentNumber1473127788ECCComponent(string name, ICallflow callflow, ICall myCall, string projectName) : base(name, callflow, myCall, projectName) {}
protected override object ExecuteCode()
{
return getAgentNumber(Convert.ToString(Parameters[0].Value));
}
private object getAgentNumber(string agent)
{
var number = System.Text.RegularExpressions.Regex.Replace(agent, @".*\(([0-9]*)\)", "$1");
if(number == "800"){
return "";
}
if(number == "801"){
return "";
}
if(number == "802"){
return "";
}
if(number == "803"){
return "";
}
if(number == "804"){
return "";
}
if(number == "805"){
return "";
}
return number; }
}
}
}