package com.xiaopeng.pushMessage.utils; import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpResponse; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.xiaopeng.api.dto.account.UserResourcesDto; import com.xiaopeng.api.feignClient.account.SSOClient; import com.xiaopeng.api.vo.account.WechatAccessTokenResVo; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.core.exception.ServiceException; import com.xiaopeng.common.core.utils.StringUtils; import com.xiaopeng.common.redis.service.RedisService; import com.xiaopeng.pushMessage.model.Category; import com.xiaopeng.pushMessage.model.MessageTemplate; import com.xiaopeng.pushMessage.model.PubTemplateKeywords; import com.xiaopeng.pushMessage.model.PubTemplatetitles; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.*; import java.util.concurrent.TimeUnit; /** * 订阅消息 */ @Slf4j @Component public class SubscribeMessageUtil { @Value("${wx.appletsAppid:1234}") private String wxAppletsAppid; @Value("${wx.appletsAppSecret:123456}") private String wxAppletsAppSecret; @Value("${sso.appid}") private String appId; @Autowired private RedisService redisService; @Resource private SSOClient ssoClient; /** * 获取微信小程序token * @return */ public String getWxAppletsAccessToken() { String accessToken = redisService.getCacheObject("wxAppletsAccessToken"); if(StringUtils.isNotEmpty(accessToken)){ return accessToken; } String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + wxAppletsAppid + "&secret=" + wxAppletsAppSecret; HttpRequest get = HttpUtil.createGet(url); HttpResponse execute = get.execute(); if(execute.getStatus() != 200){ log.info("获取微信小程序access_token失败:{}", execute.body()); throw new RuntimeException("获取微信小程序access_token失败"); } JSONObject jsonObject = JSON.parseObject(execute.body()); redisService.setCacheObject("wxAppletsAccessToken", jsonObject.getString("access_token"), 7000L, TimeUnit.SECONDS); return jsonObject.getString("access_token"); } /** * 小程序使用jscode获取openid * @param jscode * @return */ public Map code2Session(String jscode) { String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + wxAppletsAppid + "&secret=" + wxAppletsAppSecret + "&js_code=" + jscode + "&grant_type=authorization_code"; HttpRequest get = HttpUtil.createGet(url); HttpResponse execute = get.execute(); if(execute.getStatus() != 200){ log.info("小程序使用jscode获取openid失败:{}", execute.body()); throw new RuntimeException("小程序使用jscode获取openid失败"); } JSONObject jsonObject = JSON.parseObject(execute.body()); int errcode = jsonObject.getIntValue("errcode"); Map map = new HashMap<>(); if(errcode == 0){//成功 map.put("openid", jsonObject.getString("openid")); map.put("sessionKey", jsonObject.getString("session_key")); map.put("unionid", jsonObject.getString("unionid")); return map; } throw new RuntimeException(jsonObject.getString("errmsg")); } /** * 获取消息类目 * @return */ public List getCategory(){ String url = "https://api.weixin.qq.com/wxaapi/newtmpl/getcategory?access_token=" + getWxAppletsAccessToken(); HttpRequest get = HttpUtil.createGet(url); HttpResponse execute = get.execute(); if(execute.getStatus() != 200){ log.info("获取消息类目失败:{}", execute.body()); throw new RuntimeException("获取消息类目失败"); } JSONObject jsonObject = JSON.parseObject(execute.body()); Integer errcode = jsonObject.getInteger("errcode"); if(0 != errcode){ log.info("获取消息类目失败:{}", jsonObject.getString("errmsg")); throw new RuntimeException(jsonObject.getString("errmsg")); } JSONArray data = jsonObject.getJSONArray("data"); List categories = data.toJavaList(Category.class); return categories; } /** * 获取所属类目下的公共模板 * @param ids * @return */ public List getPubTemplateTitles(String ids){ List pubTemplatetitles = new ArrayList<>(); Integer start = 0; while (true){ String url = "https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatetitles?access_token=" + getWxAppletsAccessToken(); Map params = new HashMap<>(); params.put("ids", ids); params.put("start", start + ""); params.put("limit", 30); HttpRequest get = HttpUtil.createGet(url); get.form(params); HttpResponse execute = get.execute(); if(execute.getStatus() != 200){ log.info("获取公共模板失败:{}", execute.body()); throw new RuntimeException("获取公共模板失败"); } JSONObject jsonObject = JSON.parseObject(execute.body()); Integer errcode = jsonObject.getInteger("errcode"); if(0 != errcode){ log.info("获取公共模板失败:{}", jsonObject.getString("errmsg")); throw new RuntimeException(jsonObject.getString("errmsg")); } JSONArray data = jsonObject.getJSONArray("data"); List pubTemplatetitles1 = data.toJavaList(PubTemplatetitles.class); if(pubTemplatetitles1.size() == 0){ break; } pubTemplatetitles.addAll(pubTemplatetitles1); start += 30; } return pubTemplatetitles; } /** * 获取关键词列表 * @param tid * @return */ public List getPubTemplateKeywords(String tid){ String url = "https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatekeywords?access_token=" + getWxAppletsAccessToken(); Map params = new HashMap<>(); params.put("tid", tid); HttpRequest get = HttpUtil.createGet(url); get.form(params); HttpResponse execute = get.execute(); if(execute.getStatus() != 200){ log.info("获取关键词列表失败:{}", execute.body()); throw new RuntimeException("获取关键词列表失败"); } JSONObject jsonObject = JSON.parseObject(execute.body()); Integer errcode = jsonObject.getInteger("errcode"); if(0 != errcode){ log.info("获取关键词列表失败:{}", jsonObject.getString("errmsg")); throw new RuntimeException(jsonObject.getString("errmsg")); } JSONArray data = jsonObject.getJSONArray("data"); List pubTemplateKeywords = data.toJavaList(PubTemplateKeywords.class); return pubTemplateKeywords; } /** * 获取个人模板列表 * @return */ public List getMessageTemplateList(){ String url = "https://api.weixin.qq.com/wxaapi/newtmpl/gettemplate?access_token=" + getWxAppletsAccessToken(); HttpRequest get = HttpUtil.createGet(url); HttpResponse execute = get.execute(); if(execute.getStatus() != 200){ log.info("获取个人模板列表失败:{}", execute.body()); throw new RuntimeException("获取个人模板列表失败"); } JSONObject jsonObject = JSON.parseObject(execute.body()); Integer errcode = jsonObject.getInteger("errcode"); if(0 != errcode){ log.info("获取个人模板列表失败:{}", jsonObject.getString("errmsg")); throw new RuntimeException(jsonObject.getString("errmsg")); } JSONArray data = jsonObject.getJSONArray("data"); List messageTemplates = data.toJavaList(MessageTemplate.class); return messageTemplates; } /** * 添加消息模板 * @param tid 模板标题 id * @param kidList 开发者自行组合好的模板关键词列表,关键词顺序可以自由搭配(例如 [3,5,4] 或 [4,5,3]),最多支持5个,最少2个关键词组合 * @param sceneDesc 服务场景描述,15个字以内 * @return */ public String addTemplate(String tid, String[] kidList, String sceneDesc){ String url = "https://api.weixin.qq.com/wxaapi/newtmpl/addtemplate?access_token=" + getWxAppletsAccessToken(); Map params = new HashMap<>(); params.put("tid", tid); params.put("kidList", kidList); params.put("sceneDesc", sceneDesc); HttpRequest post = HttpUtil.createPost(url); post.body(JSON.toJSONString(params)); HttpResponse execute = post.execute(); if(execute.getStatus() != 200){ log.info("添加消息模板失败:{}", execute.body()); throw new RuntimeException("添加消息模板失败"); } JSONObject jsonObject = JSON.parseObject(execute.body()); Integer errcode = jsonObject.getInteger("errcode"); if(0 != errcode){ log.info("添加消息模板失败:{}", jsonObject.getString("errmsg")); throw new RuntimeException(jsonObject.getString("errmsg")); } String priTmplId = jsonObject.getString("priTmplId"); return priTmplId; } /** * 删除模板 * @param priTmplId 模板id * @return */ public R delTemplate(String priTmplId){ String url = "https://api.weixin.qq.com/wxaapi/newtmpl/deltemplate?access_token=" + getWxAppletsAccessToken(); Map params = new HashMap<>(); params.put("priTmplId", priTmplId); HttpRequest post = HttpUtil.createPost(url); post.body(JSON.toJSONString(params)); HttpResponse execute = post.execute(); if (execute.getStatus() != 200){ log.info("删除模板失败:{}", execute.body()); throw new RuntimeException("删除模板失败"); } JSONObject jsonObject = JSON.parseObject(execute.body()); Integer errcode = jsonObject.getInteger("errcode"); if(0 != errcode){ log.info("删除模板失败:{}", jsonObject.getString("errmsg")); throw new RuntimeException(jsonObject.getString("errmsg")); } return R.ok(); } String getToken(Boolean isRefresh){ WechatAccessTokenResVo wechatAccessToken = ssoClient.getWechatAccessToken(appId, wxAppletsAppid, isRefresh); if(null == wechatAccessToken){ log.info("获取微信access_token失败"); throw new ServiceException("获取微信access_token失败"); } if(0 != wechatAccessToken.getCode()){ log.info("获取微信access_token失败:{}", wechatAccessToken.getMsg()); throw new ServiceException("获取微信access_token失败"); } String accessToken = wechatAccessToken.getData().getAccessToken(); return accessToken; } /** * 发送消息 * @param template_id 所需下发的订阅模板id * @param page 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转 * @param touser 接收者(用户)的 openid * @param data 模板内容,格式形如 { "key1": { "value": any }, "key2": { "value": any } }的object * @param miniprogram_state 跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版 * @param lang 进入小程序查看”的语言类型,支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为zh_CN * @return */ public R send(String template_id, String page, String touser, String data, String miniprogram_state, String lang){ String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + getToken(false); Map params = new HashMap<>(); params.put("template_id", template_id); params.put("page", page); params.put("touser", touser); params.put("data", JSON.parseObject(data)); params.put("miniprogram_state", miniprogram_state); params.put("lang", lang); HttpRequest post = HttpUtil.createPost(url); post.body(JSON.toJSONString(params)); HttpResponse execute = post.execute(); if(execute.getStatus() != 200){ log.info("发送消息失败:{}", execute.body()); return R.fail(execute.body()); } JSONObject jsonObject = JSON.parseObject(execute.body()); Integer errcode = jsonObject.getInteger("errcode"); if(0 != errcode){ log.info("发送消息失败:{}", jsonObject.getString("errmsg")); return R.fail(jsonObject.getString("errmsg")); } return R.ok(); } }