/// <summary> /// Начать запись разговора /// </summary> protected async Task StartCallRecording(string initialChannelId, Guid initialCallId, string extension, ChannelRoleType role, string mainBridgeId, Guid?lineId = null) { if (!_asteriskOptions.RecordingEnabled) { return; } var recordsBridgeId = GetCommonRecordingBridgeId(mainBridgeId); var fullAudioRecord = new AudioRecord { FileName = $"{recordsBridgeId}", LineId = lineId, CallId = null }; await AudioRecordRepository.AddAudioRecord(fullAudioRecord); await AriClient.CreateBridge(recordsBridgeId); await AddChannelToCommonRecordingBridge(initialChannelId, extension, role, mainBridgeId, initialCallId, lineId); var result = await AriClient.StartRecordingBridge(recordsBridgeId); if (result.IsFailure) { Logger.Warning($"StartCallRecording. Failed to start call recording. MainBridgeId: {mainBridgeId}"); return; } await CreateSnoopChannelForRecording(initialChannelId, extension, role, false, initialCallId, lineId); Logger.Information($"StartRecordingBridge. Bridge recording started. {mainBridgeId}"); }
/// <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 <string> InitializeMainBridge(string channelId, string callerExtension, Guid initialCallId) { try { await AriClient.Answer(channelId); var mainBridge = await AriClient.CreateBridge(); await AriClient.AddChannelToBridge(mainBridge.Id, channelId); await StartCallRecording(channelId, initialCallId, callerExtension, ChannelRoleType.ExternalChannel, mainBridge.Id); await AriClient.StartMohInBridgeAsync(mainBridge.Id); Logger.Information($"InitializeMainBridge. Channel {channelId} added to bridge {mainBridge.Id}"); return(mainBridge.Id); } catch (Exception ex) { Logger.Warning($"InitializeMainBridge Error. {ex.Message}.", ex); return(null); } }
/// <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); }