不同类型的消息处理
这里抽象层用的是接口
MessageProcess ⬇︎⬇︎⬇︎
点击查看代码- /**
- * 消息处理
- *
- * @author haiyang
- */
- public interface MessageProcess<K,V> {
- /**
- * 处理消息
- *
- * @param messageInfo 消息相关信息
- * @return {@link V}
- */
- V dealWithMessage(final K messageInfo);
- }
复制代码 客户的消息 CustomerMessageProcess ⬇︎⬇︎⬇︎
点击查看代码- /**
- * 客户消息
- * <pre>
- * 客户回复的消息如果是数字,需要将数字对应的detail和可选项回复关联起来。
- * </pre>
- *
- * @author haiyang
- */
- public class CustomerMessageProcess implements MessageProcess<MessageFullInfoDto, MessageProcessFinalResultDto> {
- @Override
- public MessageProcessFinalResultDto dealWithMessage(final MessageFullInfoDto messageFullInfoDto) {
- // 判断是否处于禁止发言期间
- Object disableReplay = redisUtils.get(RedisKeyUtil.getDisableReplayKey(messageFullInfoDto.getRoomId()));
- if (!Objects.isNull(disableReplay)) {
- log.info("群:{}正处于禁止机器人发言期", messageFullInfoDto.getRoomId());
- return new MessageProcessFinalResultDto(false, "正处于禁止机器人发言期", null);
- }
- // 判断文本是否属于数字类型
- String messageContents = messageFullInfoDto.getMessageContents();
- boolean numeric = StringUtils.isNumeric(messageContents);
- Long groupId = messageFullInfoDto.getGroupId();
- if (numeric) {
- // 走数字逻辑
- int parseInt = Integer.parseInt(messageContents);
- if (parseInt > 0 && parseInt <= 10) {
- LambdaQueryWrapper<MsgDetail> lastDetail = new LambdaQueryWrapper<MsgDetail>().eq(MsgDetail::getGroupId, groupId).eq(MsgDetail::getType, MsgDetailEnum.Type.REPLY.getCode()).orderByDesc(MsgDetail::getCreateTime).last("limit 1");
- MsgDetail replyMsgDetail = msgDetailService.getOne(lastDetail);
- MessageProcessFinalResultDto messageProcessFinalResultDto = noOptionReplyHandler(messageFullInfoDto, messageContents, groupId, replyMsgDetail);
- if (messageProcessFinalResultDto != null) {
- return messageProcessFinalResultDto;
- }
- MsgAnswers groupLastAnswer = msgAnswersService.getGroupLastAnswer(groupId, parseInt);
- messageProcessFinalResultDto = missedReplyHandler(messageFullInfoDto, messageContents, groupId, groupLastAnswer);
- if (messageProcessFinalResultDto != null) {
- return messageProcessFinalResultDto;
- }
- messageProcessFinalResultDto = handlerInvalidate(messageFullInfoDto, messageContents, groupId, groupLastAnswer);
- if (messageProcessFinalResultDto != null) {
- return messageProcessFinalResultDto;
- }
- messageProcessFinalResultDto = hitHandler(messageFullInfoDto, messageContents, groupId, groupLastAnswer);
- String replyDetailId = replyMsgDetail.getReplyDetailId();
- if (StringUtils.isNotEmpty(replyDetailId)) {
- replyDetailId += "," + messageProcessFinalResultDto.getExtendData();
- } else {
- replyDetailId = "" + messageProcessFinalResultDto.getExtendData();
- }
- replyMsgDetail.setReplyDetailId(replyDetailId);
- msgDetailService.updateById(replyMsgDetail);
- return messageProcessFinalResultDto;
- }
- }
- // 普通文本处理
- saveDetail(messageFullInfoDto, messageContents, groupId, null, true);
- LambdaQueryWrapper<MsgWaitTask> queryWrapper = new LambdaQueryWrapper<MsgWaitTask>().eq(MsgWaitTask::getGroupId, groupId).eq(MsgWaitTask::getMergeStatus, MergeStatusEnum.WAIT_MERGE.getStatus()).orderByDesc(MsgWaitTask::getWaitMergeTime).last("limit 1");
- MsgWaitTask msgWaitTask = msgWaitTaskService.getOne(queryWrapper);
- if (Objects.isNull(msgWaitTask)) {
- saveMsgWaitTask(messageFullInfoDto, groupId);
- return new MessageProcessFinalResultDto(true, null, null);
- }
- LocalDateTime waitMergeTime = msgWaitTask.getWaitMergeTime();
- LocalDateTime now = LocalDateTime.now();
- if (now.isAfter(waitMergeTime)) {
- saveMsgWaitTask(messageFullInfoDto, groupId);
- } else {
- // 更新整合时间和最后一次微信时间
- msgWaitTask.setLastTxMsgTime(messageFullInfoDto.getMsgTime());
- msgWaitTask.setWaitMergeTime(LocalDateTime.now().plusSeconds(15));
- msgWaitTaskService.updateById(msgWaitTask);
- }
- return new MessageProcessFinalResultDto(true, null, null);
- }
- private void saveMsgWaitTask(MessageFullInfoDto messageFullInfoDto, Long groupId) {
- MsgWaitTask msgWaitTask;
- // 说明已经过了整合时间, 重新插入一条数据
- msgWaitTask = new MsgWaitTask();
- msgWaitTask.setGroupId(groupId);
- msgWaitTask.setRoomId(messageFullInfoDto.getRoomId());
- Long msgTime = messageFullInfoDto.getMsgTime();
- msgWaitTask.setWaitMergeTime(LocalDateTime.now().plusSeconds(15));
- msgWaitTask.setLastTxMsgTime(msgTime);
- msgWaitTask.setMergeStatus(MergeStatusEnum.WAIT_MERGE.getStatus());
- msgWaitTaskService.save(msgWaitTask);
- }
- /**
- * 命中处理
- */
- private MessageProcessFinalResultDto hitHandler(MessageFullInfoDto messageFullInfoDto, String messageContents, Long groupId, MsgAnswers groupLastAnswer) {
- String answerContext = groupLastAnswer.getAnswerContext();
- Long rpaMsgDetailId = saveRpaMsgDetail(messageFullInfoDto, groupId, answerContext);
- // 保存客户detail
- Long detailId = saveDetail(messageFullInfoDto, messageContents, groupId, rpaMsgDetailId, false);
- // 发送rpa任务
- sendRpaTask(messageFullInfoDto, answerContext, rpaMsgDetailId,TaskSubTypeEnum.ACCURATE.getType());
- return new MessageProcessFinalResultDto(true, null, detailId);
- }
- /**
- * 无可选项回复处理
- */
- private MessageProcessFinalResultDto noOptionReplyHandler(MessageFullInfoDto messageFullInfoDto, String messageContents, Long groupId, MsgDetail replyMsgDetail) {
- if (Objects.isNull(replyMsgDetail) || DateUtil.isAfterMinus(replyMsgDetail.getCreateTime(), 20)) {
- // 没有可选项回复 存入detail 不执行回复
- saveDetail(messageFullInfoDto, messageContents, groupId, null, false);
- log.info("客服发言的数字文本无需回复, fromAccount:{}, textContext:{}", messageFullInfoDto.getFromAccount(), messageContents);
- noWorkAutoReply(messageFullInfoDto, messageContents, groupId);
- return new MessageProcessFinalResultDto(true, null, null);
- }
- /* // 判断可选项时间是否在20min有效期
- LocalDateTime createTime = replyMsgDetail.getCreateTime();
- if (DateUtil.isAfterMinus(createTime, 20)) {
- // 超过了有效期, 回复默认文本
- // 没有可选项回复 存入detail 不执行回复
- saveDetail(messageFullInfoDto, messageContents, groupId, null, false);
- log.info("客服发言的数字文本无需回复, fromAccount:{}, textContext:{}", messageFullInfoDto.getFromAccount(), messageContents);
- return new MessageProcessFinalResultDto(true, null, null);
- }*/
- return null;
- }
- private void noWorkAutoReply(MessageFullInfoDto messageFullInfoDto, String messageContents, Long groupId) {
- // 非工自动回复处理
- boolean workTime = DateUtil.workTime(new Date());
- if (!workTime) {
- Object noWorkReplay = redisUtils.get(RedisKeyUtil.getNoWorkReplayKey(messageFullInfoDto.getRoomId()));
- if (Objects.isNull(noWorkReplay)) {
- // 发送rpa任务 推送非工时间的默认回复
- String noWorkAutoReply = ianswerProperties.getNoWorkAutoReply();
- Long rpaMsgDetailId = saveRpaMsgDetail(messageFullInfoDto, groupId, noWorkAutoReply);
- // 保存客户detail
- saveDetail(messageFullInfoDto, messageContents, groupId, rpaMsgDetailId, false);
- // 发送rpa任务
- sendRpaTask(messageFullInfoDto, noWorkAutoReply, rpaMsgDetailId,TaskSubTypeEnum.ACCURATE.getType());
- // 计算非工回复周期
- int tomorrowSeconds = DateUtil.getTomorrowSeconds(new Date());
- redisUtils.setWithExpireSeconds(RedisKeyUtil.getNoWorkReplayKey(messageFullInfoDto.getRoomId()), true, tomorrowSeconds);
- }
- }
- }
- /**
- * 未命中处理
- */
- private MessageProcessFinalResultDto missedReplyHandler(MessageFullInfoDto messageFullInfoDto, String messageContents, Long groupId, MsgAnswers groupLastAnswer) {
- if (Objects.isNull(groupLastAnswer)) {
- // 保存机器人默认回复文本
- String missedReply = ianswerProperties.getMissedReply();
- Long rpaMsgDetailId = saveRpaMsgDetail(messageFullInfoDto, groupId, missedReply);
- // 保存客户detail
- saveDetail(messageFullInfoDto, messageContents, groupId, rpaMsgDetailId, false);
- // 发送rpa任务
- sendRpaTask(messageFullInfoDto, missedReply, rpaMsgDetailId,TaskSubTypeEnum.FIXED.getType());
- return new MessageProcessFinalResultDto(true, null, null);
- }
- return null;
- }
- /**
- * 以上都不是处理
- */
- private MessageProcessFinalResultDto handlerInvalidate(MessageFullInfoDto messageFullInfoDto, String messageContents, Long groupId, MsgAnswers groupLastAnswer) {
- if (MsgAnswerEnum.Type.INVALIDATE.getCode().equals(groupLastAnswer.getType())) {
- // 以上都不是, 需要回复固定话术
- boolean workTime = DateUtil.workTime(new Date());
- String textContext = null;
- if (workTime) {
- textContext = ianswerProperties.getExitWork();
- } else {
- textContext = ianswerProperties.getExitNonWork();
- }
- Long rpaMsgDetailId = saveRpaMsgDetail(messageFullInfoDto, groupId, textContext);
- // 保存客户detail
- saveDetail(messageFullInfoDto, messageContents, groupId, rpaMsgDetailId, false);
- // 发送rpa任务
- sendRpaTask(messageFullInfoDto, textContext, rpaMsgDetailId,TaskSubTypeEnum.FIXED.getType());
- return new MessageProcessFinalResultDto(true, null, null);
- }
- return null;
- }
- private void sendRpaTask(MessageFullInfoDto messageFullInfoDto, String missedReply, Long rpaMsgDetailId,String taskSubType) {
- SendTaskDto sendTaskDto = new SendTaskDto();
- sendTaskDto.setRoomId(messageFullInfoDto.getRoomId());
- sendTaskDto.setDetailId(rpaMsgDetailId);
- sendTaskDto.setContentSign(messageContextUtil.getSHAStr(missedReply));
- sendTaskDto.setGroupId(messageFullInfoDto.getGroupId());
- SendTaskRequest sendTaskRequest = new SendTaskRequest();
- sendTaskRequest.setContent(missedReply);
- sendTaskRequest.setResourceName(messageFullInfoDto.getOrderNo());
- sendTaskRequest.setWaitingRobotAccounts(messageFullInfoDto.getRobotAccount());
- sendTaskRequest.setWaitingRobotNames(messageFullInfoDto.getRobotName());
- sendTaskRequest.setTaskOverTime(DateUtil.addTimeToString(LocalDateTime.now(), 30));
- sendTaskRequest.setCustomer(messageFullInfoDto.getCustomName());
- sendTaskRequest.setSubResourceName(messageFullInfoDto.getGrowthMember());
- sendTaskRequest.setOrderId(messageFullInfoDto.getOrderNo());
- sendTaskRequest.setTaskSubType(taskSubType);
- sendTaskDto.setSendTaskRequest(sendTaskRequest);
- rpaTaskService.sendTask(sendTaskDto);
- }
- private Long saveRpaMsgDetail(MessageFullInfoDto messageFullInfoDto, Long groupId, String missedReply) {
- MsgDetail msgDetail = new MsgDetail();
- msgDetail.setType(MsgDetailEnum.Type.COMMON.getCode());
- msgDetail.setGroupId(groupId);
- msgDetail.setRoomId(messageFullInfoDto.getRoomId());
- msgDetail.setMsgStatus(MsgDetailEnum.MsgStatus.TO_BE_RECEIVE.getCode());
- msgDetail.setTextContext(missedReply);
- msgDetail.setTextContextSign(messageContextUtil.getSHAStr(missedReply));
- msgDetail.setMergeStatus(MsgDetailEnum.MergeStatus.NONE.getCode());
- msgDetail.setReplyStatus(MsgDetailEnum.ReplyStatus.WAIT_REPLY.getCode());
- msgDetail.setSendAccountType(MsgDetailEnum.SendAccountType.RPA.getCode());
- msgDetail.setSendQwName(messageFullInfoDto.getRobotName());
- msgDetail.setSendQwAccount(messageFullInfoDto.getRobotAccount());
- msgDetailService.save(msgDetail);
- return msgDetail.getId();
- }
- private Long saveDetail(MessageFullInfoDto messageFullInfoDto, String messageContents, Long groupId, Long rpaMsgDetailId, boolean isTextMessage) {
- MsgDetail msgDetail = new MsgDetail();
- msgDetail.setType(MsgDetailEnum.Type.COMMON.getCode());
- msgDetail.setGroupId(groupId);
- msgDetail.setRoomId(messageFullInfoDto.getRoomId());
- msgDetail.setMsgId(messageFullInfoDto.getMsgId());
- msgDetail.setMsgTime(messageFullInfoDto.getMsgTime());
- msgDetail.setMsgFrom(messageFullInfoDto.getFromAccount());
- msgDetail.setMsgStatus(MsgDetailEnum.MsgStatus.RECEIVED.getCode());
- msgDetail.setTextContext(messageContents);
- msgDetail.setTextContextSign(messageContextUtil.getSHAStr(messageContents));
- if (isTextMessage) {
- msgDetail.setMergeStatus(MsgDetailEnum.MergeStatus.WAIT_MERGE.getCode());
- msgDetail.setReplyStatus(MsgDetailEnum.ReplyStatus.WAIT_REPLY.getCode());
- } else {
- msgDetail.setReplyStatus(MsgDetailEnum.ReplyStatus.NONE.getCode());
- msgDetail.setMergeStatus(MsgDetailEnum.MergeStatus.NONE.getCode());
- }
- if (Objects.nonNull(rpaMsgDetailId)) {
- msgDetail.setReplyDetailId(rpaMsgDetailId.toString());
- }
- msgDetailService.save(msgDetail);
- return msgDetail.getId();
- }
- }
复制代码 人工客服消息 StaffServiceMessageProcess ⬇︎⬇︎⬇︎
点击查看代码- /**
- * 机器人消息
- * <pre>
- * 整体处理逻辑:
- * 1.根据群id和机器人的账号+内容签名,确定一条最新的有效的明细和任务
- * 2.更新机器人发言的那条明细记录
- * 3.更新rpa任务相应的状态
- * 4.更新前面整合提问的那些明细
- * </pre>
- *
- * @author haiyang
- */
- @Component
- @Slf4j
- public class RobotMessageProcess implements MessageProcess<MessageFullInfoDto, MessageProcessFinalResultDto> {
- @Override
- public MessageProcessFinalResultDto dealWithMessage(final MessageFullInfoDto messageInfo) {
- log.info("RobotMessageProcess params:{}",JSON.toJSONString(messageInfo));
- // 1.查到对应的rpa task 和 msg detail(这个消息是机器人发送的消息)
- TaskMsgDetailDto taskDetailInfo = rpaTaskService.getTaskDetailInfo(messageInfo.getRoomId(),
- messageInfo.getFromAccount(),
- getShaContentsOfTrimAt(messageInfo.getMessageContents())
- );
- log.info("getTaskDetailInfo result:{}", JSON.toJSONString(taskDetailInfo));
- if (Objects.isNull(taskDetailInfo)) {
- return new MessageProcessFinalResultDto(false,"没有找到对应的task detail",null);
- }
- // 2.更新 rpa task 中的 rpa_msg_status
- rpaTaskService.updateRpaMsgStatus(taskDetailInfo.getTaskId(), RpaTaskEnum.RpaMsgStatus.RECEIVE_SUCCESS.getCode());
- log.info("更新rpa task的状态--完成");
- // 3.更新机器人消息的detail的中的 msg_status 状态 ,
- // 同时需要更新对应的 send_qw_name 和 send_qw_account 为实际发送消息的robot账号信息(实际回复消息的只有一个机器人)
- msgDetailService.updateMsgStatus(taskDetailInfo.getDetailId(),
- MsgDetailEnum.MsgStatus.RECEIVED.getCode(),
- messageInfo.getFromAccountName(),
- messageInfo.getFromAccount(),
- messageInfo.getMsgId(),
- messageInfo.getMsgTime(),
- messageInfo.getFromAccount());
- log.info("更新robot消息detail的状态--完成");
- // 4.更新对应的整合消息的 reply_status
- msgDetailService.refreshReplyStatus(taskDetailInfo.getDetailId(),taskDetailInfo.getMsgId(),taskDetailInfo.getMsgTime());
- log.info("更新对应的整合消息--完成");
- syncNotifyListener(taskDetailInfo);
- log.info("通知操作--完成");
- return new MessageProcessFinalResultDto(true,null,null);
- }
- /**
- * 将机器人消息去除@符号进行签名
- * <pre>
- * <b>下发rpa任务时,at的对象没有直接跟在内容里面</b>
- * </pre>
- *
- * @param msgContent 味精内容
- * @return {@link String}
- */
- private String getShaContentsOfTrimAt(final String msgContent){
- if (msgContent.contains(CommonConstant.SYMBOL_OF_AT)) {
- int i = msgContent.indexOf(CommonConstant.SYMBOL_OF_AT);
- if (i>0) {
- String trimAtString = msgContent.substring(0, i);
- return messageContextUtil.getSHAStr(trimAtString);
- }
- }
- String sign = messageContextUtil.getSHAStr(msgContent);
- log.info("msgContent:{},sign:{}",msgContent,sign);
- return sign;
- }
- /**
- * 通知操作
- *
- * @param taskDetailInfo 任务详细信息
- */
- private void syncNotifyListener(TaskMsgDetailDto taskDetailInfo){
- log.info("通知rpa消息接收结果");
- NotifyTaskRequest request = new NotifyTaskRequest();
- request.setTaskId(String.valueOf(taskDetailInfo.getTaskId()));
- request.setMsgStatus(RpaTaskEnum.RpaMsgStatus.RECEIVE_SUCCESS.getStatus());
- request.setReceivedMsgTime(DateUtil.formatYmdHms(DateUtil.secondToLocalDate(taskDetailInfo.getMsgTime())));
- sendTaskClient.notifyReceivedMessageResult(Arrays.asList(request));
- }
- }
复制代码 调用的地方是这样的:⟱⟱⟱

不同状态的处理逻辑
这里抽象层用的是抽象类
使用的时候是通过枚举指定的类型从IOC容器中获取对应的处理实例的,如下⬇︎⬇︎⬇︎
选择使用
使用很灵活,理念很简单。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |