/// <inheritdoc /> protected override async Task InternalExecute(Channel incomingCallChannel, StasisStartEventArgs args) { var callerExtension = incomingCallChannel.Caller.Number; var callId = Guid.NewGuid(); var mainBridge = await InitializeMainBridge(incomingCallChannel.Id, callerExtension, callId); if (mainBridge == null) { return; } var channel = new DAL.Entities.Channel { ChannelId = incomingCallChannel.Id, Extension = callerExtension, CallId = callId, BridgeId = mainBridge, Role = ChannelRoleType.ExternalChannel }; var bNumber = incomingCallChannel.Dialplan.Exten; await _queueSender.Publish(new IncomingCallIntegrationEvent { CallId = callId, CallerExtension = callerExtension, BNumber = bNumber, }); Logger.Information($"Sent message to queue about incoming call. Caller: {callerExtension}; ChannelId: {incomingCallChannel.Id}"); await ChannelRepository.AddChannel(channel); }
/// <inheritdoc /> protected override async Task InternalExecute(Channel userChannel, StasisStartEventArgs args) { var routeData = args.RouteData; if (!routeData.FromCallId.HasValue) { Logger.Warning($"Id вызова пользователя не задан. ChannelId: {userChannel.Id}"); return; } var userExtension = routeData.FromExtension; var destinationExtension = routeData.ToExtension; var destinationChannelId = AriClient.CreateChannelId(ChannelRoleType.ExternalChannel, destinationExtension); var bridge = await AriClient.CreateBridge(); await AriClient.AddChannelToBridge(bridge.Id, userChannel.Id); var playBackId = await AriClient.PlayBeeps(userChannel.Id); var destinationCallArgs = new StasisStartEventArgs { BridgeId = bridge.Id, EventType = StasisStartEventType.CallToDestination, RouteData = routeData, PlaybackId = playBackId }; var encodedArgs = JsonSerializer.EncodeData(destinationCallArgs); var originateResult = await AriClient.Originate(encodedArgs, "Служба 112", destinationExtension, destinationChannelId); if (!originateResult) { throw new Exception("Ошибка создания канала для участника разговора, которому звонит пользователь."); } var userChannelEntity = new DAL.Entities.Channel { ChannelId = userChannel.Id, Extension = userExtension, CallId = routeData.FromCallId.Value, BridgeId = bridge.Id, Role = ChannelRoleType.Conference, LineId = routeData.LineId }; await ChannelRepository.AddChannel(userChannelEntity); var destinationChannelEntity = new DAL.Entities.Channel { ChannelId = destinationChannelId, Extension = destinationExtension, CallId = routeData.ToCallId, BridgeId = bridge.Id, Role = ChannelRoleType.RingingFromUser, LineId = routeData.LineId }; await ChannelRepository.AddChannel(destinationChannelEntity); }
/// <summary> /// Отправить событие о том, что участник разговора, который звонил в службу завершил разговор /// </summary> private async Task NotifyIfIncomingCallEnded(DAL.Entities.Channel channelEntity) { if (channelEntity.Role == ChannelRoleType.ExternalChannel) { await _queueSender.Publish(new EndCallIntegrationEvent { CallId = channelEntity.CallId }); } }
private async Task DeleteChannel(DAL.Entities.Channel channel) { if (channel.Role == ChannelRoleType.Assistant || channel.Role == ChannelRoleType.PartialAssistant || channel.Role == ChannelRoleType.SpeakSnoopChannel) { await ChannelRepository.DeleteChannel(channel.ChannelId); await HangUpAllChannelsInBridge(channel.BridgeId); return; } await ChannelRepository.DeleteChannel(channel.ChannelId); }
/// <inheritdoc /> protected override async Task InternalExecute(Channel userChannel, StasisStartEventArgs args) { Logger.Information($"AcceptIncomingCallCommand. UserChannelId: {userChannel.Id}, IncomingChannelId: {args.ChannelId}"); try { var incomingCallChannel = await ChannelRepository.GetByChannelId(args.ChannelId); if (incomingCallChannel == null) { Logger.Warning($"Канал входящего вызова не найден. UserChannelId: {userChannel.Id}"); return; } var routeData = args.RouteData; var lineId = routeData.LineId; await InitializeRecordingChannel(userChannel.Id, routeData.ToExtension, ChannelRoleType.Conference, incomingCallChannel.BridgeId, routeData.ToCallId, lineId); await AriClient.UnholdAsync(incomingCallChannel.ChannelId); await AriClient.StopMohInBridgeAsync(incomingCallChannel.BridgeId); await AriClient.AddChannelToBridge(incomingCallChannel.BridgeId, userChannel.Id); incomingCallChannel.Interrupted = false; incomingCallChannel.LineId = lineId; await ChannelRepository.UpdateChannel(incomingCallChannel); await UpdateAudioRecords(incomingCallChannel.BridgeId, incomingCallChannel.CallId, lineId); var userChannelEntity = new DAL.Entities.Channel { ChannelId = userChannel.Id, BridgeId = incomingCallChannel.BridgeId, CallId = routeData.ToCallId, Extension = routeData.ToExtension, Role = ChannelRoleType.Conference, LineId = lineId }; await ChannelRepository.AddChannel(userChannelEntity); } catch (Exception ex) { Logger.Warning("AcceptIncomingCallCommand Error", ex); } }
/// <inheritdoc /> protected override async Task InternalExecute(Channel channel, StasisStartEventArgs args) { Logger.Information($"AddToSnoopBridge. Bridge: {args.BridgeId}. Channel: {args.ChannelId}"); await AriClient.AddChannelToBridge(args.BridgeId, args.ChannelId); var channelEntity = new DAL.Entities.Channel { ChannelId = args.ChannelId, BridgeId = args.BridgeId, Role = args.EventType == StasisStartEventType.AddToSpeakSnoopBridge ? ChannelRoleType.SpeakSnoopChannel : ChannelRoleType.SnoopChannel, LineId = args.RouteData.LineId, CallId = args.RouteData.ToCallId, OriginalChannelId = args.OriginalChannelId, Extension = args.RouteData.ToExtension }; await ChannelRepository.AddChannel(channelEntity); }
private async Task ChangeMainChannel(DAL.Entities.Channel oldMainChannel, DAL.Entities.Channel assistantChannel, Guid lineId, StasisStartEventArgs args) { var channelsInLine = await ChannelRepository.GetChannelsByLineId(lineId); var assistantRole = assistantChannel.Role; var assistantBridgeId = assistantChannel.BridgeId; var mainBridgeId = oldMainChannel.BridgeId; var newMainChannelId = assistantChannel.ChannelId; var newMainChannelExtension = assistantChannel.Extension; await AriClient.AddChannelToBridge(mainBridgeId, newMainChannelId); await AriClient.AddChannelToBridge(assistantBridgeId, oldMainChannel.ChannelId); var assistantSpeakChannel = channelsInLine.SingleOrDefault(t => t.OriginalChannelId == assistantChannel.ChannelId && t.Role == ChannelRoleType.SpeakSnoopChannel); if (assistantSpeakChannel != null) { await InitializeSnoopChannel(oldMainChannel.ChannelId, oldMainChannel.Extension, assistantRole, oldMainChannel.CallId, assistantSpeakChannel.BridgeId, args, SnoopBridgeType.Speak, true); } await SnoopChannelByAllAssistantsChannels(newMainChannelId, newMainChannelExtension, ChannelRoleType.MainUser, assistantChannel.CallId, args); if (assistantRole == ChannelRoleType.PartialAssistant) { await SnoopChannelByAllAssistantsChannels(oldMainChannel.ChannelId, oldMainChannel.Extension, assistantRole, oldMainChannel.CallId, args, assistantChannel.ChannelId); } oldMainChannel.Role = assistantRole; oldMainChannel.BridgeId = assistantBridgeId; assistantChannel.Role = ChannelRoleType.MainUser; assistantChannel.BridgeId = mainBridgeId; await ChannelRepository.UpdateChannel(oldMainChannel); await ChannelRepository.UpdateChannel(assistantChannel); await HangUpOldSnoopChannels(oldMainChannel.ChannelId, channelsInLine); await HangUpOldSnoopChannels(newMainChannelId, channelsInLine); }
/// <inheritdoc /> protected override async Task InternalExecute(Channel channel, StasisStartEventArgs args) { var routeData = args.RouteData; if (!routeData.LineId.HasValue) { return; } await AriClient.Answer(channel.Id); await InitializeRecordingChannel(channel.Id, routeData.ToExtension, ChannelRoleType.Conference, args.BridgeId, routeData.ToCallId, routeData.LineId); var bridge = await AriClient.GetBridge(args.BridgeId); await AriClient.AddChannelToBridge(bridge.Id, channel.Id); await SnoopChannelByAllAssistantsChannels(channel.Id, routeData.ToExtension, ChannelRoleType.Conference, routeData.ToCallId, args); Logger.Information($"Channel added to call in conference mode. ChannelId: {channel.Id}. CallId: {routeData.ToCallId}"); var channelForIncomingCall = await ChannelRepository.GetChannelForIncomingCall(routeData.LineId.Value); if (channelForIncomingCall != null && channelForIncomingCall.Interrupted) { channelForIncomingCall.Interrupted = false; await ChannelRepository.UpdateChannel(channelForIncomingCall); } var channelEntity = new DAL.Entities.Channel { ChannelId = channel.Id, BridgeId = args.BridgeId, CallId = routeData.ToCallId, Extension = routeData.ToExtension, Role = ChannelRoleType.Conference, LineId = routeData.LineId }; await ChannelRepository.AddChannel(channelEntity); }
/// <summary> /// Создать новую пару бриджей (LISTEN/SPEAK) для ассистента/частичного ассистента и добавить туда каналы для прослушивания/разговора /// </summary> protected async Task <DAL.Entities.Channel> CreateNewAssistantBridgesAndSnoop(Channel assistantChannel, StasisStartEventArgs args, ChannelRoleType assistantRole) { var lineId = args.RouteData?.LineId; if (!lineId.HasValue) { Logger.Warning($"CallTo{assistantRole}. LineId не найден AssistantChannelId: {assistantChannel.Id}."); return(null); } var mainChannel = await ChannelRepository.GetChannelForMainUser(lineId.Value); if (mainChannel == null) { Logger.Warning($"CallTo{assistantRole}. MainChannel не найден."); return(null); } var assistantExtension = args.RouteData.ToExtension; var assistantCallId = args.RouteData.ToCallId; var prefix = assistantRole == ChannelRoleType.PartialAssistant ? "PASSISTANT" : "ASSISTANT"; var assistantBridgeId = $"{prefix}_{assistantExtension}_{assistantChannel.Id}"; var speakBridgeId = $"{assistantBridgeId}_SPEAK"; var listenBridgeId = $"{assistantBridgeId}_LISTEN"; await InitializeRecordingChannel(assistantChannel.Id, args.RouteData.ToExtension, assistantRole, mainChannel.BridgeId, assistantCallId, lineId.Value); await AriClient.CreateBridge(speakBridgeId); await AriClient.CreateBridge(listenBridgeId); await AriClient.AddChannelToBridge(listenBridgeId, assistantChannel.Id); await InitializeSnoopChannel(assistantChannel.Id, assistantExtension, assistantRole, assistantCallId, speakBridgeId, args, SnoopBridgeType.Speak, true); var channelsInLine = await ChannelRepository.GetChannelsByLineId(lineId.Value); var channelsInMainBridge = channelsInLine.Where(t => t.BridgeId == mainChannel.BridgeId).ToList(); var partialAssistantChannels = channelsInLine.Where(t => t.Role == ChannelRoleType.PartialAssistant).ToList(); foreach (var channel in channelsInMainBridge) { await InitializeSnoopChannel(channel.ChannelId, channel.Extension, channel.Role, channel.CallId, listenBridgeId, args, SnoopBridgeType.Listen); if (NeedAddChannelToSpeakBridge(channel.Role, assistantRole)) { await InitializeSnoopChannel(channel.ChannelId, channel.Extension, channel.Role, channel.CallId, speakBridgeId, args, SnoopBridgeType.Speak); } } foreach (var channel in partialAssistantChannels) { await InitializeSnoopChannel(channel.ChannelId, channel.Extension, channel.Role, channel.CallId, listenBridgeId, args, SnoopBridgeType.Listen); if (assistantRole == ChannelRoleType.PartialAssistant) { await InitializeSnoopChannel(channel.ChannelId, channel.Extension, channel.Role, channel.CallId, speakBridgeId, args, SnoopBridgeType.Speak); } } if (assistantRole == ChannelRoleType.PartialAssistant) { await SnoopChannelByAllAssistantsChannels(assistantChannel.Id, assistantExtension, assistantRole, assistantCallId, args); } var assistantChannelEntity = new DAL.Entities.Channel { ChannelId = assistantChannel.Id, Extension = assistantExtension, CallId = assistantCallId, BridgeId = listenBridgeId, Role = assistantRole, LineId = lineId.Value }; await ChannelRepository.AddChannel(assistantChannelEntity); return(assistantChannelEntity); }