示例#1
0
        protected override void OnStartProcessing(TelecomScriptInterface tsInterface, CallButler.Telecom.TelecomProviderBase telecomProvider, WOSI.CallButler.Data.DataProviders.CallButlerDataProviderBase dataProvider)
        {
            LoggingService.AddLogEntry(LogLevel.Extended, "(Line " + tsInterface.LineNumber + ") Executing custom script at " + customScriptLocation, false);

            IMLScript imlScript = new IMLScript();

            ScriptPage introPage = new ScriptPage();

            introPage.ID = Guid.NewGuid().ToString();

            /*if (LicenseService.IsTrialLicense())
             * {
             *  if (Properties.Settings.Default.WelcomeGreetingDelay > 0)
             *  {
             *      Delay welcomeDelay = new Delay();
             *      welcomeDelay.DelayTime = Properties.Settings.Default.WelcomeGreetingDelay.ToString();
             *      introPage.Actions.Add(welcomeDelay);
             *  }
             *
             *  introPage.Actions.Add(ScriptCompilers.ScriptUtils.CreateExternalAction(ScriptCompilers.BaseExternalCommands.CALLBUTLERINTERNAL_PlayLicenseIntroGreeting.ToString(), ""));
             * }*/

            ScriptCompilers.ScriptUtils.ProcessPersonalizedGreeting(dataProvider, ref introPage, Properties.Settings.Default.CustomerID, tsInterface.IMLInterpreter.CallerDisplayName, tsInterface.IMLInterpreter.CallerUsername, tsInterface.IMLInterpreter.CallerHost, tsInterface.IMLInterpreter.DialedUsername);

            GotoPage gotoPage = new GotoPage();

            gotoPage.Location = customScriptLocation;
            introPage.Actions.Add(gotoPage);

            imlScript.Pages.Add(introPage);

            tsInterface.IMLInterpreter.StartScript(imlScript, System.IO.Path.GetDirectoryName(customScriptLocation));
        }
 void imlInterp_TransferCall(object sender, WOSI.IVR.IML.TransferEventArgs e)
 {
     if (TransferCall != null)
     {
         LoggingService.AddLogEntry(LogLevel.Basic, "(Line " + lineNumber + ") Transferring call to " + WOSI.Utilities.StringUtils.FormatPhoneNumber(e.TransferTo), false);
         TransferCall(this, e);
     }
 }
        void imlInterp_StopRecording(object sender, StopRecordingEventArgs e)
        {
            telecomProvider.StopRecording(lineNumber, e.Comments);

            LoggingService.AddLogEntry(LogLevel.Extended, "(Line " + lineNumber + ") Stopped recording", false);

            recording = false;
        }
 void telecomProvider_RemoteOnHold(object sender, LineEventArgs e)
 {
     if (e.LineNumber == lineNumber)
     {
         LoggingService.AddLogEntry(LogLevel.Extended, "(Line " + lineNumber + ") Call placed on hold from remote caller.", false);
         imlInterp.SignalCallOnHold();
     }
 }
 void telecomProvider_SpeechRecognized(object sender, CallInputEventArgs e)
 {
     if (e.LineNumber == lineNumber)
     {
         LoggingService.AddLogEntry(LogLevel.Extended, "(Line " + lineNumber + ") Heard the phrase '" + e.InputString + "'", false);
         imlInterp.SignalSpeech(e.InputString);
     }
 }
 void telecomProvider_TransferSucceeded(object sender, LineEventArgs e)
 {
     if (e.LineNumber == lineNumber)
     {
         LoggingService.AddLogEntry(LogLevel.Extended, "(Line " + lineNumber + ") Transfer succeeded", false);
         imlInterp.SignalTransferSuccess();
     }
 }
 void telecomProvider_TransferFailed(object sender, LineEventArgs e)
 {
     if (e.LineNumber == lineNumber)
     {
         LoggingService.AddLogEntry(LogLevel.Extended, "(Line " + lineNumber + ") Transfer failed", true);
         imlInterp.SignalTransferFailure();
     }
 }
 void telecomProvider_FinishedSpeaking(object sender, LineEventArgs e)
 {
     if (e.LineNumber == lineNumber)
     {
         LoggingService.AddLogEntry(LogLevel.Extended, "(Line " + lineNumber + ") Finished speaking", false);
         imlInterp.SignalEventCallback(imlScriptEventToken);
     }
 }
 void imlInterp_JoinConference(object sender, ConferenceEventArgs e)
 {
     // If the line isn't in use, don't do anything
     if (telecomProvider.IsLineInUse(lineNumber))
     {
         LoggingService.AddLogEntry(LogLevel.Extended, "(Line " + lineNumber + ") Joining conference ID " + e.ConferenceID, false);
         telecomProvider.AddLineToConference(e.ConferenceID, lineNumber);
     }
 }
        void imlInterp_StartRecording(object sender, SoundFileEventArgs e)
        {
            telecomProvider.StartRecording(lineNumber, e.SoundFilename, e.Format);

            LoggingService.AddLogEntry(LogLevel.Extended, "(Line " + lineNumber + ") Started recording to " + e.SoundFilename, false);

            lastRecording = e.SoundFilename;
            recording     = true;
        }
        void telecomProvider_CallTemporarilyMoved(object sender, CallEventArgs e)
        {
            if (e.LineNumber == lineNumber)
            {
                LoggingService.AddLogEntry(LogLevel.Basic, "(Line " + e.LineNumber + ") Call Temporarily Moved to " + e.CallingToNumber, false);

                if (scriptProcessor != null)
                {
                    scriptProcessor.OnCallTemporarilyMoved(telecomProvider, e);
                }
            }
        }
        void telecomProvider_FaxToneDetected(object sender, LineEventArgs e)
        {
            if (e.LineNumber == lineNumber)
            {
                LoggingService.AddLogEntry(LogLevel.Extended, "(Line " + lineNumber + ") Detected a fax tone", false);

                if (Properties.Settings.Default.AutoForwardFaxTo != null && Properties.Settings.Default.AutoForwardFaxTo.Length > 0)
                {
                    telecomProvider.TransferCall(e.LineNumber, Properties.Settings.Default.AutoForwardFaxTo);
                }
                else
                {
                    imlInterp.SignalFaxTone();
                }
            }
        }
        void imlInterp_CopyLastRecording(object sender, SoundFileEventArgs e)
        {
            try
            {
                if (!recording && lastRecording != null && lastRecording.Length > 0 && File.Exists(lastRecording))
                {
                    File.Copy(lastRecording, e.SoundFilename);

                    LoggingService.AddLogEntry(LogLevel.Extended, "(Line " + lineNumber + ") Move last recording at " + lastRecording + " to " + e.SoundFilename, false);
                }
            }
            catch (Exception ex)
            {
                LoggingService.AddLogEntry(LogLevel.ErrorsOnly, "(Line " + lineNumber + ") Unable to move last recording at " + lastRecording + " to " + e.SoundFilename, true);
            }
        }
        public void PlaceCall(TelephoneNumberEventArgs e)
        {
            if (!telecomProvider.IsLineInUse(lineNumber) && e.Number.Length > 0)
            {
                WOSI.CallButler.Data.CallButlerDataset.ProvidersRow profile = FindProvider(e.Profile);

                telecomProvider.Call(lineNumber, e.Number, e.FromCallerID, e.FromCallerNumber, e.Replaces, e.ReferredBy, e.RequestAutoAnswer, profile);

                LoggingService.AddLogEntry(LogLevel.Basic, "(Line " + lineNumber + ") Making an outgoing call to " + WOSI.Utilities.StringUtils.FormatPhoneNumber(e.Number), false);

                imlInterp.SignalEventCallback(e.EventToken);
            }
            else
            {
                imlInterp.SignalCallFailure();
            }
        }
        /*public void UpdateExtensionCall(int lineNumber, CallStatus status, string callerName, string callerPhoneNumber)
         * {
         *  if (Properties.Settings.Default.EnableKinesisServer)
         *  {
         *      if (this.Extension != null)
         *      {
         *          CallInfo callInfo = new CallInfo(callID, lineNumber, status, callerName, callerPhoneNumber);
         *          extStateService.UpdateCallState(this.Extension.ExtensionID, callInfo);
         *
         *          if (status == CallStatus.NotOnCall)
         *              extStateService.RemoveCallState(this.extension.ExtensionID, lineNumber);
         *      }
         *  }
         * }
         *
         * public void UpdateExtensionCallStatus(CallStatus callStatus)
         * {
         *  if (Properties.Settings.Default.EnableKinesisServer)
         *  {
         *      if (this.Extension != null)
         *      {
         *          extStateService.UpdateExtensionState(true, this.Extension.ExtensionID, StateEventType.CallStatusUpdate, new ExtensionStateParameter(StateParameterType.CallStatus, (int)callStatus));
         *      }
         *  }
         * }*/

        private void CheckAvailability()
        {
            if (!IsAvailable)
            {
                string errorMessage = "(Line " + lineNumber + ") The call is finished but the line still appears to be locked. You may want to check the script to make sure it is exiting gracefully.\r\n";

                errorMessage += "Locked: " + locked.ToString() + "\r\n";
                errorMessage += "Script Is Running: " + imlInterp.ScriptIsRunning.ToString() + "\r\n";
                errorMessage += "Line In Use: " + telecomProvider.IsLineInUse(lineNumber).ToString() + "\r\n";

                if (imlInterp.ImlScript != null)
                {
                    errorMessage += "Script: " + imlInterp.ImlScript.Description;
                }

                LoggingService.AddLogEntry(LogLevel.Basic, errorMessage, false);
            }
        }
        void imlInterp_DeleteLastRecording(object sender, EventArgs e)
        {
            try
            {
                if (!recording && lastRecording != null && lastRecording.Length > 0 && File.Exists(lastRecording))
                {
                    File.Delete(lastRecording);

                    lastRecording = null;

                    LoggingService.AddLogEntry(LogLevel.Extended, "(Line " + lineNumber + ") Deleted last recording at " + lastRecording, false);
                }
            }
            catch (Exception ex)
            {
                LoggingService.AddLogEntry(LogLevel.ErrorsOnly, "(Line " + lineNumber + ") Unable to delete recording at " + lastRecording, true);
            }
        }
        void telecomProvider_DTMFToneRecognized(object sender, CallInputEventArgs e)
        {
            if (e.LineNumber == lineNumber)
            {
                string typeStr = "OOB";

                if (e.InAudio)
                {
                    typeStr = "In Audio";
                }

                LoggingService.AddLogEntry(LogLevel.Extended, "(Line " + lineNumber + ") Heard a DTMF tone '" + e.InputString + "' (" + typeStr + ")", false);
                imlInterp.SignalDTMFDigit(e.InputString);

                if (scriptProcessor != null)
                {
                    scriptProcessor.OnDTMFDigit(telecomProvider, e);
                }
            }
        }
        void telecomProvider_CallFailed(object sender, CallFailureEventArgs e)
        {
            if (e.LineNumber == lineNumber)
            {
                LoggingService.AddLogEntry(LogLevel.Extended, "(Line " + lineNumber + ") Call failed\r\n" + e.ReasonCode + " - " + e.Reason, false);

                imlInterp.SignalCallFailure();

                if (scriptProcessor != null)
                {
                    scriptProcessor.OnCallFailed(telecomProvider, e);
                }

                //UpdateExtensionCall(e.LineNumber, CallStatus.NotOnCall, null, null);
                //UpdateExtensionCallStatus(CallStatus.NotOnCall);

                extension = null;
                callID    = Guid.Empty;

                CheckAvailability();
            }
        }
        void imlInterp_SpeakText(object sender, SpeakTextEventArgs e)
        {
            LoggingService.AddLogEntry(LogLevel.Extended, "(Line " + lineNumber + ") Speaking '" + e.TextToSpeak + "'", false);

            // If the line isn't in use, don't do anything
            if (!telecomProvider.IsLineInUse(lineNumber))
            {
                imlInterp.SignalEventCallback(e.EventToken);
                return;
            }

            try
            {
                imlScriptEventToken = e.EventToken;
                telecomProvider.SpeakText(lineNumber, e.TextToSpeak);
            }
            catch (Exception ex)
            {
                LoggingService.AddLogEntry(LogLevel.ErrorsOnly, "(Line " + lineNumber + ") Unable to speak text\r\n\r\n" + ex.Message + "\r\n" + ex.StackTrace, true);
                imlInterp.SignalEventCallback(e.EventToken);
            }
        }
        void imlInterp_ScriptFinished(object sender, EventArgs e)
        {
            try
            {
                if (telecomProvider.IsLineInUse(lineNumber))
                {
                    telecomProvider.EndCall(lineNumber);
                }
            }
            catch
            {
            }

            // Automatically unlock our line
            Locked = false;

            extension = null;
            callID    = Guid.Empty;

            LoggingService.AddLogEntry(LogLevel.Extended, "(Line " + lineNumber + ") Script finished processing", false);

            CheckAvailability();
        }
        void imlInterp_PlaySound(object sender, PlaySoundEventArgs e)
        {
            LoggingService.AddLogEntry(LogLevel.Extended, "(Line " + lineNumber + ") Playing sound at " + e.SoundFilename, false);

            // If the line isn't in use, don't do anything
            if (!telecomProvider.IsLineInUse(lineNumber))
            {
                imlInterp.SignalEventCallback(e.EventToken);
                return;
            }

            imlScriptEventToken = e.EventToken;

            try
            {
                telecomProvider.PlaySound(lineNumber, e.SoundFilename, e.Loop);
            }
            catch (Exception ex)
            {
                LoggingService.AddLogEntry(LogLevel.ErrorsOnly, "(Line " + lineNumber + ") Unable to play sound at " + e.SoundFilename, true);
                imlInterp.SignalEventCallback(e.EventToken);
            }
        }
 void imlInterp_TraceMessage(object sender, TraceEventArgs e)
 {
     LoggingService.AddLogEntry(LogLevel.Basic, "(Line " + lineNumber + ") " + e.Message, e.IsError);
 }
        void telecomProvider_CallEnded(object sender, LineEventArgs e)
        {
            if (e.LineNumber == lineNumber)
            {
                try
                {
                    LoggingService.AddLogEntry(LogLevel.Basic, "(Line " + e.LineNumber + ") Call Ended", false);

                    StopSounds(e.LineNumber);

                    // Add a call history item
                    if (Properties.Settings.Default.EnableCallHistory)
                    {
                        WOSI.CallButler.Data.CallButlerDataset.CallHistoryDataTable callHistoryTable = new WOSI.CallButler.Data.CallButlerDataset.CallHistoryDataTable();
                        WOSI.CallButler.Data.CallButlerDataset.CallHistoryRow       callHistoryItem  = callHistoryTable.NewCallHistoryRow();

                        callHistoryItem.CallDuration      = (TimeSpan)(DateTime.Now - callStartTime);
                        callHistoryItem.CallerDisplayName = imlInterp.CallerDisplayName;
                        callHistoryItem.CallerHost        = imlInterp.CallerHost;
                        callHistoryItem.CallerUsername    = imlInterp.CallerUsername;
                        callHistoryItem.ToUsername        = imlInterp.DialedUsername;
                        callHistoryItem.ToHost            = imlInterp.DialedHost;
                        callHistoryItem.CallID            = Guid.NewGuid();
                        callHistoryItem.CustomerID        = Properties.Settings.Default.CustomerID;
                        callHistoryItem.Timestamp         = callStartTime;

                        callHistoryTable.AddCallHistoryRow(callHistoryItem);

                        dataProvider.PersistCallHistory(callHistoryItem);
                    }
                }
                catch (Exception ex)
                {
                    LoggingService.AddLogEntry(LogLevel.ErrorsOnly, "(Line " + lineNumber + ") Unable to add a call history entry: " + ex.ToString(), true);
                }

                //UpdateExtensionCall(e.LineNumber, CallStatus.NotOnCall, null, null);
                //UpdateExtensionCallStatus(CallStatus.NotOnCall);

                try
                {
                    if (imlInterp == null)
                    {
                        LoggingService.AddLogEntry(LogLevel.ErrorsOnly, "**** Iml Interpreter is NULL", true);
                    }

                    imlInterp.SignalHangup();
                }
                catch (Exception ex)
                {
                    LoggingService.AddLogEntry(LogLevel.ErrorsOnly, "(Line " + lineNumber + ") Unable to signal the end of a script: " + ex.ToString(), true);
                }

                if (imlInterp.ImlScript == null)
                {
                    // Automatically unlock our line
                    Locked = false;
                }

                callID    = Guid.Empty;
                extension = null;

                CheckAvailability();
            }
        }
 void imlInterp_ScriptError(object sender, ScriptErrorEventArgs e)
 {
     LoggingService.AddLogEntry(LogLevel.ErrorsOnly, "(Line " + lineNumber + ") Script error:\r\n\r\n" + e.ErrorString, true);
 }
        void telecomProvider_CallConnected(object sender, CallEventArgs e)
        {
            if (e.LineNumber == lineNumber && scriptProcessor != null)
            {
                LoggingService.AddLogEntry(LogLevel.Basic, "(Line " + e.LineNumber + ") Call Connected", false);

                callStartTime = DateTime.Now;

                // Set our language
                imlInterp.DefaultSpeechVoice = Properties.Settings.Default.DefaultTTSVoice;
                imlInterp.SetLocalVariable("LanguageID", Properties.Settings.Default.DefaultLanguage);

                // Set our volumes
                telecomProvider.SetRecordVolume(e.LineNumber, Properties.Settings.Default.RecordVolume);
                telecomProvider.SetSoundVolume(e.LineNumber, Properties.Settings.Default.SoundVolume);
                telecomProvider.SetSpeechVolume(e.LineNumber, Properties.Settings.Default.SpeechVolume);

                // Set our call info
                imlInterp.CallerDisplayName = e.CallerDisplayName;
                imlInterp.CallerHost        = e.CallerMiscInfo;
                imlInterp.CallerUsername    = e.CallerPhoneNumber;
                imlInterp.DialedUsername    = e.CallingToNumber;
                imlInterp.DialedHost        = e.CallingToMiscInfo;

                if (autoRunScript && !imlInterp.ScriptIsRunning)
                {
                    scriptProcessor.StartProcessing(this, telecomProvider, dataProvider);
                }

                imlInterp.SignalCallConnected();

                if (scriptProcessor != null)
                {
                    scriptProcessor.OnCallConnected(telecomProvider, e);
                }

                // Check to see if this is an extension making or receiving a call. If so, update the status of the extension.
                if (Properties.Settings.Default.EnableKinesisServer && this.Extension == null)
                {
                    int extNumber = 0;

                    if (e.Outbound)
                    {
                        if (int.TryParse(e.CallingToNumber, out extNumber))
                        {
                            this.Extension = dataProvider.GetExtensionNumber(Properties.Settings.Default.CustomerID, extNumber);
                        }
                    }
                    else
                    {
                        if (int.TryParse(e.CallerPhoneNumber, out extNumber))
                        {
                            this.Extension = dataProvider.GetExtensionNumber(Properties.Settings.Default.CustomerID, extNumber);
                        }
                    }
                }

                if (callID == null)
                {
                    callID = Guid.NewGuid();
                }

                //UpdateExtensionCallStatus(CallStatus.OnCall);
                //UpdateExtensionCall(e.LineNumber, CallStatus.OnCall, e.CallerDisplayName, e.CallerPhoneNumber);
            }
        }
        public void ProcessExternalCommand(string command, string commandData, string eventToken, TelecomScriptInterface tsInterface, CallButler.Telecom.TelecomProviderBase telecomProvider, WOSI.CallButler.Data.DataProviders.CallButlerDataProviderBase dataProvider, Utilities.PluginManagement.PluginManager pluginManager, PBXRegistrarService pbxRegistrar)
        {
            // Parse out our external event action
            if (Enum.IsDefined(typeof(BaseExternalCommands), command))
            {
                BaseExternalCommands externalCommand = WOSI.Utilities.EnumUtils <BaseExternalCommands> .Parse(command);

                string languageID = "en";

                switch (externalCommand)
                {
                case BaseExternalCommands.CALLBUTLERINTERNAL_StartAddonModule:

                    CallButler.Service.Plugin.CallButlerAddonModulePlugin[] addonModules = pluginManager.GetAllPluginsOfType <CallButler.Service.Plugin.CallButlerAddonModulePlugin>();

                    foreach (CallButler.Service.Plugin.CallButlerAddonModulePlugin addonModule in addonModules)
                    {
                        if (addonModule.PluginID.ToString() == commandData)
                        {
                            try
                            {
                                // Make sure the module is licensed
                                if (!addonModule.IsLicensed)
                                {
                                    break;
                                }

                                // We found our module and we should load the script it uses
                                tsInterface.ScriptProcessor = new AddonModuleScriptProcessor(addonModule);
                                tsInterface.ScriptProcessor.StartProcessing(tsInterface, telecomProvider, dataProvider);
                                return;
                            }
                            catch (Exception e)
                            {
                                LoggingService.AddLogEntry(WOSI.CallButler.ManagementInterface.LogLevel.ErrorsOnly, "Failed to load Addon-Module '" + addonModule.PluginName + "'\r\n\r\n" + e.Message + "\r\n\r\n" + e.StackTrace, true);
                            }
                        }
                    }

                    break;

                case BaseExternalCommands.CALLBUTLERINTERNAL_ReturnToCallFlowMainMenu:

                    // Return to the Call flow main menu.
                    tsInterface.ScriptProcessor = new StandardScriptProcessor(pluginManager, pbxRegistrar);
                    ((StandardScriptProcessor)tsInterface.ScriptProcessor).StartFromMainMenu(tsInterface);

                    break;

                case BaseExternalCommands.CALLBUTLERINTERNAL_PlayLicenseIntroGreeting:

                    // If the line isn't in use, don't do anything
                    if (!telecomProvider.IsLineInUse(tsInterface.LineNumber))
                    {
                        tsInterface.IMLInterpreter.SignalEventCallback(eventToken);
                        break;
                    }

                    // Read our intro sound bytes
                    byte[] introSoundBytes = null;

                    if (telecomProvider.AudioInputRate == 8000)
                    {
                        introSoundBytes = new byte[Properties.Resources.powered_by_8khz.Length];
                        Properties.Resources.powered_by_8khz.Read(introSoundBytes, 0, introSoundBytes.Length);
                    }
                    else if (telecomProvider.AudioInputRate == 16000)
                    {
                        introSoundBytes = new byte[Properties.Resources.powered_by_16khz.Length];
                        Properties.Resources.powered_by_16khz.Read(introSoundBytes, 0, introSoundBytes.Length);
                    }

                    // Play our license intro sound
                    if (introSoundBytes != null)
                    {
                        telecomProvider.PlaySound(tsInterface.LineNumber, introSoundBytes);
                    }

                    break;

                case BaseExternalCommands.CALLBUTLERINTERNAL_PlaySystemSound:

                    // If the line isn't in use, don't do anything
                    if (!telecomProvider.IsLineInUse(tsInterface.LineNumber))
                    {
                        tsInterface.IMLInterpreter.SignalEventCallback(eventToken);
                        break;
                    }

                    // Get the sound with the current language
                    languageID = tsInterface.IMLInterpreter.GetLocalVariable("LanguageID");

                    string soundFilename = GetSoundFileForLanguage(languageID, commandData);

                    if (soundFilename == null)
                    {
                        // If we don't get a sound with the current language, try the default language
                        soundFilename = GetSoundFileForLanguage(Properties.Settings.Default.DefaultLanguage, commandData);

                        if (soundFilename == null)
                        {
                            // If we don't get a sound file with the default language, try english
                            soundFilename = GetSoundFileForLanguage("en", commandData);

                            if (soundFilename == null)
                            {
                                if (!File.Exists(soundFilename))
                                {
                                    // If the sound still doesn't exist, tell the IML interpreter to move on
                                    tsInterface.IMLInterpreter.SignalEventCallback(eventToken);
                                    break;
                                }
                            }
                        }
                    }

                    // If we get here, our system sound should exist and we should play it.
                    if (string.Compare(commandData, "ring.snd", true) == 0)
                    {
                        telecomProvider.PlaySound(tsInterface.LineNumber, soundFilename, true);
                    }
                    else
                    {
                        telecomProvider.PlaySound(tsInterface.LineNumber, soundFilename, false);
                    }

                    LoggingService.AddLogEntry(LogLevel.Extended, "(Line " + tsInterface.LineNumber + ") Playing sound at " + soundFilename, false);

                    break;

                case BaseExternalCommands.CALLBUTLERINTERNAL_PlayGreeting:

                    // If the line isn't in use, don't do anything
                    if (!telecomProvider.IsLineInUse(tsInterface.LineNumber))
                    {
                        tsInterface.IMLInterpreter.SignalEventCallback(eventToken);
                        break;
                    }

                    // Get our current language
                    languageID = tsInterface.IMLInterpreter.GetLocalVariable("LanguageID");

                    // Create our greetingID
                    Guid greetingID = new Guid(commandData);

                    // Get the greeting in our selected language
                    WOSI.CallButler.Data.CallButlerDataset.GreetingsRow greeting = dataProvider.GetGreeting(Properties.Settings.Default.CustomerID, greetingID);

                    if (greeting != null)
                    {
                        // Get the greeting for our specified language
                        WOSI.CallButler.Data.CallButlerDataset.LocalizedGreetingsRow localizedGreeting = dataProvider.GetLocalizedGreeting(Properties.Settings.Default.CustomerID, greetingID, languageID);

                        if (localizedGreeting == null)
                        {
                            // If the greeting doesn't exist in the current language, try using the default language
                            localizedGreeting = dataProvider.GetLocalizedGreeting(Properties.Settings.Default.CustomerID, greetingID, Properties.Settings.Default.DefaultLanguage);

                            if (localizedGreeting == null)
                            {
                                // If the greeting doesn't exist in the default language, heck just return the first one that exists
                                WOSI.CallButler.Data.CallButlerDataset.LocalizedGreetingsRow[] localizedGreetings = greeting.GetLocalizedGreetingsRows();

                                if (localizedGreetings.Length > 0)
                                {
                                    localizedGreeting = localizedGreetings[0];
                                }
                            }
                        }

                        if (localizedGreeting != null)
                        {
                            // Determine how we should play this greeting
                            WOSI.CallButler.Data.GreetingType greetingType = (WOSI.CallButler.Data.GreetingType)localizedGreeting.Type;

                            switch (greetingType)
                            {
                            case WOSI.CallButler.Data.GreetingType.SoundGreeting:
                                // Create our sound file path
                                string soundFilePath = WOSI.Utilities.FileUtils.GetApplicationRelativePath(Properties.Settings.Default.GreetingSoundRootDirectory) + "\\" + localizedGreeting.LanguageID + "\\" + greetingID.ToString() + ".snd";

                                if (File.Exists(soundFilePath))
                                {
                                    telecomProvider.PlaySound(tsInterface.LineNumber, soundFilePath, false);
                                    LoggingService.AddLogEntry(LogLevel.Extended, "(Line " + tsInterface.LineNumber + ") Playing sound at " + soundFilePath, false);
                                }
                                else
                                {
                                    tsInterface.IMLInterpreter.SignalEventCallback(eventToken);
                                }

                                break;

                            case WOSI.CallButler.Data.GreetingType.TextGreeting:

                                // Speak our text
                                string textToSpeak = tsInterface.IMLInterpreter.ParseVariableTokens(localizedGreeting.Data);

                                // Take out any XML
                                if (!WOSI.Utilities.StringUtils.IsWellFormedXml(textToSpeak))
                                {
                                    textToSpeak = WOSI.Utilities.StringUtils.XmlEncodeString(textToSpeak);
                                }

                                if (textToSpeak.Length > 0)
                                {
                                    if (!localizedGreeting.IsVoiceNull() && localizedGreeting.Voice.Length > 0)
                                    {
                                        textToSpeak = "<voice required=\"Name=" + localizedGreeting.Voice + "\">" + textToSpeak + "</voice>";
                                    }
                                    else if (Properties.Settings.Default.DefaultTTSVoice != null && Properties.Settings.Default.DefaultTTSVoice.Length > 0)
                                    {
                                        textToSpeak = "<voice required=\"Name=" + Properties.Settings.Default.DefaultTTSVoice + "\">" + textToSpeak + "</voice>";
                                    }

                                    telecomProvider.SpeakText(tsInterface.LineNumber, textToSpeak);
                                    LoggingService.AddLogEntry(LogLevel.Extended, "(Line " + tsInterface.LineNumber + ") Speaking '" + textToSpeak + "'", false);
                                }
                                else
                                {
                                    tsInterface.IMLInterpreter.SignalEventCallback(eventToken);
                                }

                                break;
                            }
                        }
                        else
                        {
                            // If no greeting is found in the right language, tell the interpreter to move on
                            tsInterface.IMLInterpreter.SignalEventCallback(eventToken);
                        }
                    }
                    // If the greeting isn't found, tell the interpreter to go on
                    else
                    {
                        tsInterface.IMLInterpreter.SignalEventCallback(eventToken);
                    }

                    break;
                }
            }
            else
            {
                OnExternalCommand(command, commandData, eventToken, tsInterface, telecomProvider, dataProvider);

                if (linkedScriptProcessor != null)
                {
                    linkedScriptProcessor.OnLinkedExternalCommand(command, commandData, eventToken, tsInterface, telecomProvider, dataProvider);
                }
            }
        }
 void imlInterp_LeaveConference(object sender, EventArgs e)
 {
     LoggingService.AddLogEntry(LogLevel.Extended, "(Line " + lineNumber + ") Removing line from conference", false);
     telecomProvider.RemoveLineFromConference(lineNumber);
 }