对接微信公众号

搭建测试环境

首先使用微信测试号进行测试:  测试号地址

使用调试工具进行接口调试:  微信公众平台接口调试工具

 参考资料: 获取access_token,接收事件推送, 客服接口-发消息

 第一步,接入服务器

 url就是服务器接口地址,token是自定义的,等验证的时候后台要用到,后续微信发的消息都是通过这个接口来接收的。

服务器校验:

    @RequestMapping("receiveWeixin")
    public void receiveWeixin(String signature, String timestamp, String nonce, String echostr,
                              HttpServletRequest request, HttpServletResponse response) {
        try {
            //服务器校验
            String token = "yxg2i1";
            List<String> list = new ArrayList<>();
            list.add(token);
            list.add(timestamp);
            list.add(nonce);
            list = CollectionUtil.sort(list, (o1, o2) -> o1.compareTo(o2));
            String str = CollectionUtil.join(list, "");
            if (!signature.equals(SecureUtil.sha1(str))) {
                return;
            }
            if (StringUtils.isNotEmpty(echostr)) {
                //校验服务器
                response.getOutputStream().write(echostr.getBytes());
                response.getOutputStream().flush();
                return;
            }
    }

 第二步,接收消息,发送消息

配置完服务器,就能接收消息了,比如当用户订阅你的公众号,就能收到一条事件推送,消息的格式是xml的

 这里面有openId,可以通过openid给用户回复客服消息,当然回复客服消息是有限制的,比如只有当用户发送消息,或者关注公众号时才能回复。

    @RequestMapping("receiveWeixin")
    public void receiveWeixin(String signature, String timestamp, String nonce, String echostr,
                              HttpServletRequest request, HttpServletResponse response) {
        try {
            //服务器校验
            String token = "yxg2i1";
            List<String> list = new ArrayList<>();
            list.add(token);
            list.add(timestamp);
            list.add(nonce);
            list = CollectionUtil.sort(list, (o1, o2) -> o1.compareTo(o2));
            String str = CollectionUtil.join(list, "");
            if (!signature.equals(SecureUtil.sha1(str))) {
                return;
            }
            if (StringUtils.isNotEmpty(echostr)) {
                //校验服务器
                response.getOutputStream().write(echostr.getBytes());
                response.getOutputStream().flush();
                return;
            }

            //接收消息
            Document document = XmlUtil.readXML(request.getInputStream());
            Map map = XmlUtil.xmlToMap(document);
            JSONObject json = JSONObject.parseObject(JsonUtil.getJson(map)).getJSONObject("xml");
            String msgType = json.getString("MsgType");
            if (msgType.equals("event")) {
                WeixinPushVO weixinPushVO = JSONObject.parseObject(json.toJSONString(), WeixinPushVO.class);
                if (weixinPushVO.getEvent().equals("subscribe")) {
                    // 下发欢迎消息
                    ThreadUtil.execAsync(() -> weixinConfigService.sendWelcomeMsg(weixinPushVO.getFromUserName()));

                }
            } else if (msgType.equals("text")) {
                WeixinReceiveText weixinReceiveText = JSONObject.parseObject(json.toJSONString(), WeixinReceiveText.class);
                ThreadUtil.execAsync(() -> weixinConfigService.replyMessage(weixinReceiveText.getFromUserName(), weixinReceiveText.getContent()));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

获取access_token,发送消息代码:

@Component
public class WeiXinUtil {
    protected static Logger logger = LoggerFactory.getLogger(WeiXinUtil.class);
    private final String TOKEN_KEY = "WEIXIN_TOKEN:";
    @Autowired
    private RedisTemplate redisTemplate;

    public synchronized String getToken(String appId, String appsecret) {
        String redisKey = TOKEN_KEY + appId;
        String token = (String) redisTemplate.opsForValue().get(redisKey);
        if (StrUtil.isNotEmpty(token)) return token;
        JSONObject params = new JSONObject();
        params.put("grant_type", "client_credential");
        params.put("appid", appId);
        params.put("secret", appsecret);
        String str = HttpUtil.post(WeixinConstants.ACCESS_TOKEN_URL, params.toJSONString());
        JSONObject result = handleResult(str, appId);
        token = result.getString("access_token");
        redisTemplate.opsForValue().set(redisKey, token
                , result.getIntValue("expires_in") - 10 * 60, TimeUnit.SECONDS);
        return token;
    }

    private JSONObject handleResult(String str, String appId) {
        JSONObject result = JSONObject.parseObject(str);
        if (StrUtil.isNotBlank(result.getString("errcode"))) {
            if (result.getString("errcode").equals("0")) {
                return result;
            }
            if (result.getString("errcode").equals("40014")) {
                clearToken(appId);
            }
            throw new ServiceException(StrUtil.format("微信接口出错, errcode: {}, msg: {}"
                    , result.getString("errcode"), result.getString("errmsg")));
        }
        return result;
    }

    public void clearToken(String appId) {
        String redisKey = TOKEN_KEY + appId;
        redisTemplate.delete(redisKey);
    }

    public JSONObject getMenuInfo(String appId, String appsecret) {
        String token = getToken(appId, appsecret);
        String str = HttpUtil.get(StrUtil.format(WeixinConstants.GET_MENU_INFO_URL, token));
        JSONObject result = handleResult(str, appId);
        JSONObject menuInfo = result.getJSONObject("selfmenu_info");
        if (menuInfo == null) {
            menuInfo = new JSONObject();
        }
        return menuInfo;
    }

    public void createMenu(String appId, String appsecret, String menu) {
        String token = getToken(appId, appsecret);
        String str = HttpUtil.post(StrUtil.format(WeixinConstants.CREATE_MENU_URL, token), menu);
        handleResult(str, appId);
    }

    public void customSend(String appId, String appsecret, String openId, String message) {
        String token = getToken(appId, appsecret);
        JSONObject body = new JSONObject();
        body.put("touser", openId);
        body.put("msgtype", "text");
        JSONObject content = new JSONObject();
        body.put("text", content);
        content.put("content", message);
        String str = HttpUtil.post(StrUtil.format(WeixinConstants.CUSTOM_SEND_URL, token), body.toJSONString());
        handleResult(str, appId);
    }
}
public class WeixinConstants {

    /**
     * 获取token
     */
    public static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/stable_token";

    /**
     * 获取菜单
     */
    public static final String GET_MENU_INFO_URL = "https://api.weixin.qq.com/cgi-bin/get_current_selfmenu_info?access_token={}";

    /**
     * 创建菜单
     */
    public static final String CREATE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token={}";

    /**
     * 客服接口-发消息
     */
    public static final String CUSTOM_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={}";
}
public class WeixinBaseVO {
    private String ToUserName;
    private String FromUserName;
    private String CreateTime;
    private String MsgType;
}
public class WeixinPushVO extends WeixinBaseVO {
    private String Event;
}
public class WeixinReceiveText extends WeixinBaseVO {
    private String Content;
    private String MsgId;
    private String MsgDataId;
    private String Idx;
}
public class WeixinConfigServiceImpl implements WeixinConfigService {
    @Autowired
    private WeiXinUtil weiXinUtil;

    @Override
    public void sendWelcomeMsg(String openId) {
        weiXinUtil.customSend("自己的appid", "自己的appsecret", openId, "欢迎");
    }

    @Override
    public void replyMessage(String openId, String content) {
        weiXinUtil.customSend("自己的appid", "自己的appsecret", openId, "你好啊");
    }
}

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值