IncomingNotificationHandler.cs 9.2 KB

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