package com.iformall.controller; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.iformall.controller.base.BaseController; import com.iformall.domain.po.WxAppinfo; import com.iformall.domain.po.WxComponentVerifyTicket; import com.iformall.domain.po.WxWeappAuditStatus; import com.iformall.enums.EnumAppType; import com.iformall.enums.EnumWeappAuditStatus; import com.iformall.service.*; import com.iformall.service.toutiao.FmTtOpenService; import com.iformall.service.toutiao.api.bean.TtOpenNotifyMsg; import com.iformall.utils.DateUtils; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.json.GsonHelper; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import reactor.core.publisher.Flux; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Map; @Controller @RequestMapping("/ttOpen") @Api(description = "头条第三方开放平台回调相关接口") public class TtCalllbackController extends BaseController { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired protected FmTtOpenService openService; @Autowired private WxComponentVerifyTicketService componentVerifyTicketService; @Autowired private WxAuthorizerInfoService authorizerInfoService; @Autowired private WxWeappAuditStatusService weappAuditStatusService; @Autowired private WxAppinfoService appinfoService; @Autowired private MailService mailService; @Autowired private String fmAuditEmails; @PostMapping(value = "/notify") @ApiOperation("接收ticket回调") @ResponseBody public String receiveTicket(@RequestBody Map params) throws IOException { logger.info("[" + getIpAddr() + "]接收微信回调 /ttOpen/notify"); String nonce = params.get("Nonce"); String timestamp = params.get("TimeStamp"); // String signature = params.get("signature"); String encrypt = params.get("Encrypt"); String msgSignature = params.get("MsgSignature"); if (!openService.getTtOpenComponentService().checkSignature(timestamp, nonce, encrypt, msgSignature)) { throw new IllegalArgumentException("非法请求,可能属于伪造的请求!"); } // aes加密的消息, 解密 TtOpenNotifyMsg openTicket = openService.getTtOpenComponentService().decrypt(encrypt); // 处理 handleTicket(openTicket); return "success"; } /** * 处理ticket消息 * @param * @return */ private void handleTicket(TtOpenNotifyMsg ticket) { try { String out = openService.getTtOpenComponentService().route(ticket); this.logger.info("组装回复信息:{}", out); } catch (WxErrorException e) { this.logger.error("notify", e); } if (StringUtils.isNotBlank(ticket.getMsgType()) && StringUtils.equalsIgnoreCase(ticket.getMsgType(), "Ticket")) { logger.info("------------推送ticket通知"); // 保存component_verify_ticket componentVerifyTicketService.saveOrUpdate(new WxComponentVerifyTicket() { { setComponentVerifyTicket(ticket.getTicket()); setCreateTime(DateUtils.stringToDate(ticket.getCreateTime(),"yyyy-MM-dd HH:mm:ss")); setComponentAppid(ticket.getComponentAppId()); setDeadline(new Date(Long.valueOf(System.currentTimeMillis() + (60 * 60 * 1000)))); } }); }else if(StringUtils.isNotBlank(ticket.getEvent()) && StringUtils.equalsIgnoreCase(ticket.getEvent(), "AUTHORIZED")){ logger.info("------------授权成功通知"); }else if(StringUtils.isNotBlank(ticket.getEvent()) && StringUtils.equalsIgnoreCase(ticket.getEvent(), "UNAUTHORIZED")){ logger.info("------------解除授权成功通知"); }else if(StringUtils.isNotBlank(ticket.getEvent()) && StringUtils.equalsIgnoreCase(ticket.getEvent(), "UPDATE_AUTHORIZED")){ logger.info("------------找回授权码通知"); }else if(StringUtils.isNotBlank(ticket.getEvent()) && StringUtils.equalsIgnoreCase(ticket.getEvent(), "PACKAGE_AUDIT")){ logger.info("------------审核结果通知"); handleWeappAuditedMessage(ticket); }else{ logger.info("------------未知通知"); } } /** * 处理小程序审核消息 * @param * @return */ private boolean handleWeappAuditedMessage(TtOpenNotifyMsg notifyMsg) { WxWeappAuditStatus auditStatus = weappAuditStatusService.getByAppId(notifyMsg.getAppId()); if(auditStatus == null){ logger.error("------------审核结果通知未找到审核小程序 "+notifyMsg.getAppId()); } JsonArray auditResults = notifyMsg.getAuditResults(); int status = 0; String reason = ""; for (int i = 0;i < auditResults.size(); i++) { JsonObject obj = auditResults.get(i).getAsJsonObject(); if(("douyin").equals(GsonHelper.getString(obj,"hostName"))){ status = GsonHelper.getInteger(obj,"status"); reason = obj.get("reason").toString(); break; } } if (status == 1) {//通过 auditStatus.setAuditStatus(EnumWeappAuditStatus.SUCCESS.getCode()); auditStatus.setAuditErrCode(""); } else { auditStatus.setAuditStatus(EnumWeappAuditStatus.FAIL.getCode()); auditStatus.setAuditErrCode(reason); } auditStatus.setAuditTime(DateUtils.stringToDate(notifyMsg.getEventTime(),"yyyy-MM-dd HH:mm:ss")); weappAuditStatusService.updateStatus(auditStatus); // 发邮件 WxAppinfo appinfo = appinfoService.getByAppId(notifyMsg.getAppId()); if (appinfo != null) { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式 StringBuilder titleSB = new StringBuilder(); if (appinfo.getType().equals(EnumAppType.C.getCode())) { titleSB.append("C端小程序"); } else if (appinfo.getType().equals(EnumAppType.B.getCode())) { titleSB.append("B端小程序"); } else if (appinfo.getType().equals(EnumAppType.MP_S.getCode())) { titleSB.append("公众号-服务号"); } else if (appinfo.getType().equals(EnumAppType.MP_P.getCode())) { titleSB.append("公众号-订阅号"); } titleSB.append(appinfo.getName()); if (status == 1) { titleSB.append("审核通过"); } else { titleSB.append("审核未通过"); } StringBuilder sb = new StringBuilder(); sb.append(df.format(new Date())).append("\n"); if (status == 1) { sb.append("审核通过\n"); } else { sb.append("审核未通过\n").append("原因").append(reason); } String[] receivers = fmAuditEmails.split(","); //发送邮件 mailService.sendSimpleMail(receivers, titleSB.toString(), sb.toString()); } return false; } @PostMapping(value = "/{appId}/callback") @ApiOperation("消息回调") public void callback(@PathVariable("appId") String appId, @RequestBody Map params) throws IOException { logger.info("[" + getIpAddr() + "]接收微信APP回调 /{appId}/callback"); String nonce = params.get("Nonce"); String timestamp = params.get("TimeStamp"); // String signature = params.get("signature"); String encrypt = params.get("Encrypt"); String msgSignature = params.get("MsgSignature"); if (!openService.getTtOpenComponentService().checkSignature(timestamp, nonce, encrypt, msgSignature)) { throw new IllegalArgumentException("非法请求,可能属于伪造的请求!"); } // aes加密的消息, 解密 TtOpenNotifyMsg openTicket = openService.getTtOpenComponentService().decrypt(encrypt); handleTicket(openTicket); } // private void wechatWriteSuccess(PrintWriter printWriter) { // printWriter.print("success"); // printWriter.flush(); // printWriter.close(); // } // /** // * 测试账号特殊处理 // * @param appId // * @param response // * @param inMessage // * @throws IOException // */ // private void handleWechatTest(@PathVariable("appId") String appId, HttpServletResponse response, WxMpXmlMessage inMessage) throws IOException { // String out; // try { // if (StringUtils.equals(inMessage.getMsgType(), "text")) { // if (StringUtils.equals(inMessage.getContent(), "TESTCOMPONENT_MSG_TYPE_TEXT")) { // out = WxOpenXmlMessage.wxMpOutXmlMessageToEncryptedXml( // WxMpXmlOutMessage.TEXT().content("TESTCOMPONENT_MSG_TYPE_TEXT_callback") // .fromUser(inMessage.getToUser()) // .toUser(inMessage.getFromUser()) // .build(), // openService.getWxOpenConfigStorage() // ); // } else if (StringUtils.startsWith(inMessage.getContent(), "QUERY_AUTH_CODE:")) { // String msg = inMessage.getContent().replace("QUERY_AUTH_CODE:", "") + "_from_api"; // WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(msg).toUser(inMessage.getFromUser()).build(); // openService.getWxOpenComponentService().getWxMpServiceByAppid(appId).getKefuService().sendKefuMessage(kefuMessage); // } // } else if (StringUtils.equals(inMessage.getMsgType(), "event")) { // WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(inMessage.getEvent() + "from_callback").toUser(inMessage.getFromUser()).build(); // openService.getWxOpenComponentService().getWxMpServiceByAppid(appId).getKefuService().sendKefuMessage(kefuMessage); // } // } catch (WxErrorException e) { // logger.error("callback", e); // } // } // // private String getRequestXML(HttpServletRequest request) throws IOException { // InputStream inStream = request.getInputStream(); // ByteArrayOutputStream outSteam = new ByteArrayOutputStream(); // byte[] buffer = new byte[1024]; // int len = 0; // while ((len = inStream.read(buffer)) != -1) { // outSteam.write(buffer, 0, len); // } // String resultxml = new String(outSteam.toByteArray(), Charset.forName("UTF-8")); // logger.info(resultxml); // // outSteam.close(); // inStream.close(); // return resultxml; // } // // private void getThreadCount( int i) { // ThreadGroup group = Thread.currentThread().getThreadGroup(); // ThreadGroup topGroup = group; // // 遍历线程组树,获取根线程组 // while (group != null) { // topGroup = group; // group = group.getParent(); // } // // 激活的线程数加倍 // int activeCount = topGroup.activeCount(); // // copy into a list that is the exact size // logger.info("Thread list size == " + i + " : " + activeCount); // // } // // // @GetMapping(value = "/createOpenPlatform") // @ApiOperation("创建微信开放平台") // public ResultData createOpenPlatform(@RequestParam(value = "appId") String appId) { // Gson gson = new GsonBuilder().create(); // try { // WxOpenCreateResult ret = openService.getWxOpenComponentService().createOpenAccount(appId); // logger.info(ret.toString()); // if (ret.isSuccess()) { // WxAuthorizerInfo authorizerInfo = authorizerInfoService.getByAppId(appId); // if (authorizerInfo != null) { // authorizerInfo.setId(authorizerInfo.getId()); // authorizerInfo.setOpenAppid(ret.getOpenAppid()); // authorizerInfoService.updateOpenAppid(authorizerInfo); // } // } // return new ResultData(ret.toString()); // } catch (WxErrorException e) { // logger.error(e.getMessage()); // return new ResultData(Result.ERROR, e.getMessage()); // } // } // // @GetMapping(value = "/bindOpenPlatform") // @ApiOperation("绑定微信开放平台") // public ResultData bindOpenPlatform(@RequestParam(value = "appId") String appId, @RequestParam(value = "openAppId") String openAppId) { // Gson gson = new GsonBuilder().create(); // try { // Boolean ret = openService.getWxOpenComponentService().bindOpenAccount(appId, openAppId); // if (ret) { // WxAuthorizerInfo authorizerInfo = authorizerInfoService.getByAppId(appId); // if (authorizerInfo != null) { // authorizerInfo.setId(authorizerInfo.getId()); // authorizerInfo.setOpenAppid(openAppId); // authorizerInfoService.updateOpenAppid(authorizerInfo); // } // return new ResultData(); // } // return new ResultData(Result.ERROR, ret.toString()); // } catch (WxErrorException e) { // logger.error(e.getMessage()); // return new ResultData(Result.ERROR, e.getMessage()); // } // } // // @GetMapping(value = "/unbindOpenPlatform") // @ApiOperation("解绑微信开放平台") // public ResultData unbindOpenPlatform(@RequestParam(value = "appId") String appId, @RequestParam(value = "openAppId") String openAppId) { // Gson gson = new GsonBuilder().create(); // try { // Boolean ret = openService.getWxOpenComponentService().unbindOpenAccount(appId, openAppId); // if (ret) { // WxAuthorizerInfo authorizerInfo = new WxAuthorizerInfo(); // authorizerInfo.setAuthorizerAppid(appId); // authorizerInfoService.removeOpenAppid(authorizerInfo); // return new ResultData(); // } // return new ResultData(Result.ERROR, ret.toString()); // } catch (WxErrorException e) { // logger.error(e.getMessage()); // return new ResultData(Result.ERROR, e.getMessage()); // } // } // // @GetMapping(value = "/getOpenPlatform") // @ApiOperation("获取微信开放平台appId") // public ResultData getOpenPlatform(@RequestParam(value = "appId") String appId) { // Gson gson = new GsonBuilder().create(); // try { // WxOpenGetResult ret = openService.getWxOpenComponentService().getOpenAccount(appId); // logger.info(ret.toString()); // if (ret.isSuccess()) { // WxAuthorizerInfo authorizerInfo = authorizerInfoService.getByAppId(appId); // if (authorizerInfo != null) { // if(StringUtils.isBlank(authorizerInfo.getOpenAppid()) && StringUtils.isNotBlank(ret.getOpenAppid())) { // authorizerInfo.setId(authorizerInfo.getId()); // authorizerInfo.setOpenAppid(ret.getOpenAppid()); // authorizerInfoService.updateOpenAppid(authorizerInfo); // } // } // return new ResultData(ret.getOpenAppid()); // } // return new ResultData(Result.ERROR, ret.toString()); // } catch (WxErrorException e) { // logger.error(e.getMessage()); // return new ResultData(Result.ERROR, e.getMessage()); // } // } // // @GetMapping(value = "/clearQuota") // @ApiOperation("代公众号清零quota,每个公众号每个月有10次清零机会,包括在微信公众平台上的清零以及调用API进行清零") // public ResultData clearQuota(@RequestParam(value = "appId") String appId) { // try { // openService.getWxOpenComponentService().getWxMpServiceByAppid(appId).clearQuota(appId); // return new ResultData(); // } catch (WxErrorException e) { // logger.error(e.getMessage()); // return new ResultData(Result.ERROR, e.getMessage()); // } // } // // @GetMapping(value = "/getAuthorizerList") // @ApiOperation("拉取当前所有已授权的帐号基本信息") // public ResultData getAuthorizerList() { // try { // WxOpenAuthorizerListResult authorizerListResult = openService.getWxOpenComponentService().getAuthorizerList(0, 100); // logger.info("getAuthorizerList: " + authorizerListResult); // if(authorizerListResult.getTotalCount() > 0) { // for (Map data : authorizerListResult.getList()) { // String appId = data.get("authorizer_appid"); // String refreshToken = data.get("refresh_token"); // Long authTime = Long.valueOf(data.get("auth_time")); // Date authDate = new Date(authTime*1000); // // if(StringUtils.isBlank(refreshToken)) { // continue; // } // // WxAuthorizerInfo authorizerInfo = new WxAuthorizerInfo(); // authorizerInfo.setAuthorizerAppid(appId); // authorizerInfo.setRefreshToken(refreshToken); // authorizerInfo.setAuthTime(authDate); // authorizerInfoService.updateAuthAppidInfo(authorizerInfo); // // openService.getWxOpenComponentService().getWxOpenConfigStorage().setAuthorizerRefreshToken(appId, refreshToken); // } // } // return new ResultData(authorizerListResult.toString()); // } catch (WxErrorException e) { // logger.error(e.getMessage()); // return new ResultData(Result.ERROR, e.getMessage()); // } // } }