IncomingNotificationHandler.cs 9.3 KB

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