123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375 |
- using System.Security.Authentication;
- using Hotline.CallCenter;
- using Hotline.CallCenter.Devices;
- using Hotline.Share.Notifications;
- using MapsterMapper;
- using MediatR;
- using Microsoft.Extensions.Logging;
- using NewRock.Sdk.Events;
- using NewRock.Sdk.Extensions;
- using NewRock.Sdk.Security;
- using XF.Domain.Dependency;
- namespace Hotline.NewRock.Handlers
- {
- public class DeviceEventHandler : IDeviceEventHandler, IScopeDependency
- {
- private readonly IMediator _mediator;
- private readonly IMapper _mapper;
- private readonly ILogger<DeviceEventHandler> _logger;
- private static readonly string _cdrMarkup = "<Cdr id=";
- public DeviceEventHandler(
- IMediator mediator,
- IMapper mapper,
- ILogger<DeviceEventHandler> logger)
- {
- _mediator = mediator;
- _mapper = mapper;
- _logger = logger;
- }
- public async Task HandleAsync(Stream eventStream, CallCenterConfiguration deviceConfigs,
- CancellationToken cancellationToken)
- {
- var sr = new StreamReader(eventStream);
- var content = await sr.ReadToEndAsync();
- _logger.LogInformation("收到设备事件:\r\n{content}", content);
- if (content.Contains(_cdrMarkup))
- {
- // cdr事件
- //通话记录报告
- var eventBase = content.DeserializeWithAuthorize<NewRockCdrEvent>();
- if (eventBase.value == null) return;
- if (deviceConfigs.DeviceConfigs.Authorize && (eventBase.authorize == null ||
- !eventBase.authorize.IsAuthorized(deviceConfigs.DeviceConfigs.SendKey)))
- throw new AuthenticationException("无有效身份认证信息");
- var cdrRcv = content.DeserializeWithAuthorize<CdrEvent>();
- await _mediator.Publish(_mapper.Map<CdrNotification>(cdrRcv.value!), cancellationToken);
- }
- else
- {
- var eventBase = content.DeserializeWithAuthorize<NewRockEvent>();
- if (eventBase.value == null) return;
- if (deviceConfigs.DeviceConfigs.Authorize && (eventBase.authorize == null ||
- !eventBase.authorize.IsAuthorized(deviceConfigs.DeviceConfigs.SendKey)))
- throw new AuthenticationException("无有效身份认证信息");
- switch (eventBase.value.Attribute)
- {
- //分机上线事件发布
- case Event.ONLINE:
- var onLineRcv = content.DeserializeWithAuthorize<OnlineEvent>();
- await _mediator.Publish(_mapper.Map<OnlineNotification>(onLineRcv.value!), cancellationToken);
- break;
- //分机下线事件
- case Event.OFFLINE:
- var offLineRcv = content.DeserializeWithAuthorize<OfflineEvent>();
- await _mediator.Publish(_mapper.Map<OfflineNotification>(offLineRcv.value!), cancellationToken);
- break;
- //分机示闲事件
- case Event.IDLE:
- var idleRcv = content.DeserializeWithAuthorize<IdleEvent>();
- await _mediator.Publish(_mapper.Map<IdleNotification>(idleRcv.value!), cancellationToken);
- break;
- //分机示忙事件
- case Event.BUSY:
- var busyRcv = content.DeserializeWithAuthorize<BusyEvent>();
- await _mediator.Publish(_mapper.Map<BusyNotification>(busyRcv.value!), cancellationToken);
- break;
- //振铃事件
- case Event.RING:
- var ringRcv = content.DeserializeWithAuthorize<RingEvent>();
- //判断是哪种振铃事件
- //分机呼分机
- if (ringRcv.value?.Ext.Count > 1)
- {
- //await _mediator.Publish(_mapper.Map<RingExtToExtNotification>(ringRcv.value!),cancellationToken);
- }
- //来电转分机
- else if (ringRcv.value?.Ext.Count == 1 && ringRcv.value.Visitor != null)
- {
- await _mediator.Publish(_mapper.Map<RingVisitorToExtNotification>(ringRcv.value!),
- cancellationToken);
- }
- //分机外呼
- else if (ringRcv.value?.Ext.Count == 1 && ringRcv.value.Outer != null && ringRcv.value.Outer.Id != "")
- {
- await _mediator.Publish(_mapper.Map<RingExtToOuterNotification>(ringRcv.value!), cancellationToken);
- }
- //menu呼叫分机
- else if (ringRcv.value?.Ext.Count == 1 && ringRcv.value.Menu != null)
- {
- await _mediator.Publish(_mapper.Map<RingMenuToExtNotification>(ringRcv.value!),
- cancellationToken);
- }
- break;
- //回铃事件
- case Event.ALERT:
- var alertRcv = content.DeserializeWithAuthorize<AlertEvent>();
- //判断是 哪种回铃事件
- //来电转分机,分机回铃
- if (alertRcv.value?.Ext.Count == 1 && alertRcv.value.Visitor != null)
- {
- await _mediator.Publish(_mapper.Map<AlertVisitorToExtNotification>(alertRcv.value!),
- cancellationToken);
- }
- //分机呼外部电话,外部电话回铃
- else if (alertRcv.value?.Ext.Count == 1 && alertRcv.value.Outer != null)
- {
- await _mediator.Publish(_mapper.Map<AlertExtToOuterNotification>(alertRcv.value!),
- cancellationToken);
- }
- //分机呼分机,被叫分机回铃
- else if (alertRcv.value?.Ext.Count > 1)
- {
- await _mediator.Publish(_mapper.Map<AlertExtToExtNotification>(alertRcv.value!),
- cancellationToken);
- }
- //Menu外呼,外部电话回铃
- else if ((alertRcv.value?.Ext == null || alertRcv.value?.Ext.Count == 0) &&
- alertRcv.value?.Outer != null)
- {
- await _mediator.Publish(_mapper.Map<AlertMenuToOuterNotification>(alertRcv.value!),
- cancellationToken);
- }
- break;
- //呼叫应答事件
- case Event.ANSWER:
- var answerRcv = content.DeserializeWithAuthorize<AnswerEvent>();
- //分机呼分机,被叫分机应答
- if (answerRcv.value?.Ext.Count > 1)
- {
- await _mediator.Publish(_mapper.Map<AnswerExtToExtNotification>(answerRcv.value!),
- cancellationToken);
- }
- //来电转分机,分机应答
- else if (answerRcv.value?.Ext.Count == 1 && answerRcv.value.Visitor != null)
- {
- await _mediator.Publish(_mapper.Map<AnswerViisitorToExtNotification>(answerRcv.value!),
- cancellationToken);
- }
- //去电转分机,分机应答
- else if (answerRcv.value?.Ext.Count == 1 && answerRcv.value?.Outer != null)
- {
- await _mediator.Publish(_mapper.Map<AnswerExtToOuterNotification>(answerRcv.value!),
- cancellationToken);
- }
- break;
- //呼叫被应答事件
- case Event.ANSWERED:
- var answeredRcv = content.DeserializeWithAuthorize<AnsweredEvent>();
- //分机呼分机,主叫分机检查到被叫分机应答
- if (answeredRcv.value?.Ext.Count > 1)
- {
- await _mediator.Publish(_mapper.Map<AnsweredExtToExtNotification>(answeredRcv.value!),
- cancellationToken);
- }
- //分机呼外部电话,分机检查到外部电话应答
- else if (answeredRcv.value?.Ext.Count == 1 && answeredRcv.value?.Outer != null)
- {
- await _mediator.Publish(_mapper.Map<AnsweredExtToOuterNotification>(answeredRcv.value!),
- cancellationToken);
- }
- //来电呼叫分机
- else if (answeredRcv.value?.Visitor != null && answeredRcv.value?.Ext.Count == 1)
- {
- await _mediator.Publish(_mapper.Map<AnsweredVisitorToExtNotification>(answeredRcv.value!),
- cancellationToken);
- }
- //分机呼外部电话,转接其他分机,其他分机应答
- else if (answeredRcv.value?.Outer != null)
- {
- await _mediator.Publish(
- _mapper.Map<AnsweredExtToOuterToExtNotification>(answeredRcv.value!),
- cancellationToken);
- }
- break;
- //通话结束事件
- case Event.BYE:
- var byeRcv = content.DeserializeWithAuthorize<ByeEvent>();
- //来电和分机的通话结束,来电挂断
- if (byeRcv.value?.Ext.Count==1 && byeRcv.value?.Visitor != null)
- {
- await _mediator.Publish(_mapper.Map<ByeVisitorAndExtNotification>(byeRcv.value!),
- cancellationToken);
- }
- //来电和分机的通话,分机挂断
- else if (byeRcv.value?.Visitor != null)
- {
- await _mediator.Publish(_mapper.Map<ByeVisitorOffNotification>(byeRcv.value!),
- cancellationToken);
- }
- //来电转去电的通话结束,来电挂断
- else if (byeRcv.value?.Outer != null && byeRcv.value?.Visitor != null)
- {
- await _mediator.Publish(_mapper.Map<ByeVisitorAndOuterNotification>(byeRcv.value!),
- cancellationToken);
- }
- //分机和分机结束通话,挂断
- else if(byeRcv.value?.Ext.Count==2)
- {
- await _mediator.Publish(_mapper.Map<ByeExtAndExtNotification>(byeRcv.value!), cancellationToken);
- }
- //其他条件
- else if (byeRcv.value?.Outer != null)
- {
- //分机和去电的通话结束,分机挂断 类型一
- if (byeRcv.value?.Ext.Count == 1)
- {
- await _mediator.Publish(_mapper.Map<ByeExtAndOuterOneNotification>(byeRcv.value!),
- cancellationToken);
- }
- //双向外呼的通话结束,两个去电分别各有一个 BYE 事件
- else if (byeRcv.value?.Outer.From != "")
- {
- await _mediator.Publish(_mapper.Map<ByeOuterAndOuterNotification>(byeRcv.value!),
- cancellationToken);
- }
- //分机和去电的通话结束,分机挂断 类型二
- else
- {
- await _mediator.Publish(_mapper.Map<ByeExtAndOuterTwoNotification>(byeRcv.value!),
- cancellationToken);
- }
- }
- break;
- //呼叫转移事件
- case Event.DIVERT:
- var divertRcv = content.DeserializeWithAuthorize<DivertEvent>();
- //来电呼叫分机时,因分机设置了呼叫转移等原因,导致该呼叫被转移
- if (divertRcv.value?.Visitor != null)
- {
- await _mediator.Publish(_mapper.Map<DivertVisitorToExtNotification>(divertRcv.value!),
- cancellationToken);
- }
- //分机呼叫其他分机时,因被叫分机设置了呼叫转移等原因,导致该呼叫被转移
- else if (divertRcv.value?.Ext != null)
- {
- await _mediator.Publish(_mapper.Map<DivertExtToExtNotification>(divertRcv.value!),
- cancellationToken);
- }
- break;
- //呼叫临时事件
- case Event.TRANSIENT:
- var transientRcv = content.DeserializeWithAuthorize<TransientEvent>();
- if (transientRcv.value?.Outer != null)
- {
- await _mediator.Publish(_mapper.Map<TransientOuterNotification>(transientRcv.value!),
- cancellationToken);
- }
- else if (transientRcv.value?.Visitor != null)
- {
- await _mediator.Publish(_mapper.Map<TransientVisitorNotification>(transientRcv.value!),
- cancellationToken);
- }
- //TODO 处理来电临时事件
- break;
- //呼叫失败事件
- case Event.FAILED:
- var failedRcv = content.DeserializeWithAuthorize<FailedEvent>();
- await _mediator.Publish(_mapper.Map<FailedNotification>(failedRcv.value!), cancellationToken);
- break;
- //来电呼叫请求事件
- case Event.INVITE:
- var inviteRcv = content.DeserializeWithAuthorize<InviteEvent>();
- await _mediator.Publish(_mapper.Map<InviteNotification>(inviteRcv.value!), cancellationToken);
- break;
- //来电呼入事件
- case Event.INCOMING:
- var incomingRcv = content.DeserializeWithAuthorize<IncomingEvent>();
- await _mediator.Publish(_mapper.Map<IncomingNotification>(incomingRcv.value!),
- cancellationToken);
- break;
- //按键信息事件
- case Event.DTMF:
- var dtmfRcv = content.DeserializeWithAuthorize<DtmfEvent>();
- await _mediator.Publish(_mapper.Map<DtmfNotification>(dtmfRcv.value!), cancellationToken);
- break;
- //语音文件播放完毕事件
- case Event.EndOfAnn:
- var endOfAnnRcv = content.DeserializeWithAuthorize<EndOfAnnEvent>();
- //来电转menu
- if (endOfAnnRcv.value?.Visitor != null && endOfAnnRcv.value?.Menu != null)
- {
- await _mediator.Publish(_mapper.Map<EndOfAnnVisitorToMenuNotification>(endOfAnnRcv.value!),
- cancellationToken);
- }
- //去电转menu
- else if (endOfAnnRcv.value?.Outer != null && endOfAnnRcv.value?.Menu != null)
- {
- await _mediator.Publish(_mapper.Map<EndOfAnnOuterToMenuNotification>(endOfAnnRcv.value!),
- cancellationToken);
- }
- //分机转menu
- else if (endOfAnnRcv.value?.Ext != null && endOfAnnRcv.value?.Menu != null)
- {
- await _mediator.Publish(_mapper.Map<EndOfAnnExtToMenuNotification>(endOfAnnRcv.value!),
- cancellationToken);
- }
- break;
- //分机组队列事件
- case Event.QUEUE:
- var queueRcv = content.DeserializeWithAuthorize<QueueEvent>();
- //分机呼入分机组
- if (queueRcv.value?.Ext != null && queueRcv.value?.Waiting != null)
- {
- //组内分机全忙,分机和来电相继呼入分机组
- if (queueRcv.value?.Waiting.Reason == "")
- {
- await _mediator.Publish(_mapper.Map<QueueExtToGroupBusyNotification>(queueRcv.value!),
- cancellationToken);
- }
- //若所有分机离线,分机和来电呼叫分机组
- else if (queueRcv.value?.Waiting.Reason == "offline")
- {
- await _mediator.Publish(
- _mapper.Map<QueueExtToGroupOfflineNotification>(queueRcv.value!),
- cancellationToken);
- }
- //若排队满了,分机和来电呼叫分机组
- else if (queueRcv.value?.Waiting.Reason == "full")
- {
- await _mediator.Publish(_mapper.Map<QueueExtToGroupFullNotification>(queueRcv.value!),
- cancellationToken);
- }
- }
- //组内分机全忙,分机和来电相继呼入分机组
- //来电呼入分机组
- else if (queueRcv.value?.Visitor != null && queueRcv.value?.Waiting != null)
- {
- //组内分机全忙,分机和来电相继呼入分机组
- if (queueRcv.value?.Waiting.Reason == "")
- {
- await _mediator.Publish(
- _mapper.Map<QueueVisitorToGroupBusyNotification>(queueRcv.value!),
- cancellationToken);
- }
- else if (queueRcv.value?.Waiting.Reason == "offline")
- {
- await _mediator.Publish(
- _mapper.Map<QueueVisitorToGroupOfflineNotification>(queueRcv.value!),
- cancellationToken);
- }
- else if (queueRcv.value?.Waiting.Reason == "full")
- {
- await _mediator.Publish(
- _mapper.Map<QueueVisitorToGroupFullNotification>(queueRcv.value!),
- cancellationToken);
- }
- }
- break;
- //系统重启事件
- case Event.BOOTUP:
- var bootupRcv = content.DeserializeWithAuthorize<BootupEvent>();
- await _mediator.Publish(_mapper.Map<BootupNotification>(bootupRcv.value!), cancellationToken);
- break;
- default:
- break;
- }
- }
- }
- }
- }
|