/// <summary> /// Get msi channel /// </summary> /// <param name="channelName"></param> /// <returns></returns> public static ManagedChannel GetMsiChannel(string channelName) { ManagedChannel mc = null; lock (MsiChannelList) { try { for (int i = 0; i < MsiChannelList.Count; i++) { if (MsiChannelList[i].Status == ChannelStatus.Available && MsiChannelList[i].ChannelResource.DeviceName.ToLower() == channelName.ToLower()) { MsiChannelList[i].Status = ChannelStatus.Busy; mc = MsiChannelList[i]; //mc.ChannelResource.VoiceResource.Codec = Codec.PCM_8Khz_8Bit; break; } } } catch (Exception ee) { Log.WriteException(ee, "GetMsiChannel Exception"); } } // Log.Write("|MC|GetMsiChannel check the device name and route to : {0} ", mc == null ? "--No MSI Channel Available--" : mc.ChannelResource.DeviceName); return(mc); }
/// <summary> /// Disconnect server /// </summary> public void Disconnect() { lock (s_SyncVar) { s_Connected = false; if (TelephonyServer != null) { try { // stop campaign polling if (tmrGetCampaigns != null) { tmrGetCampaigns.Stop(); tmrGetCampaigns = null; } // stop agents pooling if (tmrGetAgents != null) { tmrGetAgents.Stop(); tmrGetAgents = null; } // stop running campaigns StopAllCampaigns(); // dispose all channels ManagedChannel.Dispose(); ManagedAgent.Dispose(); CampaignProcess.Dispose(); } catch { } try { CampaignAPI.DialerStoped(this.ActivityId); } catch (Exception ex) { Log.WriteException(ex, "Updating Dialer start error"); } TelephonyServer.NewCall -= new NewCall(m_TelephonyServer_NewCall); TelephonyServer.Dispose(); TelephonyServer = null; // wait for a while, Child threads release the resources Thread.Sleep(10); Log.Write("|DE|Disconnected from VE server."); } } }
/// <summary> /// Sets All channels /// </summary> /// <param name="ChannelList"></param> /// <returns></returns> public static void Initialize() { Log.Write("|MC|Initializing managed channels."); List <ChannelResource> ChannelList = null; try { ChannelList = DialerEngine.TelephonyServer.GetAllChannels(); int iMaxAllowedForAgents = Convert.ToInt32(Utilities.GetAppSetting("MaxAgentChannelCount", "2")); if (ChannelList.Count <= iMaxAllowedForAgents) { // Incorrect allocation dispose all channels DisposeChannels(ChannelList); throw new Exception("No sufficiant channels available"); } for (int i = 0; i < ChannelList.Count; i++) { Log.Write("|MC|Managed channel list adding device '{0}'", ChannelList[i].DeviceName); ManagedChannel managedChannel = new ManagedChannel(ChannelList[i]); managedChannel.Id = i + 1; if (managedChannel.Type == ChannelType.MsiChannel) { MsiChannelList.Add(managedChannel); } else if (managedChannel.Type == ChannelType.SipChannel | managedChannel.Type == ChannelType.T1Channel | managedChannel.Type == ChannelType.DigitalChannel) { OutboundChannelList.Add(managedChannel); AvailableOutboundCount++; } } } catch (Exception ee) { Log.WriteException(ee, "SetChannels Exception"); if (ChannelList != null) { DisposeChannels(ChannelList); } throw ee; } }
/// <summary> /// Get outbound channel /// </summary> /// <param name="campaignID"></param> /// <returns></returns> public static ManagedChannel GetOutboundChannel(long campaignID) { //Log.Write("|MC|GetOutboundChannel"); ManagedChannel mc = null; lock (s_SyncVar) { try { if (OutboundChannelList.Count > 0) { for (int i = 0; i < OutboundChannelList.Count; i++) { if (OutboundChannelList[i].Status == ChannelStatus.Available) { AvailableOutboundCount--; OutboundChannelList[i].Status = ChannelStatus.Busy; mc = OutboundChannelList[i]; mc.ChannelResource.VoiceResource.Codec = Codec.MULAW_8Khz_8Bit; break; } } // increment the count for this campaign if (mc != null && campaignID > 0) { int count = 1; if (dCampaignChannelCount.ContainsKey(campaignID)) { count = dCampaignChannelCount[campaignID]; count++; dCampaignChannelCount.Remove(campaignID); } dCampaignChannelCount.Add(campaignID, count); } } } catch (Exception ee) { Log.WriteException(ee, "GetChannel Exception"); } } return(mc); }
/// <summary> /// Entry point for campaign process /// </summary> public void Start() { // This is the main application entry point when the dialer is started ** try { if (TelephonyServer != null) { try { CampaignAPI.DialerStarted(this.ActivityId); } catch (Exception ex) { Log.WriteException(ex, "Updating Dialer start error"); } // Added GW 10.01.10 to reset any campaigns that somehow locked into run or paused states. CampaignAPI.ResetCampaignsToIdle(); try { ManagedChannel.Initialize(); } catch (Exception ex) { Log.WriteException(ex, "Channels are not allocated properly please check"); Disconnect(); return; } GetLoggodInAgents(); tmrGetAgents = new System.Windows.Forms.Timer(); tmrGetAgents.Tick += new EventHandler(Timer_GetAgents); tmrGetAgents.Interval = Convert.ToInt32( Utilities.GetAppSetting("AgentPollingInterval", "10000")); tmrGetAgents.Enabled = true; GetCampaigns(); tmrGetCampaigns = new System.Windows.Forms.Timer(); tmrGetCampaigns.Tick += new EventHandler(Timer_GetCampaigns); tmrGetCampaigns.Interval = Convert.ToInt32( Utilities.GetAppSetting("CampaignPollingInterval", "10000")); tmrGetCampaigns.Enabled = true; // Added for support of PromptRecorder GetAdminRequests(); tmrGetAdminRequests = new System.Windows.Forms.Timer(); tmrGetAdminRequests.Tick += new EventHandler(Timer_GetAdminRequests); tmrGetAdminRequests.Interval = Convert.ToInt32( Utilities.GetAppSetting("AdminPollingInterval", "10000")); tmrGetAdminRequests.Enabled = true; Log.Write("|DE|Admin timer interval set to {0}.", tmrGetAdminRequests.Interval); } else { Log.Write(""); Log.Write("|DE|Not Connected to VE server."); } } catch (Exception ex) { Log.WriteException(ex, "Error in Start"); } }
public void RunScript() { try { if (string.IsNullOrEmpty(m_RecordPath) || string.IsNullOrEmpty(m_PromptPath)) { Log.Write("Error in prompt recorder: invalid or missing paths to play or record. Aborting."); return; } if (m_NumberToCall.Length < 7) { Log.Write("Invalid number to call for prompt recording:{0}. Aborting.", m_NumberToCall); return; } // *** Looks like it will give a channel with campaign = 0, but confirm ManagedChannel = ManagedChannel.GetOutboundChannel(0); if (ManagedChannel == null || ManagedChannel.ChannelResource == null) { // Channels not available, prior checking also implemented this will not happen Log.Write("No channels available, recorder thread has been started without a channel."); return; } // Subscribe to hangup events try { ManagedChannel.ChannelResource.Disconnected -= new Disconnected(ChannelResource_Disconnected); } catch { } ManagedChannel.ChannelResource.Disconnected += new Disconnected(ChannelResource_Disconnected); // No CPA, only wait for connect ManagedChannel.ChannelResource.CallProgress = CallProgress.WaitForConnect; if (ManagedChannel.ChannelResource is T1Channel) // For t1, route to self { ManagedChannel.ChannelResource.RouteFull(ManagedChannel.ChannelResource.VoiceResource); } DialResult dr; ManagedChannel.ChannelResource.CallProgressTemplate = @"Dialogic\DxCap"; Dictionary <string, int> overrides = new Dictionary <string, int>(); overrides.Add("ca_noanswer", 3600); ManagedChannel.ChannelResource.CallProgressOverrides = overrides; Log.WriteWithId(ManagedChannel.Id.ToString(), "Recorder Dialing {0} on channel {1}.", m_NumberToCall, ManagedChannel.ChannelResource.DeviceName); try { lock (this) { isDialing = true; } dr = ManagedChannel.ChannelResource.Dial(m_NumberToCall); lock (this) { isDialing = false; } } catch (Exception ex) { Log.WriteException(ex, "Recorder - General dialing exception."); dr = DialResult.Failed; } finally { ManagedChannel.ChannelResource.CallProgress = CallProgress.WaitForConnect; } // Log dial result Log.WriteWithId(ManagedChannel.Id.ToString(), "The recorder dial result for {0} was: {1}.", m_NumberToCall, dr); switch (dr) { case DialResult.Connected: case DialResult.HumanDetected: case DialResult.Successful: case DialResult.MachineDetected: RecordPrompts(); break; case DialResult.NoAnswer: case DialResult.Busy: case DialResult.Error: case DialResult.Failed: case DialResult.OperatorIntercept: default: // call failed no answer Log.WriteWithId(ManagedChannel.Id.ToString(), "Recorder call failed with dial result: '{0}'", dr); break; } return; } catch (ElementsException ee) { // These are Telephony Specific exceptions, such an the caller hanging up the phone during a play or record. if (ee is HangupException) { Log.Write("The Recorder Hungup."); } else { Log.WriteException(ee, "Recorder Elements Exception"); } } catch (Exception ex) { Log.WriteException(ex, "Error in prompt recorder main script"); } finally { if (ManagedChannel != null) { try { if (isDialing) { try { ManagedChannel.ChannelResource.StopDial(); } catch { } isDialing = false; } if (ManagedChannel.ChannelResource != null) { ManagedChannel.ChannelResource.Disconnect(); ManagedChannel.ChannelResource.Disconnected -= new Disconnected(ChannelResource_Disconnected); // Route to Home VR. ManagedChannel.ChannelResource.RouteFull(ManagedChannel.ChannelResource.VoiceResource); } } catch { } // Add channel back to the list for later use // 0 as camp ID looks ok once again, testing will show. ManagedChannel.ReturnChannel(ManagedChannel, 0); } } }
/// <summary> /// Return channel back to available list /// </summary> /// <param name="mc"></param> /// <param name="campaignID"></param> public static void ReturnChannel(ManagedChannel mc, long campaignID) { Log.Write("|MC|0|Returning channel '{1}' to available channel pool.", campaignID, mc.ChannelResource.DeviceName); mc.Connected = false; lock (s_SyncVar) { try { try { if (mc.ChannelResource != null) { mc.ChannelResource.Disconnect(); } } catch { } if (mc.type != ChannelType.MsiChannel) { for (int i = 0; i < OutboundChannelList.Count; i++) { if (OutboundChannelList[i].Id == mc.Id) { OutboundChannelList[i].Status = ChannelStatus.Available; AvailableOutboundCount++; // decrement the count for this campaign if (campaignID > 0) { int iCount = 0; if (dCampaignChannelCount.ContainsKey(campaignID)) { iCount = dCampaignChannelCount[campaignID]; iCount--; dCampaignChannelCount.Remove(campaignID); } dCampaignChannelCount.Add(campaignID, iCount); } return; } } } else { for (int i = 0; i < MsiChannelList.Count; i++) { if (MsiChannelList[i].Id == mc.Id) { MsiChannelList[i].Status = ChannelStatus.Available; return; } } } } catch (Exception ee) { Log.WriteException(ee, "ReturnChannel Exception"); } } }
/// <summary> /// New call event for channel /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void ChannelResource_NewCall(object sender, NewCallEventArgs e) { if (e.ChannelResource is MsiChannel) { Log.Write("|MC|Msi {0} went off hook", e.ChannelResource.DeviceName); // Start something here to managed an off hook agent... //Check if the agent is logged in or not and play message //to agent to Login else add to off hook list ManagedAgent ma = ManagedAgent.CheckAgentLoggedIn(e.ChannelResource.DeviceName); ManagedChannel mc = null; if (ma != null) { if (!ma.AgentDetails.AllwaysOffHook) { foreach (ManagedChannel mc2 in ManagedChannel.MsiChannelList) { if (mc2.ChannelResource.Equals(e.ChannelResource)) { mc = mc2; break; } } if (mc == null) { Log.Write("|MC|ChannelResource_NewCall unable to locate channel."); } else { ma.InboundAgent(mc); } } else { Log.Write("|MC|ChannelResource_NewCall AllwaysOffHook agent with station-{0}", e.ChannelResource.DeviceName); } } else { try { // VoiceResource on MSIChannel, // e.ChannelResource.VoiceResource.PlayTTS("Please Login"); } finally { e.ChannelResource.Disconnect(); } } } else { // Handle new call event try { Log.Write("|MC|{0} NewCall. Answering.", e.ChannelResource.DeviceName); // MONROE e.ChannelResource.Answer(); Log.Write("|MC|{0} Playing Good Bye Message.", e.ChannelResource.DeviceName); e.ChannelResource.VoiceResource.Play(@"AudioFiles\Goodbye.wav"); } finally { Log.Write("|MC|{0} Disconnecting.", e.ChannelResource.DeviceName); e.ChannelResource.Disconnect(); } } }