【问题标题】:Identifying the call that is connected to me via transfer Tapi3识别通过转接 Tapi3 连接到我的呼叫
【发布时间】:2018-02-13 15:41:00
【问题描述】:

我已经能够创建一个应用程序,该应用程序 (ab) 使用 TAPI3Lib 并了解来电,将它们置于保持状态,拨打内部号码,将保持状态的线路连接到目标号码。

下面是获取来电号码的代码

     private void tapi_ITTAPIEventNotification_Event_Event(TAPI3Lib.TAPI_EVENT TapiEvent, object pEvent)
     {
        try
        {

            switch (TapiEvent)
            {
                case TAPI3Lib.TAPI_EVENT.TE_CALLNOTIFICATION:
                    TAPI3Lib.ITCallNotificationEvent cln = pEvent as TAPI3Lib.ITCallNotificationEvent;
                    if (cln.Call.CallState == TAPI3Lib.CALL_STATE.CS_OFFERING)
                    {
                        string c = cln.Call.get_CallInfoString(TAPI3Lib.CALLINFO_STRING.CIS_CALLERIDNUMBER);
                        string target = cln.Call.Address.DialableAddress;
                    .
                    .
                    .

在这里,我对数据库运行 MSSQL 查询,以确定谁是号码的所有者。我在屏幕上显示一个表格,显示正在呼叫的潜在用户。表单上的按钮可让您拨打内部号码(此操作会自动添加当前线路保持状态。

    IEnumCall ec = ia[line].EnumerateCalls();
        uint arg = 0;
        ITCallInfo ici;

        try
        {
            ec.Next(1, out ici, ref arg);
            ITBasicCallControl bc = (ITBasicCallControl)ici;
            bc.Hold(true);

        }
        catch (Exception exp)
        {
            System.Windows.Forms.MessageBox.Show("May not have any call to put on hold!\n\n" + exp.ToString(), "TAPI3");
        }

        IEnumCall ec1 = ia[line].EnumerateCalls();
        uint arg1 = 0;
        ITCallInfo ici1;

        try
        {
            ec1.Next(1, out ici1, ref arg1);
            ITBasicCallControl bc1 = ia[line].CreateCall("107",TapiConstants.LINEADDRESSTYPE_IPADDRESS, TapiConstants.TAPIMEDIATYPE_AUDIO);
            bc1.Connect(false);


        }
        catch (Exception exp)
        {
            System.Windows.Forms.MessageBox.Show("Target looks unreachable!\n\n" + exp.ToString(), "TAPI3");
        }

这部分连接当前活动线路和保持线路;

    ITBasicCallControl callOnHold = null;
        ITBasicCallControl callConnected = null;
        IEnumCall enumCall = ia[line].EnumerateCalls();
        ITCallInfo callInfo;
        uint dummy = 0;
        while (true)
        {
            enumCall.Next(1, out callInfo, ref dummy);
            if (callInfo == null)
                return;
            if (callInfo.CallState == CALL_STATE.CS_HOLD)
                callOnHold = (ITBasicCallControl)callInfo;
            else if (callInfo.CallState == CALL_STATE.CS_CONNECTED)
                callConnected = (ITBasicCallControl)callInfo;
            if (callOnHold != null && callConnected != null)
                break;
        }

        callOnHold.Transfer(callConnected, true); 
        callConnected.Finish(FINISH_MODE.FM_ASTRANSFER);

启蒙如下;

    ITAddress[] ia = new TAPI3Lib.ITAddress[10]; 
    ...
    try
        {
            tobj = new TAPIClass();
            tobj.Initialize();
            IEnumAddress ea = tobj.EnumerateAddresses();
            ITAddress ln;
            uint arg3 = 0;
            lines = 0;

            cn = new callnotification();

            tobj.ITTAPIEventNotification_Event_Event += new TAPI3Lib.ITTAPIEventNotification_EventEventHandler(cn.Event);
            tobj.EventFilter = (int)(TAPI_EVENT.TE_CALLNOTIFICATION |
                TAPI_EVENT.TE_DIGITEVENT |
                TAPI_EVENT.TE_PHONEEVENT |
                TAPI_EVENT.TE_CALLSTATE |
                TAPI_EVENT.TE_GENERATEEVENT |
                TAPI_EVENT.TE_GATHERDIGITS |
                TAPI_EVENT.TE_REQUEST);

            for (int i = 0; i < 10; i++)
            {
                ea.Next(1, out ln, ref arg3);
                ia[i] = ln;
                if (ln != null)
                {
                   lines++;
                }
                else
                    break;
            }
        }
        catch (Exception e)
        {
            System.Windows.Forms.MessageBox.Show(e.ToString());
        }

--场景

CallA:来电

CallB:内部调用

接线员:主要接听接线员

Bob:此应用程序的用户

Alice:CallA的调用者

Bob 用他的手机拨打 Alice 的呼叫中心。 接线员看到一个包含Bob的姓名和号码的弹出屏幕,然后拿起电话。 (CallA 已存储)。 Bob 请求与 Alice 交谈。 接线员点击屏幕上的“Alice”(CallA现在处于保持状态,接线员的电话创建 CallB,它会拨打 Alice 的电话)。 Alice 接听电话并同意接听电话。 接线员点击屏幕上的“转接”,CallACallB连接。

--场景结束

--预期结果

Operator 呼叫 Alice 时,事件会看到 100 呼叫 107(其中 100 是 Operator 在 PBX 上的地址, 107 Alice的。当Operator连接两个通话时,我希望能够弹出与Operator相同的屏幕其中包括已连接呼叫者的信息。为了触发该事件,我错过了什么?因为当我尝试检查 cln.Call.get_CallInfoString(TAPI3Lib.CALLINFO_STRING.CIS_CALLERIDNUMBER) 时,我看到的只是 100,即调用 Operator >爱丽丝,这是正确的。我需要做什么检查才能确定呼叫已被转移→获取来电显示→弹出屏幕

--预期结果结束

我希望我能够按照我的想法描述它。感谢您抽出宝贵时间,请原谅我的冗长帖子。

【问题讨论】:

    标签: c# pbx tapi


    【解决方案1】:

    TAPI3 库的命名可能略有不同,但您要查找的字段在 TAPI 本身上称为 ConnectedId、RedirectingId 和 RedirectionId。 但是这些字段是否填满,很大程度上取决于 PBX 本身。

    在“理论上”的转移呼叫场景中,您应该在呼叫信息中看到这一点:

    • 呼叫者 ID:原始呼叫的来源(= 客户)
    • 被叫 id:原始呼叫的目的地(= 公司或服务的公开号码)
    • connected id:当前的实际对方(=您正在与之交谈的人)
    • redirecting id:将呼叫转接给您的号码(=话务员分机)
    • redirection id:重定向方(=运营商)将呼叫转移到的号码,“应该”是您从中观察的设备(如果不涉及进一步的转发)

    但是 TAPI 没有强制执行这些,因此 PBX 可以填写它想要的内容,并且不同的供应商会:(

    【讨论】:

    • 问题是,当我接到接线员的电话时,REDIRECTIONID 为空,因为该线路尚未重定向到我。如果我在接听接线员的电话并转移线路后添加断点,REDIRECTIONID 会按照您的建议保留客户号码,但接线员单击“转移”不会触发 Tapi Events 的呼叫提供。话务员拨打我的电话时会触发通话服务。
    【解决方案2】:

    按照 Kris Vanherck 的建议,我采取了临时措施来处理转移,直到我们找到合适的解决方案;

         string con="000";
                                while (con.Length ==3 && con.Length >=3)
                                {
    
                                    con = cln.Call.get_CallInfoString(TAPI3Lib.CALLINFO_STRING.CIS_CONNECTEDIDNUMBER);
                                }
    

    愚蠢的做法,但嘿,它的工作原理。迫不及待地想看到更合适的方法来做到这一点。再次感谢 Kris 的指导。

    【讨论】:

      【解决方案3】:

      你对自己太苛刻了。您无需手动调用 Hold,Transfer 方法为您完成。

      当有来自 B 的新来电 (TAPI_EVENT.TE_CALLNOTIFICATION) 时,您可以使用其 ITBasicCallControl 拨打 Transfer

      case TAPI_EVENT.TE_CALLNOTIFICATION:
        ITBasicCallControl incomingCall = callNotification.Call;
        break;
      

      Transfer 方法采用指向新创建的咨询呼叫的指针,因此请确保您事先创建了一个新呼叫:

      //In this case address is of type ITAddress and represents the operators address.
      ITBasicCallControl consultationCall = address.CreateCall("107", TapiConstants.LINEADDRESSTYPE_PHONENUMBER, TapiConstants.TAPIMEDIATYPE_AUDIO);
      

      现在您可以拨打转接电话了:

      incomingCall.Transfer(consultationCall, false);
      

      最后,当咨询电话断开,Alice想接听电话时,使用Finish方法完成转接:

      case CALL_STATE.CS_DISCONNECTED:
        ITBasicCallControl consultationCall = (ITBasicCallControl )callStateEvent.Call;
        consultationCall.Finish(FINISH_MODE.FM_ASTRANSFER);
        break;
      

      【讨论】:

      • 是的,这是另一种方法。问题是,我可能需要打电话,也许回复的人无法接听处于保留状态的电话,我将不得不再次拨打咨询电话给其他人。所以 Disconnected 事件可能会让它有点奇怪,不是吗?没有把握。我可以试试,让你知道!谢谢你的时间:)
      • ITCallStateEvent 有一个CALL_STATE_EVENT_CAUSE 属性,它将告诉您断开连接事件发生的原因。 CEC_DISCONNECT_NOANSWER 是您正在寻找的那个,但我认为,根据您的 PBX,CALL_STATE_EVENT_CAUSE 可能设置不正确。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多