|
|
@ -8,8 +8,11 @@ import com.dingtalk.api.DingTalkClient; |
|
|
|
import com.dingtalk.api.request.OapiRobotSendRequest; |
|
|
|
import com.dingtalk.api.response.OapiRobotSendResponse; |
|
|
|
import com.epmet.commons.tools.constant.NumConstant; |
|
|
|
import com.epmet.commons.tools.dto.form.DingTalkTextMsg; |
|
|
|
import com.epmet.commons.tools.exception.RenException; |
|
|
|
import com.epmet.commons.tools.utils.ConvertUtils; |
|
|
|
import com.epmet.commons.tools.utils.HttpClientManager; |
|
|
|
import com.epmet.commons.tools.utils.Result; |
|
|
|
import com.epmet.constant.ModuleConstant; |
|
|
|
import com.epmet.constant.ThirdRedisKeyConstant; |
|
|
|
import com.epmet.constant.ThirdRunTimeInfoConstant; |
|
|
@ -30,6 +33,7 @@ import com.fasterxml.jackson.core.JsonGenerator; |
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper; |
|
|
|
import com.taobao.api.ApiException; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
import org.apache.commons.codec.binary.Base64; |
|
|
|
import org.apache.commons.lang3.StringUtils; |
|
|
|
import org.dom4j.DocumentException; |
|
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
@ -37,10 +41,14 @@ import org.springframework.beans.factory.annotation.Value; |
|
|
|
import org.springframework.stereotype.Service; |
|
|
|
import org.springframework.transaction.annotation.Transactional; |
|
|
|
|
|
|
|
import javax.crypto.Mac; |
|
|
|
import javax.crypto.spec.SecretKeySpec; |
|
|
|
import javax.servlet.http.HttpServletRequest; |
|
|
|
import javax.servlet.http.HttpServletResponse; |
|
|
|
import java.io.IOException; |
|
|
|
import java.io.InputStream; |
|
|
|
import java.io.PrintWriter; |
|
|
|
import java.net.URLEncoder; |
|
|
|
import java.util.Date; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.Map; |
|
|
@ -87,15 +95,16 @@ public class WarrantServiceImpl implements WarrantService { |
|
|
|
*/ |
|
|
|
@Transactional(rollbackFor = Exception.class) |
|
|
|
@Override |
|
|
|
public String acceptMessageAndEvent(HttpServletRequest request, String appId, HttpServletResponse response)throws IOException, DocumentException, AesException { |
|
|
|
log.info("消息与事件接收URL【代码审核结果】开始执行......"); |
|
|
|
log.info("appId:"+ appId); |
|
|
|
public void acceptMessageAndEvent(HttpServletRequest request, String appId, HttpServletResponse response)throws IOException, DocumentException, AesException { |
|
|
|
request.setCharacterEncoding(ModuleConstant.UTF8); |
|
|
|
String msgSignature = request.getParameter(ModuleConstant.MSG_SIGNATURE); |
|
|
|
String timeStamp = request.getParameter(ModuleConstant.TIMESTAMP); |
|
|
|
String nonce = request.getParameter(ModuleConstant.NONCE); |
|
|
|
if (!StringUtils.isNotBlank(msgSignature)) { |
|
|
|
return ModuleConstant.SUCCESS;// 微信推送给第三方开放平台的消息一定是加过密的,无消息加密无法解密消息
|
|
|
|
// 微信推送给第三方开放平台的消息一定是加过密的,无消息加密无法解密消息
|
|
|
|
PrintWriter pw = response.getWriter(); |
|
|
|
pw.write(ModuleConstant.SUCCESS); |
|
|
|
pw.flush(); |
|
|
|
} |
|
|
|
InputStream inputStream; |
|
|
|
String postData = null; |
|
|
@ -109,7 +118,6 @@ public class WarrantServiceImpl implements WarrantService { |
|
|
|
} catch (AesException e) { |
|
|
|
e.printStackTrace(); |
|
|
|
} |
|
|
|
log.info(String.format(ThirdRunTimeInfoConstant.MSG,msg)); |
|
|
|
// 将xml转为map
|
|
|
|
Map<String, Object> result = WXXmlToMapUtil.multilayerXmlToMap(msg); |
|
|
|
Map<String,Object> xml = (Map<String, Object>) result.get(ModuleConstant.XML); |
|
|
@ -117,20 +125,22 @@ public class WarrantServiceImpl implements WarrantService { |
|
|
|
log.info(String.format(ThirdRunTimeInfoConstant.MSG_TYPE,msgType)); |
|
|
|
String toUserName = null; |
|
|
|
String fromUserName = null; |
|
|
|
if (xml.containsKey(ModuleConstant.TO_USER_NAME)){ |
|
|
|
toUserName = xml.get(ModuleConstant.TO_USER_NAME).toString(); |
|
|
|
log.info("toUserName为:" + toUserName); |
|
|
|
} |
|
|
|
if (xml.containsKey(ModuleConstant.FROM_USER_NAME)){ |
|
|
|
fromUserName = xml.get(ModuleConstant.FROM_USER_NAME).toString(); |
|
|
|
log.info("fromUserName为:"+fromUserName); |
|
|
|
} |
|
|
|
if (msgType.equals(ModuleConstant.EVENT_LOW)) { |
|
|
|
String event = xml.get(ModuleConstant.EVENT).toString(); |
|
|
|
if (xml.containsKey(ModuleConstant.TO_USER_NAME)){ |
|
|
|
toUserName = xml.get(ModuleConstant.TO_USER_NAME).toString(); |
|
|
|
} |
|
|
|
if (xml.containsKey(ModuleConstant.FROM_USER_NAME)){ |
|
|
|
fromUserName = xml.get(ModuleConstant.FROM_USER_NAME).toString(); |
|
|
|
} |
|
|
|
if (event.startsWith(ModuleConstant.WE_APP_AUDIT)) { |
|
|
|
log.info("消息与事件接收URL【代码审核结果】开始执行......"); |
|
|
|
// TODO 目前来看,msgType = ‘event’ 的是代码审核结果
|
|
|
|
Long createTime = Long.valueOf(xml.get(ModuleConstant.CREATE_TIME).toString()); |
|
|
|
CodeAuditRecordFormDTO codeAuditRecord = ConvertUtils.mapToEntity(xml, CodeAuditRecordFormDTO.class); |
|
|
|
codeAuditRecord.setWechatCreateTime(componentVerifyTicketServiceImpl.sToDate(createTime.toString())); |
|
|
|
// String toUserName = codeAuditRecord.getToUserName();//小程序原始ID
|
|
|
|
CustomerIdAndClientResultDTO customerIdAndClientResultDTO = miniInfoDao.selectCustomerIdAndClientByToUserName(toUserName); |
|
|
|
String clientType = customerIdAndClientResultDTO.getClientType(); |
|
|
|
String customerId = customerIdAndClientResultDTO.getCustomerId(); |
|
|
@ -147,27 +157,30 @@ public class WarrantServiceImpl implements WarrantService { |
|
|
|
log.info(String.format(ThirdRunTimeInfoConstant.CODE_AUDIT_RESULT, xml)); |
|
|
|
codeAuditRecordDao.insertCodeAuditRecord(codeAuditRecord); |
|
|
|
// 修改 code_audit_result 中的代码审核结果
|
|
|
|
// String event = codeAuditRecord.getEvent();
|
|
|
|
String reason = codeAuditRecord.getReason(); |
|
|
|
String codeResult = null; |
|
|
|
switch (event) { |
|
|
|
case ModuleConstant.WEAPP_AUDIT_SUCCESS: |
|
|
|
codeResult = ModuleConstant.AUDIT_SUCCESS; |
|
|
|
this.dingDingRobot(reason,null,customerName,client); |
|
|
|
break; |
|
|
|
case ModuleConstant.WEAPP_AUDIT_FAIL: |
|
|
|
codeResult = ModuleConstant.AUDIT_FAILED; |
|
|
|
this.dingDingRobot(reason,codeResult,customerName,client); |
|
|
|
break; |
|
|
|
case ModuleConstant.WEAPP_AUDIT_DELAY: |
|
|
|
codeResult = ModuleConstant.DELAY; |
|
|
|
this.dingDingRobot(reason,codeResult,customerName,client); |
|
|
|
break; |
|
|
|
} |
|
|
|
log.info("开始寻找机器人发送消息"); |
|
|
|
this.dingDingRobot(reason,codeResult,customerName,client); |
|
|
|
log.info("已找到robot,并发送消息......"); |
|
|
|
String codeCustomerId = codeCustomerDao.selectCodeCustomerId(codeAuditRecord); |
|
|
|
codeAuditResultDao.updateAuditResult(customerId, codeCustomerId, codeResult); |
|
|
|
log.info("消息与事件接收URL【代码审核结果】结束......"); |
|
|
|
PrintWriter pw = response.getWriter(); |
|
|
|
pw.write(ModuleConstant.SUCCESS); |
|
|
|
pw.flush(); |
|
|
|
}else { |
|
|
|
log.info("==================== ==== event message ========= ="); |
|
|
|
this.replyEventMessage(request,response,event,toUserName,fromUserName); |
|
|
|
} |
|
|
|
}else if (msgType.equals(ModuleConstant.TEXT)){ |
|
|
@ -179,16 +192,24 @@ public class WarrantServiceImpl implements WarrantService { |
|
|
|
// messagePushTextDao.insertMessageText(messagePushTextFormDTO);
|
|
|
|
String content = messagePushTextFormDTO.getContent(); |
|
|
|
log.info(String.format(ThirdRunTimeInfoConstant.CONTENT,content)); |
|
|
|
/** |
|
|
|
* 测试公众号处理用户消息 |
|
|
|
* 模拟粉丝发送文本消息给专用测试公众号,第三方平台方需根据文本消息的内容进行相应的响应: |
|
|
|
* 1)微信模推送给第三方平台方:文本消息,其中 Content 字段的内容固定为:TESTCOMPONENT_MSG_TYPE_TEXT |
|
|
|
* 2)第三方平台方立马回应文本消息并最终触达粉丝:Content 必须固定为:TESTCOMPONENT_MSG_TYPE_TEXT_callback |
|
|
|
*/ |
|
|
|
this.processTextMessage(request,response,content,toUserName,fromUserName); |
|
|
|
if(ModuleConstant.TESTCOMPONENT_MSG_TYPE_TEXT.equals(content)){ |
|
|
|
log.info("收到消息,要回复了......"); |
|
|
|
// String returnContent = content+ModuleConstant._CALL_BACK;
|
|
|
|
String returnContent = "TESTCOMPONENT_MSG_TYPE_TEXT_callback"; |
|
|
|
log.info("拼接的回复内容【普通】:"+returnContent); |
|
|
|
replyTextMessage(request, response, returnContent, toUserName, fromUserName); |
|
|
|
|
|
|
|
}else if(StringUtils.startsWithIgnoreCase(content, ModuleConstant.QUERY_AUTH_CODE)){ |
|
|
|
PrintWriter pw = response.getWriter();//需在5秒内返回空串表明暂时不回复,然后再立即使用客服消息接口发送消息回复粉丝
|
|
|
|
pw.write(""); |
|
|
|
pw.flush(); |
|
|
|
|
|
|
|
log.info(String.format(ThirdRunTimeInfoConstant.TEXT_MESSAGE_LOG_INFO,content,content.split(ThirdRedisKeyConstant.COLON)[NumConstant.ONE],fromUserName,toUserName)); |
|
|
|
//接下来客服API再回复一次消息
|
|
|
|
String[] split = content.split(ThirdRedisKeyConstant.COLON); |
|
|
|
replyApiTextMessage(split[NumConstant.ONE],fromUserName); |
|
|
|
} |
|
|
|
} |
|
|
|
return ModuleConstant.SUCCESS; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@ -197,7 +218,6 @@ public class WarrantServiceImpl implements WarrantService { |
|
|
|
* @date 2020/8/5 4:33 下午 |
|
|
|
*/ |
|
|
|
public void dingDingRobot(String result,String event,String customerName,String clientType){ |
|
|
|
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/robot/send?access_token=5b48fcbc3fde24b8ba4696aa062b7f8146479a9d3467dbb1f9cf132ec36b955a"); |
|
|
|
OapiRobotSendRequest request = new OapiRobotSendRequest(); |
|
|
|
request.setMsgtype("markdown"); |
|
|
|
OapiRobotSendRequest.Markdown markdown = new OapiRobotSendRequest.Markdown(); |
|
|
@ -222,12 +242,34 @@ public class WarrantServiceImpl implements WarrantService { |
|
|
|
break; |
|
|
|
} |
|
|
|
request.setMarkdown(markdown); |
|
|
|
log.info("robot需要发送的内容为:"+markdown.getTitle()); |
|
|
|
String url = "https://oapi.dingtalk.com/robot/send?access_token=2438902efbcc15909deb7076963c5cbe2d6fdbfdb9d66750faab2f2cce6eb09f"; |
|
|
|
String secret = "SECe3c785dd254659608667a4a623acc5a0395636143411617f6e36838b48941e74"; |
|
|
|
this.sendCodeMsg(request,url,secret); |
|
|
|
} |
|
|
|
/* |
|
|
|
public static void main(String[] args) { |
|
|
|
WarrantServiceImpl w = new WarrantServiceImpl(); |
|
|
|
w.dingDingRobot("审核失败","weapp_audit_fail","机器人测试","居民端"); |
|
|
|
}*/ |
|
|
|
|
|
|
|
public Result<String> sendCodeMsg(OapiRobotSendRequest request,String url,String secret) { |
|
|
|
Long timestamp = System.currentTimeMillis(); |
|
|
|
try { |
|
|
|
OapiRobotSendResponse response = client.execute(request); |
|
|
|
} catch (ApiException e) { |
|
|
|
log.error("机器人生病了......"); |
|
|
|
String stringToSign = timestamp + "\n" + secret; |
|
|
|
Mac mac = Mac.getInstance("HmacSHA256"); |
|
|
|
mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256")); |
|
|
|
byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8")); |
|
|
|
String sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8"); |
|
|
|
log.info("sign为:"+sign); |
|
|
|
url = url.concat("×tamp=" + timestamp + "&sign=" + sign); |
|
|
|
Result<String> stringResult = HttpClientManager.getInstance().sendPostByJSON(url, JSON.toJSONString(request)); |
|
|
|
log.info("robot发送消息结果为:"+stringResult.getData()); |
|
|
|
return stringResult; |
|
|
|
} catch (Exception e) { |
|
|
|
e.printStackTrace(); |
|
|
|
} |
|
|
|
return new Result<String>().error(); |
|
|
|
} |
|
|
|
|
|
|
|
public String getClient(String clientType){ |
|
|
@ -236,7 +278,7 @@ public class WarrantServiceImpl implements WarrantService { |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 方法描述: 类型为enevt的时候,拼接 |
|
|
|
* 方法描述: 类型为event的时候,拼接 |
|
|
|
* @param request |
|
|
|
* @param response |
|
|
|
* @param event |
|
|
@ -247,8 +289,9 @@ public class WarrantServiceImpl implements WarrantService { |
|
|
|
public void replyEventMessage(HttpServletRequest request, HttpServletResponse response, |
|
|
|
String event, String toUserName, String fromUserName) |
|
|
|
throws DocumentException, IOException { |
|
|
|
log.info("================ event + from_callback..................."); |
|
|
|
String content = event + ModuleConstant.FROM_CALLBACK; |
|
|
|
replyTextMessage(request,response,content,toUserName,fromUserName); |
|
|
|
replyTextMessage(request, response, content, toUserName, fromUserName); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -262,15 +305,7 @@ public class WarrantServiceImpl implements WarrantService { |
|
|
|
public void processTextMessage(HttpServletRequest request, HttpServletResponse response, |
|
|
|
String content,String toUserName, String fromUserName) |
|
|
|
throws IOException, DocumentException{ |
|
|
|
if(ModuleConstant.TESTCOMPONENT_MSG_TYPE_TEXT.equals(content)){ |
|
|
|
String returnContent = content+ModuleConstant._CALL_BACK; |
|
|
|
replyTextMessage(request,response,returnContent,toUserName,fromUserName); |
|
|
|
}else if(StringUtils.startsWithIgnoreCase(content, ModuleConstant.QUERY_AUTH_CODE)){ |
|
|
|
response.getWriter().print("");//需在5秒内返回空串表明暂时不回复,然后再立即使用客服消息接口发送消息回复粉丝
|
|
|
|
log.info(String.format(ThirdRunTimeInfoConstant.TEXT_MESSAGE_LOG_INFO,content,content.split(ThirdRedisKeyConstant.COLON)[NumConstant.ONE],fromUserName,toUserName)); |
|
|
|
//接下来客服API再回复一次消息
|
|
|
|
replyApiTextMessage(content.split(ThirdRedisKeyConstant.COLON)[NumConstant.ONE],toUserName); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -289,16 +324,27 @@ public class WarrantServiceImpl implements WarrantService { |
|
|
|
throws DocumentException, IOException { |
|
|
|
Long createTime = System.currentTimeMillis() / NumConstant.ONE_THOUSAND; |
|
|
|
StringBuffer sb = new StringBuffer(512); |
|
|
|
log.info("********************** encryption start.............."); |
|
|
|
sb.append("<xml>"); |
|
|
|
sb.append("<ToUserName><![CDATA["+toUserName+"]]></ToUserName>"); |
|
|
|
sb.append("<FromUserName><![CDATA["+fromUserName+"]]></FromUserName>"); |
|
|
|
sb.append("<CreateTime>"+createTime.toString()+"</CreateTime>"); |
|
|
|
sb.append("<CreateTime><![CDATA["+createTime+"]]></CreateTime>"); |
|
|
|
sb.append("<MsgType><![CDATA[text]]></MsgType>"); |
|
|
|
sb.append("<Content><![CDATA["+content+"]]></Content>"); |
|
|
|
sb.append("</xml>"); |
|
|
|
String replyMsg = sb.toString(); |
|
|
|
log.info(String.format(ThirdRunTimeInfoConstant.SEND_MESSAGE_XML,replyMsg)); |
|
|
|
returnJSON(replyMsg,response); |
|
|
|
WXBizMsgCrypt wxBizMsgCrypt; |
|
|
|
String generate = null; |
|
|
|
try { |
|
|
|
wxBizMsgCrypt = new WXBizMsgCrypt(token,aesKey,componentAppId); |
|
|
|
generate = wxBizMsgCrypt.encryptMsg(replyMsg, String.valueOf(createTime), wxBizMsgCrypt.getRandomStr()); |
|
|
|
PrintWriter pw = response.getWriter(); |
|
|
|
pw.write(generate); |
|
|
|
pw.flush(); |
|
|
|
} catch (AesException e) { |
|
|
|
e.printStackTrace(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@ -319,15 +365,20 @@ public class WarrantServiceImpl implements WarrantService { |
|
|
|
jsonObject.put(ModuleConstant.AUTHORIZATION_CODE, auth_code); |
|
|
|
String authInfo = HttpClientManager.getInstance().sendPostByJSON(WxMaCodeConstant.API_QUERY_AUTH_URL + componentAccessToken, JSON.toJSONString(jsonObject)).getData(); |
|
|
|
HashMap<String,Map> hashMap = JSON.parseObject(authInfo, HashMap.class); |
|
|
|
if (hashMap.containsKey("errcode")){ |
|
|
|
throw new RenException("全网发布接入检测【API文本消息回复失败】"); |
|
|
|
} |
|
|
|
Map map = hashMap.get(ModuleConstant.AUTHORIZATION_INFO); |
|
|
|
AuthorizationInfoResultDTO authorizationInfoResultDTO = ConvertUtils.mapToEntity(map, AuthorizationInfoResultDTO.class); |
|
|
|
String authorizer_access_token = authorizationInfoResultDTO.getAuthorizer_access_token(); |
|
|
|
|
|
|
|
Map<String,Object> msgMap = new HashMap<String,Object>(); |
|
|
|
String msg = auth_code + "_from_api"; |
|
|
|
msgMap.put("content", msg); |
|
|
|
JSONObject json = new JSONObject(); |
|
|
|
json.put("touser",fromUserName); |
|
|
|
json.put("msgtype", "text"); |
|
|
|
json.put("text", "{\"content\":\""+auth_code+ModuleConstant._FROM_API+"\"}"); |
|
|
|
|
|
|
|
json.put("msgtype","text"); |
|
|
|
json.put("text",msgMap); |
|
|
|
String data = HttpClientManager.getInstance().sendPostByJSON(WxMaCodeConstant.SEND_MESSAGE_CUSTOM + authorizer_access_token, JSON.toJSONString(json)).getData(); |
|
|
|
log.info("客服发送接口返回值:"+data); |
|
|
|
} |
|
|
@ -347,7 +398,7 @@ public class WarrantServiceImpl implements WarrantService { |
|
|
|
JsonGenerator generator = objectMapper.getJsonFactory(). |
|
|
|
createJsonGenerator(response.getOutputStream(), encoding); |
|
|
|
objectMapper.writeValue(generator, data); |
|
|
|
} catch (IOException e) { |
|
|
|
} catch (Exception e) { |
|
|
|
e.printStackTrace(); |
|
|
|
} |
|
|
|
} |
|
|
|