微信第三方平台集成公众号发送模板消息

最近老板下发了个任务,有一个业务是整合用户的微信公众号(服务号),然后在我们的erp系统里给下家客户发送模板消息,找了一下发现微信第三方平台可以实现,那就干起来。

先在微信开放平台,申请一个第三方平台服务。
然后通过下面几步实现消息推送

1 、微信验证接口,拿到 ticket
2 、拿到调用令牌 component_access_token
3 、获取预授权码 pre_auth_code
4 、扫码授权,获取授权码 auth_code
5 、通过授权码拿到调用令牌(authorizer_access_token)和刷新令牌(authorizer_refresh_token)
6 、通过 authorizer_access_token 实现消息推送

1、验证接口代码

@RequestMapping("getTicket")
    public String componentVerifyTicket(HttpServletRequest request, HttpServletResponse response) throws Exception{
        log.info("接收component_verify_ticket 或 authorized事件");
        String nonce = request.getParameter("nonce");
        String timestamp = request.getParameter("timestamp");
        String msgSignature = request.getParameter("msg_signature");

        

StringBuilder sb = new StringBuilder();
        BufferedReader in = request.getReader();
        String line;
        while((line = in.readLine()) != null) {
            sb.append(line);
        }
        String postData = sb.toString();
        log.info("nonce: " + nonce);
        log.info("timestamp: " + timestamp);
        log.info("msgSignature: " + msgSignature);
        log.info("postData: " + postData);
        getComponentVerifyTicket(timestamp, nonce, msgSignature, postData);

        return "success";
    }
public static void getComponentVerifyTicket(String timestamp, String nonce, String msgSignature, String postData) throws Exception {
        // 需要加密的明文
        // COMPONENT_TOKEN  token
        // aesKey   加密密钥
        WXBizMsgCrypt pc = new WXBizMsgCrypt(COMPONENT_TOKEN, aesKey, appId);

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
        dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
        dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
        dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
        dbf.setXIncludeAware(false);
        dbf.setExpandEntityReferences(false);
        DocumentBuilder db = dbf.newDocumentBuilder();
        StringReader sr = new StringReader(postData);
        InputSource is = new InputSource(sr);
        Document document = db.parse(is);

        Element root = document.getDocumentElement();
        NodeList nodelist1 = root.getElementsByTagName("Encrypt");
        String encrypt = nodelist1.item(0).getTextContent();

        String format = "<xml><ToUserName><![CDATA[toUser]]></ToUserName><Encrypt><![CDATA[%1$s]]></Encrypt></xml>";
        String fromXML = String.format(format, encrypt);

        String result = pc.decryptMsg(msgSignature, timestamp, nonce, fromXML);
        log.info("解密后: " + result);


        Map<String, String> map = XMLUtil.doXMLParse(result);
        String componentVerifyTicket = map.get("ComponentVerifyTicket");
        System.out.println("获取ticket====="+componentVerifyTicket);
       
    }

XMLUtil

/**
     * 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
     *
     * @param strxml
     * @return
     * @throws JDOMException
     * @throws IOException
     */
    public static Map doXMLParse(String strxml) throws JDOMException, IOException {
        strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");

        if (null == strxml || "".equals(strxml)) {
            return null;
        }

        Map m = new HashMap();

        InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));
        SAXBuilder builder = new SAXBuilder();
        Document doc = builder.build(in);
        Element root = doc.getRootElement();
        List list = root.getChildren();
        Iterator it = list.iterator();
        while (it.hasNext()) {
            Element e = (Element) it.next();
            String k = e.getName();
            String v = "";
            List children = e.getChildren();
            if (children.isEmpty()) {
                v = e.getTextNormalize();
            } else {
                v = XMLUtil.getChildrenText(children);
            }

            m.put(k, v);
        }

        //关闭流
        in.close();

        return m;
    }

    /**
     * 获取子结点的xml
     *
     * @param children
     * @return String
     */
    public static String getChildrenText(List children) {
        StringBuffer sb = new StringBuffer();
        if (!children.isEmpty()) {
            Iterator it = children.iterator();
            while (it.hasNext()) {
                Element e = (Element) it.next();
                String name = e.getName();
                String value = e.getTextNormalize();
                List list = e.getChildren();
                sb.append("<" + name + ">");
                if (!list.isEmpty()) {
                    sb.append(XMLUtil.getChildrenText(list));
                }
                sb.append(value);
                sb.append("</" + name + ">");
            }
        }

        return sb.toString();
    }

2、拿到调用令牌 component_access_token


微信文档链接:
https://developers.weixin.qq.com/doc/oplatform/openApi/OpenApiDoc/ticket-token/getComponentAccessToken.html

通过上一步拿到的ticket,传入第三方的appid和appsecret ,调用微信接口获取第三方的调用令牌:
component_access_token

https://api.weixin.qq.com/cgi-bin/component/api_component_token

{
  "component_appid":  "*****" ,	//	第三方平台appid
  "component_appsecret":  "*****",	//	密钥
  "component_verify_ticket":""

}

3、拿到component_access_token后再次调用接口获取预授权码


微信文档:
https://developers.weixin.qq.com/doc/oplatform/openApi/OpenApiDoc/ticket-token/getPreAuthCode.html


ACCESS_TOKEN: 就是上一步获取到的component_access_token


https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?access_token=ACCESS_TOKEN


{
   "component_appid": "wxe7986597a6b2a7e4"
  
}

在这里插入图片描述

4、通过预授权码生成链接,管理员扫码后授权获取授权码


将上一步获取到的预授权吗填入下面:
https://mp.weixin.qq.com/cgi-bin/componentloginpage?
component_appid=wxe7986597a6b2a7e4
&pre_auth_code=preauthcode@@@IbLBSSV_2LkGjtZKk8aPCFc4JI2Wzzawfj6tse60aktFdrTD1oP_nWNULntkhPjHKvp3Ae1GnL4sReu_7A2zjA
&redirect_uri=http://ys99.top/bed/wx/getAuthCode

component_appid:第三方平台的appid
pre_auth_code:上一步拿到的预授权码
redirect_uri:授权后重定向地址,接口里拿到正式的授权码 queryauthcode

然后通过a链接打开就可以了

5、通过授权码获取第三方公众号的授权令牌 authorizer_access_token

https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token=******

{
    "component_appid":"wxe7986597a6b2a7e4",
    "authorization_code":"queryauthcode@@@qCsx1osdrsQRn7LoiLVOIz3Ut273KrqYJlT9cdbQS3lCupjsPvFcaAbaT3zHG2EDhCgJ3dUw94gbgrOOTFhl_g"
}

在这里插入图片描述

6、通过上一步获取到了公众号的调用令牌authorizer_access_token


后续的公众号所有操作都使用这个令牌

https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=
66_Ew0rFnSUMD56EEsZBk8aVTteynjtjojSliKpAIvBd8AR750VvN0O3puNI2srbPAIlkesBainkEBJTT4dRQWVQbxf2wuFB_om-mgJ-AXxZ26gJKjIAdPpNIQzkUOX9x8TJllWGBqU2Fr7oR16OCNaAHDAOZ

access_token:就是上一步获取到的调用令牌
touser:用户在微信公众号的openid
template_id:在公众号的消息模板id

在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程有财

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值