package com.gustz.dove.cpcli.api.message.service.impl;
import java.io.StringReader;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.sinovatech.rd.wcsb.cli.api.app.service.impl.ClientAppService;
import com.sinovatech.rd.wcsb.cli.api.app.vo.ClientAppVo;
import com.sinovatech.rd.wcsb.cli.api.customer.vo.TextCust;
import com.sinovatech.rd.wcsb.cli.api.message.req.CommEventMsgReq;
import com.sinovatech.rd.wcsb.cli.api.message.req.MsgBaseReq;
import com.sinovatech.rd.wcsb.cli.api.message.service.impl.MessageServiceImpl;
import com.sinovatech.rd.wcsb.cli.api.service.dict.EventTypeDict;
import com.sinovatech.rd.wcsb.cli.api.service.util.AppLogStyle;
import com.sinovatech.rd.wcsb.cli.api.service.util.ClientConstants;
import com.sinovatech.rd.wcsb.cpcli.api.customer.req.TextCustReq;
import com.sinovatech.rd.wcsb.cpcli.api.customer.req.TextCustReq.TextBodyCustReq;
import com.sinovatech.rd.wcsb.cpcli.api.customer.service.CustomerCpService;
import com.sinovatech.rd.wcsb.cpcli.api.message.service.MessageCpService;
import com.sinovatech.rd.wcsb.cpcli.api.security.service.OauthCpService;
import com.sinovatech.rd.wcsb.repo.account.AccConstants;
/**
*
* TODO: 消息处理服务的接口实现
*
* @author ZHENFENG ZHANG
* @since [ Aug 3, 2015 ]
*/
@Service
public class MessageCpServiceImpl extends MessageServiceImpl implements MessageCpService {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private CustomerCpService customerCpService;
@Autowired
private ClientAppService clientAppService;
@Autowired
private OauthCpService oauthCpService;
/**
* 转发接收企业号的消息
*
* <pre>
* 1、直接回复空串(指字节长度为0的空字符串,而不是XML结构体中content字段的内容为空)
* 2、直接回复success
* </pre>
* @param msgSignature
* @param timestamp
* @param nonce
* @param postData
* @return
*/
@Override
public String dispatcherMsg(String msgSignature, String timestamp, String nonce, String postData) {
AppLogStyle appLogs = new AppLogStyle();
appLogs.begin(String.format("转发接收企业号的消息,msgSignature[ %1$s ],timestamp[ %2$s ],nonce[ %3$s ] ", msgSignature, timestamp,
nonce));
try {
Document doc = new SAXReader().read(new StringReader(postData));
// 企业号
String _toUserName = doc.selectSingleNode(MsgBaseReq.TO_USER_NAME_XPATH).getText();
if (!this.hasUserName(appLogs, "接收的企业号", _toUserName)) {
return "";
}
// 企业号的应用ID
String _agentId = doc.selectSingleNode(MsgBaseReq.AGENT_ID_XPATH).getText();
if (StringUtils.isBlank(_agentId)) {
appLogs.runtimeWarn(String.format("接收的企业号的应用ID[ %1$s ]不存在 ", _agentId));
return "";
}
//
final String _key = AccConstants.getCpAccountCode(_agentId, _toUserName);
ClientAppVo _appVo = clientAppService.getActiveCacheByAcc().get(_key);
if (!this.hasClientApp(appLogs, "应用ID", _appVo, _agentId)) {
return "";
}
// 微信解密消息
final String atomData = this.decryptMsg(_appVo, msgSignature, timestamp, nonce, doc);
// 发送方的账号
String _fromUserName = CommEventMsgReq.toBean(EventTypeDict.ENTER_AGENT, atomData).getFromUserName();
if (!this.hasUserName(appLogs, "发送方的账号", _fromUserName)) {
return "";
}
//
final String _statusKey = AccConstants.getCpAccountCode(_agentId, _appVo.getWecAppId());
// OAuth授权URL
String oauthCbUrl = oauthCpService.getSnsapiBaseUrl(_appVo.getCliAppCode(), _statusKey);
String newPostData = this.localEncryptMsg(atomData, oauthCbUrl); // 本地的加密消息
// 直接推送到接入的客户端APP
if (!this.hasSendToCliApp(appLogs, _appVo, _fromUserName, newPostData)) {
return "";
}
// 自动回复消息
this.doAutoReplyMsg(_appVo, doc);
//
return ClientConstants.SUCCESS_RSP;
} catch (Exception e) {
appLogs.error("处理接收的企业号消息异常\n", e);
} finally {
appLogs.end();
}
return "";
}
/**
* 自动回复消息(客服回复)
*
* <pre>
* 异步发送客服消息
* </pre>
* @param eventType 事件类型
* @param toUserName 接收者
* @param fromUserName 发送者
* @param cliAppCode 客户端APP编码
* @param content 消息
*/
@Override
public void autoReplyMsg(final String eventType, final String toUserName, final String fromUserName, final String cliAppCode,
final String content) {
// 不需要校验客户端应用
this.setCheckCliApp(false);
// 根据事件类型过滤回复语
if (EventTypeDict.SUBSCRIBE.name().equalsIgnoreCase(eventType)) { // 关注事件
ExecutorService exeService = Executors.newSingleThreadExecutor();
exeService.execute(new Runnable() {
@Override
public void run() {
// 文本消息请求的报文
TextBodyCustReq body = new TextBodyCustReq(toUserName, new TextCust(content));
// 发送客服消息
logger.info("CP客服自动回复消息...");
customerCpService.sendCustomerMsg(System.currentTimeMillis(), cliAppCode, new TextCustReq(fromUserName, body));
}
});
}
}
}