识别通过转接 Tapi3 连接到我的呼叫

Identifying the call that is connected to me via transfer Tapi3

我已经能够创建一个应用程序(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 使用他的手机phone 呼叫Alice 的呼叫中心。 接线员 看到一个弹出屏幕,其中包含 Bob 的姓名和号码,然后拿起 phone。 (CallA 已存储)。 Bob 请求与 Alice 交谈。 Operator 点击屏幕上的“Alice”(CallA 现在处于等待状态并且 Operator 的 phone 创建了 CallB 并响铃 Alice 的 phone)。 Alice 接听电话并同意接听电话。 接线员 在屏幕上单击 "Transfer",CallACallB 已连接。

--场景结束

--预期结果

Operator 调用 Alice 时,事件发现 100 调用了 107(100 是 Operator 在 PBX 上的地址和 107 Alice 的地址。当 Operator 连接这两个电话时,我希望能够弹出与 Operator 相同的屏幕,其中包括已连接呼叫者的信息。为了触发该事件,我缺少什么?因为当我尝试检查 cln.Call.get_CallInfoString(TAPI3Lib.CALLINFO_STRING.CIS_CALLERIDNUMBER) 我只看到 100,它是调用 AliceOperator,这是正确的。为了识别来电已转接→获取来电显示→弹屏

--预期结果结束

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

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

在呼叫转移的情况下"theoretically"您应该在呼叫信息中看到:

  • 来电显示:原始呼叫的来源(=客户)
  • 被叫号码:原始呼叫的目的地(=公司或服务的公布号码)
  • connected id: 实际的当前对方(=你正在和谁通话)
  • 重定向 ID:将呼叫转移给您的号码(= 接线员分机)
  • 重定向 ID:重定向方(= 运营商)将呼叫转移到的号码,"should" 是您从中观察到此消息的设备(如果不涉及进一步的转发)

但是 none 这由 TAPI 强制执行,因此 PBX 可以填写它想要的内容,不同的供应商将:(

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

     string con="000";
                            while (con.Length ==3 && con.Length >=3)
                            {

                                con = cln.Call.get_CallInfoString(TAPI3Lib.CALLINFO_STRING.CIS_CONNECTEDIDNUMBER);
                            }

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

你太难为自己了。您不需要手动调用 Hold,Transfer 方法会为您完成。

当 B 的新电话打进来时 (TAPI_EVENT.TE_CALLNOTIFICATION),您可以使用它的 ITBasicCallControl 拨打 Transfer on:

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;