IncomingNotificationHandler.cs 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. using Hotline.Caching.Interfaces;
  2. using Hotline.CallCenter.Calls;
  3. using Hotline.CallCenter.Devices;
  4. using Hotline.CallCenter.Ivrs;
  5. using Hotline.Realtimes;
  6. using Hotline.Settings;
  7. using Hotline.Share.Enums.CallCenter;
  8. using Hotline.Share.Notifications;
  9. using MediatR;
  10. using Microsoft.Extensions.Logging;
  11. using Microsoft.Extensions.Options;
  12. using NewRock.Sdk;
  13. using NewRock.Sdk.Transfer.Connect.Request;
  14. using NewRock.Sdk.Transfer.Queue.Request;
  15. using Oracle.ManagedDataAccess.Types;
  16. using XF.Domain.Cache;
  17. using XF.Domain.Constants;
  18. using XF.Domain.Exceptions;
  19. namespace Hotline.Application.Handlers.CallCenter.FlowControl
  20. {
  21. public class IncomingNotificationHandler : INotificationHandler<IncomingNotification>
  22. {
  23. private readonly ICallRepository _callRepository;
  24. private readonly ICallDetailRepository _callDetailRepository;
  25. private readonly ISystemSettingCacheManager _systemSettingCacheManager;
  26. private readonly IIvrCacheManager _ivrCacheManager;
  27. private readonly INewRockClient _newRockClient;
  28. private readonly IOptionsSnapshot<CallCenterConfiguration> _options;
  29. private readonly ITypedCache<List<TrunkIvrManager>> _worktimeCache;
  30. private readonly ILogger<IncomingNotificationHandler> _logger;
  31. private readonly ITrunkIvrManagerRepository _trunkIvrManagerRepository;
  32. private readonly ICallCacheManager _callCacheManager;
  33. private readonly IRealtimeService _realtimeService;
  34. public IncomingNotificationHandler(
  35. ICallRepository callRepository,
  36. ICallDetailRepository callDetailRepository,
  37. ISystemSettingCacheManager systemSettingCacheManager,
  38. IIvrCacheManager ivrCacheManager,
  39. INewRockClient newRockClient,
  40. IOptionsSnapshot<CallCenterConfiguration> options,
  41. ITypedCache<List<TrunkIvrManager>> worktimeCache,
  42. ILogger<IncomingNotificationHandler> logger,
  43. ITrunkIvrManagerRepository trunkIvrManagerRepository,
  44. ICallCacheManager callCacheManager,
  45. IRealtimeService realtimeService)
  46. {
  47. _callRepository = callRepository;
  48. _callDetailRepository = callDetailRepository;
  49. _systemSettingCacheManager = systemSettingCacheManager;
  50. _ivrCacheManager = ivrCacheManager;
  51. _newRockClient = newRockClient;
  52. _options = options;
  53. _worktimeCache = worktimeCache;
  54. _logger = logger;
  55. _trunkIvrManagerRepository = trunkIvrManagerRepository;
  56. _callCacheManager = callCacheManager;
  57. _realtimeService = realtimeService;
  58. }
  59. public async Task Handle(IncomingNotification notification, CancellationToken cancellationToken)
  60. {
  61. var model = await _callRepository.GetAsync(
  62. x => x.ConversationId == notification.Visitor.Id && x.Trunk == notification.TrunkId &&
  63. x.FromNo == notification.Visitor.From && x.CreationTime >= DateTime.Now.AddHours(-2), true, x => x.CreationTime, cancellationToken);
  64. if (model != null)
  65. {
  66. model.CallStatus = ECallStatus.Incoming;
  67. await _callRepository.UpdateAsync(model, cancellationToken);
  68. var detail = new CallDetail()
  69. {
  70. CallId = model.Id,
  71. CallStatus = ECallStatus.Incoming,
  72. OMCallId = notification.Visitor.CallId,
  73. ConversationId = notification.Visitor.Id,
  74. EventName = notification.Attribute,
  75. FromNo = notification.Visitor.From,
  76. ToNo = notification.Visitor.To,
  77. };
  78. await _callDetailRepository.AddAsync(detail, cancellationToken);
  79. //TODO IVR处理
  80. var setting = _systemSettingCacheManager.GetSetting(SettingConstants.IVRConfig);
  81. if (bool.Parse(setting.SettingValue))
  82. {
  83. var correct = GetCorrectIvr(notification.Visitor.To);
  84. //var ivr = GetCorrectIvr();
  85. switch (correct.eCorrectIvr)
  86. {
  87. case ECorrectIvr.Ivr:
  88. var ivrList = await _ivrCacheManager.GetIvrsAsync(cancellationToken);
  89. if (!ivrList.Any())
  90. throw new UserFriendlyException("未查到任何ivr配置");
  91. var ivr = ivrList.First(x => x.IvrCategoryId == correct.ReturnValue && x.IsRoot);
  92. _logger.LogInformation("transfer to ivr.no: {ivrNo}", ivr.No);
  93. await _newRockClient.VisitorToMenu(
  94. new VisitorToMenuRequest()
  95. {
  96. Attribute = "Connect",
  97. Menu = new VisitorToMenuMenu() { Id = ivr.No },
  98. Visitor = new VisitorToMenuVisitor() { Id = notification.Visitor.Id }
  99. },
  100. _options.Value.DeviceConfigs.ReceiveKey, _options.Value.DeviceConfigs.Expired, cancellationToken);
  101. //写入进入IVR流程
  102. model.InIvrTime = DateTime.Now;
  103. await _callRepository.UpdateAsync(model, cancellationToken);
  104. var detailTwo = new CallDetail()
  105. {
  106. CallId = model.Id,
  107. CallStatus = ECallStatus.InIvr,
  108. OMCallId = notification.Visitor.CallId,
  109. ConversationId = notification.Visitor.Id,
  110. EventName = notification.Attribute,
  111. FromNo = notification.Visitor.From,
  112. ToNo = notification.Visitor.To,
  113. };
  114. await _callDetailRepository.AddAsync(detail, cancellationToken);
  115. break;
  116. case ECorrectIvr.Group:
  117. _logger.LogInformation("transfer to group.no:{groupNo}", correct.ReturnValue);
  118. await _newRockClient.VisitorToGroupQueue(new VisitorToGroupQueueRequest()
  119. {
  120. Attribute = "Queue",
  121. Visitor = new VisitorToGroupQueueVisitor() { Id = notification.Visitor.Id },
  122. Group = new VisitorToGroupQueueGroup() { Id = correct.ReturnValue }
  123. },
  124. _options.Value.DeviceConfigs.ReceiveKey, _options.Value.DeviceConfigs.Expired, cancellationToken);
  125. model.InQueueTime = DateTime.Now;
  126. await _callRepository.UpdateAsync(model, cancellationToken);
  127. //处理队列记录
  128. _callCacheManager.AddCallCache(model);
  129. await _realtimeService.CallQueueAsync(_callCacheManager.GetCallQueueList(), cancellationToken);
  130. break;
  131. default:
  132. //TODO 跳转默认分机组
  133. break;
  134. }
  135. }
  136. else
  137. {
  138. //TODO 跳转默认分机组
  139. }
  140. }
  141. }
  142. private CorrectIvr GetCorrectIvr(string to)
  143. {
  144. var worktimeSettings = _worktimeCache.GetOrSet("worktimesettings", d =>
  145. {
  146. var settings = _trunkIvrManagerRepository.QueryAsync(x => x.IsEnable).GetAwaiter().GetResult();
  147. return settings;
  148. });
  149. var correct = GetCorrectCategory(worktimeSettings.First(x => x.TrunkId == to));
  150. return correct;
  151. }
  152. public class CorrectIvr
  153. {
  154. public string ReturnValue { get; set; }
  155. public ECorrectIvr eCorrectIvr { get; set; }
  156. }
  157. private CorrectIvr GetCorrectCategory(TrunkIvrManager settings)
  158. {
  159. if (!settings.WorkDay.Any(x => x.weekValue == ((int)DateTime.Now.DayOfWeek).ToString()))
  160. return new CorrectIvr() { eCorrectIvr = settings.RestCategory != "" ? ECorrectIvr.Ivr : ECorrectIvr.Group, ReturnValue = settings.RestCategory != "" ? settings.RestCategory : settings.RestToGroup };
  161. var time = TimeOnly.FromDateTime(DateTime.Now);
  162. if ((time >= TimeOnly.Parse(settings.MorningBegin) && time <= TimeOnly.Parse(settings.MorningEnd))
  163. || (time >= TimeOnly.Parse(settings.AfterBegin) && time <= TimeOnly.Parse(settings.AfterEnd))
  164. )
  165. {
  166. return new CorrectIvr() { eCorrectIvr = settings.WorkCategory != "" ? ECorrectIvr.Ivr : ECorrectIvr.Group, ReturnValue = settings.WorkCategory != "" ? settings.WorkCategory : settings.WorkToGroup };
  167. }
  168. else
  169. {
  170. return new CorrectIvr() { eCorrectIvr = settings.RestCategory != "" ? ECorrectIvr.Ivr : ECorrectIvr.Group, ReturnValue = settings.RestCategory != "" ? settings.RestCategory : settings.RestToGroup };
  171. }
  172. }
  173. }
  174. }