DeviceEventHandler.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. using System.Security.Authentication;
  2. using CallCenter.Devices;
  3. using CallCenter.Notifications;
  4. using CallCenter.Share.Notifications;
  5. using MapsterMapper;
  6. using MediatR;
  7. using Microsoft.Extensions.Logging;
  8. using NewRock.Sdk.Events;
  9. using NewRock.Sdk.Extensions;
  10. using NewRock.Sdk.Security;
  11. using XF.Domain.Dependency;
  12. namespace CallCenter.NewRock.Handlers
  13. {
  14. public class DeviceEventHandler : IDeviceEventHandler, IScopeDependency
  15. {
  16. private readonly IMediator _mediator;
  17. private readonly IMapper _mapper;
  18. private readonly ILogger<DeviceEventHandler> _logger;
  19. private static readonly string _cdrMarkup = "<Cdr id=";
  20. public DeviceEventHandler(
  21. IMediator mediator,
  22. IMapper mapper,
  23. ILogger<DeviceEventHandler> logger)
  24. {
  25. _mediator = mediator;
  26. _mapper = mapper;
  27. _logger = logger;
  28. }
  29. public async Task HandleAsync(Stream eventStream, DeviceConfigs deviceConfigs,
  30. CancellationToken cancellationToken)
  31. {
  32. var sr = new StreamReader(eventStream);
  33. var content = await sr.ReadToEndAsync();
  34. _logger.LogInformation("收到设备事件:\r\n{content}", content);
  35. if (content.Contains(_cdrMarkup))
  36. {
  37. // cdr事件
  38. //通话记录报告
  39. var eventBase = content.DeserializeWithAuthorize<NewRockCdrEvent>();
  40. if (eventBase.value == null) return;
  41. if (deviceConfigs.Authorize && (eventBase.authorize == null ||
  42. !eventBase.authorize.IsAuthorized(deviceConfigs.SendKey)))
  43. throw new AuthenticationException("无有效身份认证信息");
  44. var cdrRcv = content.DeserializeWithAuthorize<CdrEvent>();
  45. await _mediator.Publish(_mapper.Map<CdrNotification>(cdrRcv.value!), cancellationToken);
  46. }
  47. else
  48. {
  49. var eventBase = content.DeserializeWithAuthorize<NewRockEvent>();
  50. if (eventBase.value == null) return;
  51. if (deviceConfigs.Authorize && (eventBase.authorize == null ||
  52. !eventBase.authorize.IsAuthorized(deviceConfigs.SendKey)))
  53. throw new AuthenticationException("无有效身份认证信息");
  54. switch (eventBase.value.Attribute)
  55. {
  56. //分机上线事件发布
  57. case Event.ONLINE:
  58. var onLineRcv = content.DeserializeWithAuthorize<OnlineEvent>();
  59. await _mediator.Publish(_mapper.Map<OnlineNotification>(onLineRcv.value!), cancellationToken);
  60. break;
  61. //分机下线事件
  62. case Event.OFFLINE:
  63. var offLineRcv = content.DeserializeWithAuthorize<OfflineEvent>();
  64. await _mediator.Publish(_mapper.Map<OfflineNotification>(offLineRcv.value!), cancellationToken);
  65. break;
  66. //分机示闲事件
  67. case Event.IDLE:
  68. var idleRcv = content.DeserializeWithAuthorize<IdleEvent>();
  69. await _mediator.Publish(_mapper.Map<IdleNotification>(idleRcv.value!), cancellationToken);
  70. break;
  71. //分机示忙事件
  72. case Event.BUSY:
  73. var busyRcv = content.DeserializeWithAuthorize<BusyEvent>();
  74. await _mediator.Publish(_mapper.Map<BusyNotification>(busyRcv.value!), cancellationToken);
  75. break;
  76. //振铃事件
  77. case Event.RING:
  78. var ringRcv = content.DeserializeWithAuthorize<RingEvent>();
  79. //判断是哪种振铃事件
  80. //分机呼分机
  81. if (ringRcv.value?.Ext.Count > 1)
  82. {
  83. await _mediator.Publish(_mapper.Map<RingExtToExtNotification>(ringRcv.value!),cancellationToken);
  84. }
  85. //来电转分机
  86. else if (ringRcv.value?.Ext.Count == 1 && ringRcv.value.Visitor != null)
  87. {
  88. await _mediator.Publish(_mapper.Map<RingVisitorToExtNotification>(ringRcv.value!),
  89. cancellationToken);
  90. }
  91. //分机外呼
  92. else if (ringRcv.value?.Ext.Count == 1 && ringRcv.value.Outer != null && ringRcv.value.Outer.Id != "")
  93. {
  94. await _mediator.Publish(_mapper.Map<RingExtToOuterNotification>(ringRcv.value!), cancellationToken);
  95. }
  96. //menu呼叫分机
  97. else if (ringRcv.value?.Ext.Count == 1 && ringRcv.value.Menu != null)
  98. {
  99. await _mediator.Publish(_mapper.Map<RingMenuToExtNotification>(ringRcv.value!),
  100. cancellationToken);
  101. }
  102. break;
  103. //回铃事件
  104. case Event.ALERT:
  105. var alertRcv = content.DeserializeWithAuthorize<AlertEvent>();
  106. //判断是 哪种回铃事件
  107. //来电转分机,分机回铃
  108. if (alertRcv.value?.Ext.Count == 1 && alertRcv.value.Visitor != null)
  109. {
  110. await _mediator.Publish(_mapper.Map<AlertVisitorToExtNotification>(alertRcv.value!),
  111. cancellationToken);
  112. }
  113. //分机呼外部电话,外部电话回铃
  114. else if (alertRcv.value?.Ext.Count == 1 && alertRcv.value.Outer != null)
  115. {
  116. await _mediator.Publish(_mapper.Map<AlertExtToOuterNotification>(alertRcv.value!),
  117. cancellationToken);
  118. }
  119. //分机呼分机,被叫分机回铃
  120. else if (alertRcv.value?.Ext.Count > 1)
  121. {
  122. await _mediator.Publish(_mapper.Map<AlertExtToExtNotification>(alertRcv.value!),
  123. cancellationToken);
  124. }
  125. //Menu外呼,外部电话回铃
  126. else if ((alertRcv.value?.Ext == null || alertRcv.value?.Ext.Count == 0) &&
  127. alertRcv.value?.Outer != null)
  128. {
  129. await _mediator.Publish(_mapper.Map<AlertMenuToOuterNotification>(alertRcv.value!),
  130. cancellationToken);
  131. }
  132. break;
  133. //呼叫应答事件
  134. case Event.ANSWER:
  135. var answerRcv = content.DeserializeWithAuthorize<AnswerEvent>();
  136. //分机呼分机,被叫分机应答
  137. if (answerRcv.value?.Ext.Count > 1)
  138. {
  139. await _mediator.Publish(_mapper.Map<AnswerExtToExtNotification>(answerRcv.value!),
  140. cancellationToken);
  141. }
  142. //来电转分机,分机应答
  143. else if (answerRcv.value?.Ext.Count == 1 && answerRcv.value.Visitor != null)
  144. {
  145. await _mediator.Publish(_mapper.Map<AnswerViisitorToExtNotification>(answerRcv.value!),
  146. cancellationToken);
  147. }
  148. //去电转分机,分机应答
  149. else if (answerRcv.value?.Ext.Count == 1 && answerRcv.value?.Outer != null)
  150. {
  151. await _mediator.Publish(_mapper.Map<AnswerExtToOuterNotification>(answerRcv.value!),
  152. cancellationToken);
  153. }
  154. break;
  155. //呼叫被应答事件
  156. case Event.ANSWERED:
  157. var answeredRcv = content.DeserializeWithAuthorize<AnsweredEvent>();
  158. //分机呼分机,主叫分机检查到被叫分机应答
  159. if (answeredRcv.value?.Ext.Count > 1)
  160. {
  161. await _mediator.Publish(_mapper.Map<AnsweredExtToExtNotification>(answeredRcv.value!),
  162. cancellationToken);
  163. }
  164. //分机呼外部电话,分机检查到外部电话应答
  165. else if (answeredRcv.value?.Ext.Count == 1 && answeredRcv.value?.Outer != null)
  166. {
  167. await _mediator.Publish(_mapper.Map<AnsweredExtToOuterNotification>(answeredRcv.value!),
  168. cancellationToken);
  169. }
  170. //来电呼叫分机
  171. else if (answeredRcv.value?.Visitor != null && answeredRcv.value?.Ext.Count == 1)
  172. {
  173. await _mediator.Publish(_mapper.Map<AnsweredVisitorToExtNotification>(answeredRcv.value!),
  174. cancellationToken);
  175. }
  176. //分机呼外部电话,转接其他分机,其他分机应答
  177. else if (answeredRcv.value?.Outer != null)
  178. {
  179. await _mediator.Publish(
  180. _mapper.Map<AnsweredExtToOuterToExtNotification>(answeredRcv.value!),
  181. cancellationToken);
  182. }
  183. break;
  184. //通话结束事件
  185. case Event.BYE:
  186. var byeRcv = content.DeserializeWithAuthorize<ByeEvent>();
  187. //来电和分机的通话结束,来电挂断
  188. if(byeRcv.value?.Visitor!=null && byeRcv.value?.Menu !=null)
  189. {
  190. await _mediator.Publish(_mapper.Map<ByeVisitorAndMenuNotification>(byeRcv.value!), cancellationToken);
  191. }
  192. else if (byeRcv.value?.Ext.Count == 1 && byeRcv.value?.Visitor != null)
  193. {
  194. await _mediator.Publish(_mapper.Map<ByeVisitorAndExtNotification>(byeRcv.value!),
  195. cancellationToken);
  196. }
  197. //来电和分机的通话,分机挂断
  198. else if (byeRcv.value?.Visitor != null)
  199. {
  200. await _mediator.Publish(_mapper.Map<ByeVisitorOffNotification>(byeRcv.value!),
  201. cancellationToken);
  202. }
  203. //来电转去电的通话结束,来电挂断
  204. else if (byeRcv.value?.Outer != null && byeRcv.value?.Visitor != null)
  205. {
  206. await _mediator.Publish(_mapper.Map<ByeVisitorAndOuterNotification>(byeRcv.value!),
  207. cancellationToken);
  208. }
  209. //分机和分机通话,分机挂断
  210. else if (byeRcv.value?.Ext.Count > 1)
  211. {
  212. await _mediator.Publish(_mapper.Map<ByeExtAndExtNotification>(byeRcv.value!), cancellationToken);
  213. }
  214. //其他条件
  215. else if (byeRcv.value?.Outer != null)
  216. {
  217. //分机和去电的通话结束,分机挂断 类型一
  218. if (byeRcv.value?.Ext != null)
  219. {
  220. await _mediator.Publish(_mapper.Map<ByeExtAndOuterOneNotification>(byeRcv.value!),
  221. cancellationToken);
  222. }
  223. //双向外呼的通话结束,两个去电分别各有一个 BYE 事件
  224. else if (byeRcv.value?.Outer.From != "")
  225. {
  226. await _mediator.Publish(_mapper.Map<ByeOuterAndOuterNotification>(byeRcv.value!),
  227. cancellationToken);
  228. }
  229. //分机和去电的通话结束,分机挂断 类型二
  230. else
  231. {
  232. await _mediator.Publish(_mapper.Map<ByeExtAndOuterTwoNotification>(byeRcv.value!),
  233. cancellationToken);
  234. }
  235. }
  236. break;
  237. //呼叫转移事件
  238. case Event.DIVERT:
  239. var divertRcv = content.DeserializeWithAuthorize<DivertEvent>();
  240. //来电呼叫分机时,因分机设置了呼叫转移等原因,导致该呼叫被转移
  241. if (divertRcv.value?.Visitor != null)
  242. {
  243. await _mediator.Publish(_mapper.Map<DivertVisitorToExtNotification>(divertRcv.value!),
  244. cancellationToken);
  245. }
  246. //分机呼叫其他分机时,因被叫分机设置了呼叫转移等原因,导致该呼叫被转移
  247. else if (divertRcv.value?.Ext != null)
  248. {
  249. await _mediator.Publish(_mapper.Map<DivertExtToExtNotification>(divertRcv.value!),
  250. cancellationToken);
  251. }
  252. break;
  253. //呼叫临时事件
  254. case Event.TRANSIENT:
  255. var transientRcv = content.DeserializeWithAuthorize<TransientEvent>();
  256. if (transientRcv.value?.Outer != null)
  257. {
  258. await _mediator.Publish(_mapper.Map<TransientOuterNotification>(transientRcv.value!),
  259. cancellationToken);
  260. }
  261. else if (transientRcv.value?.Visitor != null)
  262. {
  263. await _mediator.Publish(_mapper.Map<TransientVisitorNotification>(transientRcv.value!),
  264. cancellationToken);
  265. }
  266. //TODO 处理来电临时事件
  267. break;
  268. //呼叫失败事件
  269. case Event.FAILED:
  270. var failedRcv = content.DeserializeWithAuthorize<FailedEvent>();
  271. await _mediator.Publish(_mapper.Map<FailedNotification>(failedRcv.value!), cancellationToken);
  272. break;
  273. //来电呼叫请求事件
  274. case Event.INVITE:
  275. var inviteRcv = content.DeserializeWithAuthorize<InviteEvent>();
  276. await _mediator.Publish(_mapper.Map<InviteNotification>(inviteRcv.value!), cancellationToken);
  277. break;
  278. //来电呼入事件
  279. case Event.INCOMING:
  280. var incomingRcv = content.DeserializeWithAuthorize<IncomingEvent>();
  281. await _mediator.Publish(_mapper.Map<IncomingNotification>(incomingRcv.value!),
  282. cancellationToken);
  283. break;
  284. //按键信息事件
  285. case Event.DTMF:
  286. var dtmfRcv = content.DeserializeWithAuthorize<DtmfEvent>();
  287. await _mediator.Publish(_mapper.Map<DtmfNotification>(dtmfRcv.value!), cancellationToken);
  288. break;
  289. //语音文件播放完毕事件
  290. case Event.EndOfAnn:
  291. var endOfAnnRcv = content.DeserializeWithAuthorize<EndOfAnnEvent>();
  292. //来电转menu
  293. if (endOfAnnRcv.value?.Visitor != null && endOfAnnRcv.value?.Menu != null)
  294. {
  295. await _mediator.Publish(_mapper.Map<EndOfAnnVisitorToMenuNotification>(endOfAnnRcv.value!),
  296. cancellationToken);
  297. }
  298. //去电转menu
  299. else if (endOfAnnRcv.value?.Outer != null && endOfAnnRcv.value?.Menu != null)
  300. {
  301. await _mediator.Publish(_mapper.Map<EndOfAnnOuterToMenuNotification>(endOfAnnRcv.value!),
  302. cancellationToken);
  303. }
  304. //分机转menu
  305. else if (endOfAnnRcv.value?.Ext != null && endOfAnnRcv.value?.Menu != null)
  306. {
  307. await _mediator.Publish(_mapper.Map<EndOfAnnExtToMenuNotification>(endOfAnnRcv.value!),
  308. cancellationToken);
  309. }
  310. break;
  311. //分机组队列事件
  312. case Event.QUEUE:
  313. var queueRcv = content.DeserializeWithAuthorize<QueueEvent>();
  314. //分机呼入分机组
  315. if (queueRcv.value?.Ext != null && queueRcv.value?.Waiting != null)
  316. {
  317. //组内分机全忙,分机和来电相继呼入分机组
  318. if (queueRcv.value?.Waiting.Reason == "")
  319. {
  320. await _mediator.Publish(_mapper.Map<QueueExtToGroupBusyNotification>(queueRcv.value!),
  321. cancellationToken);
  322. }
  323. //若所有分机离线,分机和来电呼叫分机组
  324. else if (queueRcv.value?.Waiting.Reason == "offline")
  325. {
  326. await _mediator.Publish(
  327. _mapper.Map<QueueExtToGroupOfflineNotification>(queueRcv.value!),
  328. cancellationToken);
  329. }
  330. //若排队满了,分机和来电呼叫分机组
  331. else if (queueRcv.value?.Waiting.Reason == "full")
  332. {
  333. await _mediator.Publish(_mapper.Map<QueueExtToGroupFullNotification>(queueRcv.value!),
  334. cancellationToken);
  335. }
  336. }
  337. //组内分机全忙,分机和来电相继呼入分机组
  338. //来电呼入分机组
  339. else if (queueRcv.value?.Visitor != null && queueRcv.value?.Waiting != null)
  340. {
  341. //组内分机全忙,分机和来电相继呼入分机组
  342. if (queueRcv.value?.Waiting.Reason == "")
  343. {
  344. await _mediator.Publish(
  345. _mapper.Map<QueueVisitorToGroupBusyNotification>(queueRcv.value!),
  346. cancellationToken);
  347. }
  348. else if (queueRcv.value?.Waiting.Reason == "offline")
  349. {
  350. await _mediator.Publish(
  351. _mapper.Map<QueueVisitorToGroupOfflineNotification>(queueRcv.value!),
  352. cancellationToken);
  353. }
  354. else if (queueRcv.value?.Waiting.Reason == "full")
  355. {
  356. await _mediator.Publish(
  357. _mapper.Map<QueueVisitorToGroupFullNotification>(queueRcv.value!),
  358. cancellationToken);
  359. }
  360. }
  361. break;
  362. //系统重启事件
  363. case Event.BOOTUP:
  364. var bootupRcv = content.DeserializeWithAuthorize<BootupEvent>();
  365. await _mediator.Publish(_mapper.Map<BootupNotification>(bootupRcv.value!), cancellationToken);
  366. break;
  367. default:
  368. break;
  369. }
  370. }
  371. }
  372. }
  373. }