コード例 #1
0
ファイル: AcdTransfer.cs プロジェクト: wasabii/UcmaKit
        public override async Task<AcdActionResult> Execute(LocalEndpoint localEndpoint, AudioVideoCall call, CancellationToken cancellationToken)
        {
            if (Endpoint == null)
                return AcdActionResult.Continue;

            // extract information from incoming caller
            var callParticipant = call.RemoteEndpoint.Participant;
            var callAddress = new RealTimeAddress(callParticipant.Uri, localEndpoint.DefaultDomain, localEndpoint.PhoneContext);
            var callSipUri = new SipUriParser(callAddress.Uri);
            callSipUri.RemoveParameter(new SipUriParameter("user", "phone"));
            var callUri = callSipUri.ToString();
            var callPhoneUri = callParticipant.OtherPhoneUri;
            var callName = callParticipant.DisplayName;

            // impersonate incoming caller to agent
            var remoteConversation = new Conversation(localEndpoint);
            remoteConversation.Impersonate(callUri, callPhoneUri, callName);

            // establish call to endpoint
            var remoteCall = new AudioVideoCall(remoteConversation);
            var remoteOpts = new CallEstablishOptions();
            remoteOpts.Transferor = localEndpoint.OwnerUri;
            remoteOpts.Headers.Add(new SignalingHeader("Ms-Target-Class", "secondary"));

            // initiate call with duration
            var destCallT = remoteCall.EstablishAsync(Endpoint.Uri, remoteOpts, cancellationToken);

            try
            {
                // wait for agent call to complete
                await destCallT;
            }
            catch (OperationCanceledException)
            {
                // ignore
            }
            catch (RealTimeException)
            {
                // ignore
            }

            // ensure two accepted transfers cannot both complete
            using (var lck = await call.GetContext<AsyncLock>().LockAsync())
                if (call.State == CallState.Established)
                    if (remoteCall.State == CallState.Established)
                    {
                        var participant = remoteConversation.RemoteParticipants.FirstOrDefault();
                        if (participant != null)
                        {
                            var endpoint = participant.GetEndpoints().FirstOrDefault(i => i.EndpointType == EndpointType.User);
                            if (endpoint != null)
                            {
                                var ctx = new ConversationContextChannel(remoteConversation, endpoint);

                                // establish conversation context with application
                                await ctx.EstablishAsync(
                                    new Guid("FA44026B-CC48-42DA-AAA8-B849BCB43A21"), 
                                    new ConversationContextChannelEstablishOptions());

                                // send context data
                                await ctx.SendDataAsync(
                                    new ContentType("text/plain"), 
                                    Encoding.UTF8.GetBytes("Id=123"));
                            }
                        }

                        return await TransferAsync(call, remoteCall);
                    }

            // terminate outbound call if still available
            if (remoteCall.State != CallState.Terminating &&
                remoteCall.State != CallState.Terminated)
                await remoteCall.TerminateAsync();

            // we could not complete the transfer attempt
            return AcdActionResult.Continue;
        }