DeviceEventHandler.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  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?.Ext != null && byeRcv.value?.Visitor != null)
  189. {
  190. await _mediator.Publish(_mapper.Map<ByeVisitorAndExtNotification>(byeRcv.value!),
  191. cancellationToken);
  192. }
  193. //来电和分机的通话,分机挂断
  194. else if (byeRcv.value?.Visitor != null)
  195. {
  196. await _mediator.Publish(_mapper.Map<ByeVisitorOffNotification>(byeRcv.value!),
  197. cancellationToken);
  198. }
  199. //来电转去电的通话结束,来电挂断
  200. else if (byeRcv.value?.Outer != null && byeRcv.value?.Visitor != null)
  201. {
  202. await _mediator.Publish(_mapper.Map<ByeVisitorAndOuterNotification>(byeRcv.value!),
  203. cancellationToken);
  204. }
  205. //其他条件
  206. else if (byeRcv.value?.Outer != null)
  207. {
  208. //分机和去电的通话结束,分机挂断 类型一
  209. if (byeRcv.value?.Ext != null)
  210. {
  211. await _mediator.Publish(_mapper.Map<ByeExtAndOuterOneNotification>(byeRcv.value!),
  212. cancellationToken);
  213. }
  214. //双向外呼的通话结束,两个去电分别各有一个 BYE 事件
  215. else if (byeRcv.value?.Outer.From != "")
  216. {
  217. await _mediator.Publish(_mapper.Map<ByeOuterAndOuterNotification>(byeRcv.value!),
  218. cancellationToken);
  219. }
  220. //分机和去电的通话结束,分机挂断 类型二
  221. else
  222. {
  223. await _mediator.Publish(_mapper.Map<ByeExtAndOuterTwoNotification>(byeRcv.value!),
  224. cancellationToken);
  225. }
  226. }
  227. break;
  228. //呼叫转移事件
  229. case Event.DIVERT:
  230. var divertRcv = content.DeserializeWithAuthorize<DivertEvent>();
  231. //来电呼叫分机时,因分机设置了呼叫转移等原因,导致该呼叫被转移
  232. if (divertRcv.value?.Visitor != null)
  233. {
  234. await _mediator.Publish(_mapper.Map<DivertVisitorToExtNotification>(divertRcv.value!),
  235. cancellationToken);
  236. }
  237. //分机呼叫其他分机时,因被叫分机设置了呼叫转移等原因,导致该呼叫被转移
  238. else if (divertRcv.value?.Ext != null)
  239. {
  240. await _mediator.Publish(_mapper.Map<DivertExtToExtNotification>(divertRcv.value!),
  241. cancellationToken);
  242. }
  243. break;
  244. //呼叫临时事件
  245. case Event.TRANSIENT:
  246. var transientRcv = content.DeserializeWithAuthorize<TransientEvent>();
  247. if (transientRcv.value?.Outer != null)
  248. {
  249. await _mediator.Publish(_mapper.Map<TransientOuterNotification>(transientRcv.value!),
  250. cancellationToken);
  251. }
  252. else if (transientRcv.value?.Visitor != null)
  253. {
  254. await _mediator.Publish(_mapper.Map<TransientVisitorNotification>(transientRcv.value!),
  255. cancellationToken);
  256. }
  257. //TODO 处理来电临时事件
  258. break;
  259. //呼叫失败事件
  260. case Event.FAILED:
  261. var failedRcv = content.DeserializeWithAuthorize<FailedEvent>();
  262. await _mediator.Publish(_mapper.Map<FailedNotification>(failedRcv.value!), cancellationToken);
  263. break;
  264. //来电呼叫请求事件
  265. case Event.INVITE:
  266. var inviteRcv = content.DeserializeWithAuthorize<InviteEvent>();
  267. await _mediator.Publish(_mapper.Map<InviteNotification>(inviteRcv.value!), cancellationToken);
  268. break;
  269. //来电呼入事件
  270. case Event.INCOMING:
  271. var incomingRcv = content.DeserializeWithAuthorize<IncomingEvent>();
  272. await _mediator.Publish(_mapper.Map<IncomingNotification>(incomingRcv.value!),
  273. cancellationToken);
  274. break;
  275. //按键信息事件
  276. case Event.DTMF:
  277. var dtmfRcv = content.DeserializeWithAuthorize<DtmfEvent>();
  278. await _mediator.Publish(_mapper.Map<DtmfNotification>(dtmfRcv.value!), cancellationToken);
  279. break;
  280. //语音文件播放完毕事件
  281. case Event.EndOfAnn:
  282. var endOfAnnRcv = content.DeserializeWithAuthorize<EndOfAnnEvent>();
  283. //来电转menu
  284. if (endOfAnnRcv.value?.Visitor != null && endOfAnnRcv.value?.Menu != null)
  285. {
  286. await _mediator.Publish(_mapper.Map<EndOfAnnVisitorToMenuNotification>(endOfAnnRcv.value!),
  287. cancellationToken);
  288. }
  289. //去电转menu
  290. else if (endOfAnnRcv.value?.Outer != null && endOfAnnRcv.value?.Menu != null)
  291. {
  292. await _mediator.Publish(_mapper.Map<EndOfAnnOuterToMenuNotification>(endOfAnnRcv.value!),
  293. cancellationToken);
  294. }
  295. //分机转menu
  296. else if (endOfAnnRcv.value?.Ext != null && endOfAnnRcv.value?.Menu != null)
  297. {
  298. await _mediator.Publish(_mapper.Map<EndOfAnnExtToMenuNotification>(endOfAnnRcv.value!),
  299. cancellationToken);
  300. }
  301. break;
  302. //分机组队列事件
  303. case Event.QUEUE:
  304. var queueRcv = content.DeserializeWithAuthorize<QueueEvent>();
  305. //分机呼入分机组
  306. if (queueRcv.value?.Ext != null && queueRcv.value?.Waiting != null)
  307. {
  308. //组内分机全忙,分机和来电相继呼入分机组
  309. if (queueRcv.value?.Waiting.Reason == "")
  310. {
  311. await _mediator.Publish(_mapper.Map<QueueExtToGroupBusyNotification>(queueRcv.value!),
  312. cancellationToken);
  313. }
  314. //若所有分机离线,分机和来电呼叫分机组
  315. else if (queueRcv.value?.Waiting.Reason == "offline")
  316. {
  317. await _mediator.Publish(
  318. _mapper.Map<QueueExtToGroupOfflineNotification>(queueRcv.value!),
  319. cancellationToken);
  320. }
  321. //若排队满了,分机和来电呼叫分机组
  322. else if (queueRcv.value?.Waiting.Reason == "full")
  323. {
  324. await _mediator.Publish(_mapper.Map<QueueExtToGroupFullNotification>(queueRcv.value!),
  325. cancellationToken);
  326. }
  327. }
  328. //组内分机全忙,分机和来电相继呼入分机组
  329. //来电呼入分机组
  330. else if (queueRcv.value?.Visitor != null && queueRcv.value?.Waiting != null)
  331. {
  332. //组内分机全忙,分机和来电相继呼入分机组
  333. if (queueRcv.value?.Waiting.Reason == "")
  334. {
  335. await _mediator.Publish(
  336. _mapper.Map<QueueVisitorToGroupBusyNotification>(queueRcv.value!),
  337. cancellationToken);
  338. }
  339. else if (queueRcv.value?.Waiting.Reason == "offline")
  340. {
  341. await _mediator.Publish(
  342. _mapper.Map<QueueVisitorToGroupOfflineNotification>(queueRcv.value!),
  343. cancellationToken);
  344. }
  345. else if (queueRcv.value?.Waiting.Reason == "full")
  346. {
  347. await _mediator.Publish(
  348. _mapper.Map<QueueVisitorToGroupFullNotification>(queueRcv.value!),
  349. cancellationToken);
  350. }
  351. }
  352. break;
  353. //系统重启事件
  354. case Event.BOOTUP:
  355. var bootupRcv = content.DeserializeWithAuthorize<BootupEvent>();
  356. await _mediator.Publish(_mapper.Map<BootupNotification>(bootupRcv.value!), cancellationToken);
  357. break;
  358. default:
  359. break;
  360. }
  361. }
  362. }
  363. }
  364. }