公众号接口配置 - CSDN
精华内容
参与话题
  • 微信公众号接口配置信息详解

    千次阅读 2020-06-12 14:06:52
    当回调接口没有上面的代码时,接口配置信息修改后保存提示配置失败 需要在项目中运行一下代码接口,才能实现接口配置 回调接口代码: package com.huawei.test; import java.io.IOException; import java.io....

    微信测试号页面

    这里写图片描述

    当回调接口没有上面的代码时,接口配置信息修改后保存提示配置失败

    需要在项目中运行一下代码接口,才能实现接口配置

    回调接口代码:

    package com.huawei.test;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.Arrays;
    import java.util.List;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.huawei.interfaces.tools.StrUtil;
    import com.umpay.api.util.SignUtil;
    
    import edu.emory.mathcs.backport.java.util.Collections;
    
    
    public class TestAction extends HttpServlet
    {
        private static final long serialVersionUID = 1L;
    
    public static final String TOKEN = "123456";  
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException
    {
        doPost(req, resp);
    }
    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException
    {
        
        String signature = request.getParameter("signature");  
        // 时间戳  
        String timestamp = request.getParameter("timestamp");  
        // 随机数  
        String nonce = request.getParameter("nonce");  
        // 随机字符串  
        String echostr = request.getParameter("echostr");  
    
        PrintWriter out = response.getWriter();  
        // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败  
        if (checkSignature(signature, timestamp, nonce) == signature ) {  
            out.write(echostr);  
            System.out.println("微信服务验证成功!"+echostr);  
        }else {  
             out.print(echostr);  
             System.out.println("微信服务验证失败!"+echostr);  
        }  
        out.flush();  
        out.close();  
    }
    
    public static String checkSignature(String signature ,String timestamp, String nonce)
    {
        String[] src = {TOKEN,timestamp,nonce};
        List<String> list =Arrays.asList(src);
        Collections.sort(list);
        
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < list.size(); i++)
        {
            sb.append(list.get(i));
        }
        return StrUtil.SHA1(sb.toString());
        
    }
    
     /**
         * 
         * @param decript
         * @return
         */
        public static String SHA1(String decript) {
            try {
                MessageDigest digest = MessageDigest.getInstance("SHA-1");
                digest.update(decript.getBytes());
                byte messageDigest[] = digest.digest();
                // Create Hex String
                StringBuffer hexString = new StringBuffer();
                // 字节数组转换为 十六进制 数
                for (int i = 0; i < messageDigest.length; i++) {
                    String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
                    if (shaHex.length() < 2) {
                        hexString.append(0);
                    }
                    hexString.append(shaHex);
                }
                return hexString.toString();
    
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }
    }
    
    展开全文
  • 微信公众号开发(一)服务器及接口配置

    万次阅读 多人点赞 2019-05-22 09:21:41
    微信公众号开发(一)服务器及接口配置 关于微信公众号中的订阅号和服务的区别这里不多加讨论,网上有很多资源可以搜到,这里直接进入正题,如果是个人开发者,这里建议使用测试号进行开发学习,测试号的权限要比...

    微信公众号开发(一)服务器及接口的配置

    关于微信公众号中的订阅号和服务的区别这里不多加讨论,网上有很多资源可以搜到,这里直接进入正题,如果是个人开发者,这里建议使用测试号进行开发学习,测试号的权限要比个人订阅号要多的多,而本篇博客也是基于测试号进行开发的。

     

    在开始微信号开发之前需要准备好两样东西,1、需要一个测试号,2、需要一个拥有域名的服务器,下面将分别介绍怎样获取这两样东西。

    1、测试号

    点击此链接测试号登录可直接用微信扫一扫注册一个测试号,相应的界面如下所示

     

    进入测试号界面之后可以获得一些开发所需要的东西,以及关注者列表和开发权限等,如下所示

     

    2、服务器

    微信号开发需要一个第三方服务器来和微信服务器沟通,这里我使用的是一个百度云的BAE虚拟主机,理由有以下几点:

    1、性价比高,该主机一天只需要2毛钱,而且不限制充值金额,如果你只是用来学习微信公众号开发,而且预计一个月学会的话,那么你只需要充值6元钱就可以,相比其他最低充值一年的平台相比,要划算的多。

    2、可以免去购买域名的费用,该BAE可免费设置一个二级域名,可用于微信公众号开发,并且数据库的使用也是免费的。

    3、该BAE的代码可以使用git或svn管理,我们在本地写好代码之后,直接push上去就可以了,相当方便,而且可以设置快捷发布,提交代码当即发布。

    缺点就是它的日志系统不够完善,不过这个缺点很容易解决,我们可以自己打印信息到文件里,然后读取出来,下面将会介绍到。

     

    百度云网址是:https://login.bce.baidu.com/?account=,登录之后,点击BAE后如图

     

    好了,这样我们就准备好了微信开发的两个必备的东西。接下来就要配置接口了。

     

    3、配置接口

    上面进入测试号界面的时候我们可以看到有一个接口配置信息的模块,如下所示

     

     

    这里的URL就是填写以上BAE中的域名就好了,当然了要注意加上http://前缀,以后用户发送的消息都会经过微信服务器转发到该接口。Token可以随便填写一些东西,这里填写了weixin。关于Token的用途下面会讲到。

    好了,现在先别急着点击提交,因为我们还没有在URL指向的服务器里编写任何的代码,还不能正确响应微信服务器的请求。

     

    在编写任何的代码之前,我先说一下本博客的一些习惯,为了便于理解,我会先将文件的结构和代码先贴出来,然后才解释具体代码的含义,这样如果熟悉的人就可以直接跳过该部分了。

     

    文件结构如下

     

    index.php用于处理消息。

    output_log.php和output_query.php分别用来输出post过来的数据和请求的查询字符串,Utils.php主要用来将数据输出到文件中,看了下面的代码你就明白了,其实相当简单,这三个东西是我用来调试用的,相比起微信公众号提供的在线调试接口而言(需要设置一堆的信息),我觉得这样更加简单。

     

    Utils.php,提供了两个函数,traceHttp()将请求的时间、远程主机地址和查询字符串输出到query.xml文件中。logger()将类型、时间和post数据输出到log.xml中。

    <?php
    class Utils
    {
        public static function traceHttp()
        {
            $content = date('Y-m-d H:i:s')."\n\rremote_ip:".$_SERVER["REMOTE_ADDR"].
                "\n\r".$_SERVER["QUERY_STRING"]."\n\r\n\r";
            $max_size = 1000;
            $log_filename = "./query.xml";
            if (file_exists($log_filename) and (abs(filesize($log_filename))) > $max_size){
                unlink($log_filename);
            }else {
    
            }
            file_put_contents($log_filename, $content, FILE_APPEND);
        }
    
        public static function logger($log_content, $type = '用户')
        {
            $max_size = 3000;
            $log_filename = "./log.xml";
            if (file_exists($log_filename) and (abs(filesize($log_filename)) >
                    $max_size)) {
                unlink($log_filename);
            }
            file_put_contents($log_filename, "$type  ".date('Y-m-d H:i:s')."\n\r".$log_content."\n\r",
                FILE_APPEND);
        }
    }

     

    output_query.php,输出query.xml的内容

    <?php
    @header('Content-type: text/plain;charset=UTF-8');
    $filepath = './query.xml';
    readfile($filepath);


    output_log.php,输出log.xml的内容。

    <?php
    @header('Content-type: text/plain;charset=UTF-8');
    $filepath = './log.xml';
    readfile($filepath);


    是不是非常简单,然后我们开始写处理消息index.php

    <?php
    //设置时区
    date_default_timezone_set("Asia/Shanghai");
    //定义TOKEN常量,这里的"weixin"就是在公众号里配置的TOKEN
    define("TOKEN", "weixin");
    
    require_once("Utils.php");
    //打印请求的URL查询字符串到query.xml
    Utils::traceHttp();
    
    $wechatObj = new wechatCallBackapiTest();
    /**
     * 如果有"echostr"字段,说明是一个URL验证请求,
     * 否则是微信用户发过来的信息
     */
    if (isset($_GET["echostr"])){
        $wechatObj->valid();
    }else {
        $wechatObj->responseMsg();
    }
    
    class wechatCallBackapiTest
    {
        /**
         * 用于微信公众号里填写的URL的验证,
         * 如果合格则直接将"echostr"字段原样返回
         */
        public function valid()
        {
            $echoStr = $_GET["echostr"];
            if ($this->checkSignature()){
                echo $echoStr;
                exit;
            }
        }
    
        /**
         * 用于验证是否是微信服务器发来的消息
         * @return bool
         */
        private function checkSignature()
        {
            $signature = $_GET["signature"];
            $timestamp = $_GET["timestamp"];
            $nonce = $_GET["nonce"];
    
            $token = TOKEN;
            $tmpArr = array($token, $timestamp, $nonce);
            sort($tmpArr);
            $tmpStr = implode($tmpArr);
            $tmpStr = sha1($tmpStr);
    
            if ($tmpStr == $signature){
                return true;
            }else {
                return false;
            }
        }
    
        /**
         * 响应用户发来的消息
         */
        public function responseMsg()
        {
            //获取post过来的数据,它一个XML格式的数据
            $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
            //将数据打印到log.xml
            Utils::logger($postStr);
            if (!empty($postStr)){
                //将XML数据解析为一个对象
                $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
                $RX_TYPE = trim($postObj->MsgType);
                //消息类型分离
                switch($RX_TYPE){
                    case "event":
                        $result = $this->receiveEvent($postObj);
                        break;
                    default:
                        $result = "unknow msg type:".$RX_TYPE;
                        break;
                }
                //打印输出的数据到log.xml
                Utils::logger($result, '公众号');
                echo $result;
            }else{
                echo "";
                exit;
            }
        }
    
        /**
         * 接收事件消息
         */
        private function receiveEvent($object)
        {
            switch ($object->Event){
                //关注公众号事件
                case "subscribe":
                    $content = "欢迎关注微微一笑很倾城";
                    break;
                default:
                    $content = "";
                    break;
            }
            $result = $this->transmitText($object, $content);
            return $result;
        }
    
        /**
         * 回复文本消息
         */
        private function transmitText($object, $content)
        {
            $xmlTpl = "<xml>
        <ToUserName><![CDATA[%s]]></ToUserName>
        <FromUserName><![CDATA[%s]]></FromUserName>
        <CreateTime><![CDATA[%s]]></CreateTime>
        <MsgType><![CDATA[text]]></MsgType>
        <Content><![CDATA[%s]]></Content>
    </xml>";
            $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, time(), $content);
            return $result;
        }
    }


    这几个文件写好之后,直接通过git push到BAE上,如果设置了快捷发布,过1、2秒钟就会自动发布了,状态里面会显示绿色的"正常",如果没有设置快捷发布,上传代码后需要手动点击右边的快捷发布按钮。

     

    这时我们就可以点击测试号界面里面的那个提交按钮了。

     

     

    如果配置正确,则会提示配置成功。

     

    4、调试

    在浏览器地址栏上输入,xxx/output_query.php,xxx是你的域名。则会出现你点击提交后发送过来的请求,类似如下

     

     

    可以看到该查询字符串有4个字段

    • signature:微信加密签名
    • echostr:随机字符串
    • timestamp:时间戳
    • nonce:随机数

    只有在验证URL的时候查询字符串中才会有“echostr”这个字段,验证的方法是

    1. 将token、timestamp、nonce三个参数进行字典序排序
    2. 将三个参数字符串拼接成一个字符串进行sha1加密
    3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信

     

    验证通过之后,我们可以用微信扫一扫,扫描测试号里面的公众号二维码,关注该公众号,关注之后,公众号列表会显示出关注者的列表。

     

    此时微信应该会回复一条文本消息,也就是以上在index.php中设置的“欢迎关注XXX”。

     

    这时我们重新刷新一下xxx/output_query.php,发现没有“echostr”这个字段了,因为这个是用户发来的消息,而不是验证URL的消息。多出来的openid字段是用户的微信号,如果采用的是加密模式,还会有encrypt_type和msg_signature等字段。测试号只有明文模式。

    接着我们重新打开一个标签,访问XXX/log.xml,查看发送的post数据,下面是一个关注公众号的事件,和我们返回给微信的XML数据。

     

    现在不比纠结这些数据格式的问题,以后我们会提到,这样我们的微信公众号开发就准备好了,记得把这两个日志URL保存为浏览器的标签方便下次访问,以后调试只要F5一下就可以了,是不是比微信提供的在线调试容易多了。

    注意:必须在5秒内响应微信的服务器,否则会导致重传或者报错

     

    下一章我们将会尝试微信的基本消息接口,那时候就会理解这些数据结构了。

    相关博客

    微信公众号开发(一)服务器及接口的配置

    微信公众号开发(二)基础接口

    微信公众号开发(三)获取access_token

    微信公众号开发(四)自定义菜单

    微信公众号开发(五)个性化菜单

    微信公众号开发(六)素材管理

    微信公众号开发(七)发送客服消息

    微信公众号开发(八)用户管理

    微信公众号开发(九)群发消息接口

    微信公众号开发(十)模板消息

    微信公众号开发(十一)生成带参数二维码

    微信公众号开发(十二)OAuth2.0网页授权

    展开全文
  • 1、因为再微信公众号开发关键字回复的时候需要使用到接口配置信息URL和Token. 刚开始配置的时候总是失败,原因是自己使用花生壳的外网的端口不是80,所以我将外网端口该为了80,后来配置成功。 重点:1、这个一定...

    1、因为再微信公众号开发关键字回复的时候需要使用到接口配置信息URL和Token.

    刚开始配置的时候总是失败,原因是自己使用花生壳的外网的端口不是80,所以我将外网端口该为了80,后来配置成功。

    重点:1、这个一定是使用外网可以访问的url;2、外网端口一定是80的,好像还有一个不过我忘记啦,自己本地的端口可以随便(我的是8080)3、本地地址可以外网访问的话,可以使用花生壳,(是免费的,可以直接在官网下载,然后注册下就可以啦)4、token是自己随便设置的

     

     1、本地写一个微信访问的方法:

    package com.uvksoft.mobile.web.agent.wx;
    import javax.servlet.http.HttpServletRequest;
    import com.uvksoft.common.util.wx.SignUtil;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import java.io.PrintWriter;
    import java.util.Enumeration;
    import javax.servlet.http.HttpServletResponse;
    @RestController
    public class AgentWeixinReplyController {
    	
    
    	
    
    	@RequestMapping(value = "/wx/reply.do")
    	public void get(HttpServletRequest request, HttpServletResponse response) throws Exception {
    
    		System.out.println("========WechatController========= ");
    		
    
    		Enumeration pNames = request.getParameterNames();
    		while (pNames.hasMoreElements()) {
    			String name = (String) pNames.nextElement();
    			String value = request.getParameter(name);
    			// out.print(name + "=" + value);
    			String log = "name =" + name + "     value =" + value;
    		}
    		System.out.println("========WechatControllertets========= ");
    		String signature = request.getParameter("signature");/// 微信加密签名
    		String timestamp = request.getParameter("timestamp");/// 时间戳
    		String nonce = request.getParameter("nonce"); /// 随机数
    		String echostr = request.getParameter("echostr"); // 随机字符串
    		PrintWriter out = response.getWriter();
    
    		 if (SignUtil.checkSignature(signature, timestamp, nonce)) {  
    			 System.out.println("校验成功!!!!!!!!!!!!!");
    	          out.print(echostr);  
    	      } 
    		
    		out.close();
    		out = null;
    
    	}
    
    }
    

    2、token校验方法

    package com.uvksoft.common.util.wx;
    
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import java.util.Arrays;
    
    /** 
     * 请求校验工具类 
     *  
     * @author HXM 
     * @date 2019-07-6 
     */  
    public class SignUtil {  
        // 与接口配置信息中的Token要一致  
        private static String token = "weixinCore";  
      
        /** 
         * 验证签名 
         *  
         * @param signature 
         * @param timestamp 
         * @param nonce 
         * @return 
         */  
        public static boolean checkSignature(String signature, String timestamp, String nonce) {  
            String[] arr = new String[] { token, timestamp, nonce };  
            // 将token、timestamp、nonce三个参数进行字典序排序  
            Arrays.sort(arr);  
            StringBuilder content = new StringBuilder();  
            for (int i = 0; i < arr.length; i++) {  
                content.append(arr[i]);  
            }  
            MessageDigest md = null;  
            String tmpStr = null;  
      
            try {  
                md = MessageDigest.getInstance("SHA-1");  
                // 将三个参数字符串拼接成一个字符串进行sha1加密  
                byte[] digest = md.digest(content.toString().getBytes());  
                tmpStr = byteToStr(digest);  
            } catch (NoSuchAlgorithmException e) {  
                e.printStackTrace();  
            }  
      
            content = null;  
            // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信  
            return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;  
        }  
      
        /** 
         * 将字节数组转换为十六进制字符串 
         *  
         * @param byteArray 
         * @return 
         */  
        private static String byteToStr(byte[] byteArray) {  
            String strDigest = "";  
            for (int i = 0; i < byteArray.length; i++) {  
                strDigest += byteToHexStr(byteArray[i]);  
            }  
            return strDigest;  
        }  
      
        /** 
         * 将字节转换为十六进制字符串 
         *  
         * @param mByte 
         * @return 
         */  
        private static String byteToHexStr(byte mByte) {  
            char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };  
            char[] tempArr = new char[2];  
            tempArr[0] = Digit[(mByte >>> 4) & 0X0F];  
            tempArr[1] = Digit[mByte & 0X0F];  
      
            String s = new String(tempArr);  
            return s;  
        }  
    }  

     

    展开全文
  • 1.在学习微信公众号开发,因为是屌丝,没办法只能搞内网穿透,配置微信公众号接口配置,一直显示匹配失败。做个流程笔记,以备于下次忘记。 第一步,写代码创建一个工程,创建app.js.基于koa。安装依赖koa(参考...

    1.本文是在学习网络视频做的总结

    1.在学习微信公众号开发,因为是屌丝,没办法只能搞内网穿透,配置微信公众号的接口配置,一直显示匹配失败。做个流程笔记,以备于下次忘记。

    第一步,写代码创建一个工程,创建app.js.基于koa。安装依赖koa(参考廖老师的安装koa)和sha1.

    var Koa = require('koa')
    var sha1 = require('sha1')
    var config= {
        wechat:{
         appID:'wxf56df97c0c8a4d115',
         appSecret:'ed3528ca1ac2133243e3fac9918fb714b',
         token:'dhadgkadgajkdgasfdszsafgvdfnss',
        }
     }
     var app = new Koa()
     app.use(function *(next){
        console.log(this.query)
        var token= config.wechat.token
            var signature = this.query.signature
            var nonce = this.query.nonce
            var timestamp = this.query.timestamp
            var echostr = this.query.echostr
            var str = [token,timestamp,nonce].sort().join('')
            var sha = sha1(str) 
            if (sha===signature) {
                this.body = echostr + ''
            
            } else {
                this.body = 'wrong'
            }
     })
     app.listen(3104)
     console.log("listening:3104")

    注意appid和appSecret都是来自于测试接口。

    第二:开启 node app.js。(浏览器中输入http://localhost:3104/?a=1),控制台打印{"a":1},此时表示koa监听浏览器成功。

    第三步开启ngrok代理。

    填写微信公众号平台的接口验证,

    需要注意的当点击提交按钮的时候,实际上经历的是微信公众平台给你填写的内网穿透服务器地址发送了一个消息,而内网服务器映射地址到本地的主机浏览器监听3104端口。

    展开全文
  • 微信公众号开发 背景 流程 第一步 申请测试公众号 第二步 创建SpringBoot 项目,实现响应接口 1. WaChatController 层 2. CheckUtil 3. SHA1加密 第三步 内网穿透 第四步 配置接口配置信息
  • 微信公众号接口之接口信息配置(一)

    千次阅读 2018-06-01 14:27:12
    微信公众号地址:...t=sandbox/index配置url和token&lt;?php/** * wechat php test *///define your tokendefine("TOKEN", "你的token");$wechatObj = ne...
  • 微信公众号 接口配置信息 URL 配置失败(能进入后台方法,无返回信息) 操作步骤:1.微信公众号输入url、token点提交,提示配置失败。 后台代码: @ResponseBody @RequestMapping("/check.do") public String ...
  • 微信公众号接口平台配置请参考 zc的救赎:http://blog.csdn.net/qq_28506819/article/details/77827899 以下内容为补充: 开始提交的时候一定注意,token,因为大佬的 index.php没有写 define token = “weixin...
  • 2:接口配置信息 可以看到参数 (测试公众号只有url 和 token) 1:url 是开发者用来接收微信消息和事件 的接口URL。(必须以http://开头,目前支持80端口) 2: Token:可由开发者可以任意填写,用作生成签名(该Token...
  • 配置node服务器 在购买好服务器后,用Xshell链接到服务器。 1、安装nvm curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash 或者 wget -qO- ...
  • 微信公众号接口配置信息对接

    千次阅读 2018-09-17 09:26:39
    微信开发者测试公众号申请: ...进去第一步就是设置接口配置信息,在开发者后台接口中进行安全验证: 输入url和token后,微信后台会向公众号后台发送一个get请求,具体为: /? signature=ae09bb...
  • 一、环境说明:开发工具:EclipseJDK版本:JDK1.8Servlet容器:Tomcat8.5内网穿透工具:NATAPP本教程基于Servlet来做请求响应,不使用相关框架,旨在说明微信公众号开发的相关流程。二、账号接口配置要进行公众号...
  • 之前和室友合租的服务器到期了,现在自己租了一个,想把之前开发的公众号搬过来。然后就换配置接口的URL后提交。一致提示配置失败,后台没看到请求进来,也没看到错误日志。想想是不是请求发到别的地方去了,才突然...
  • 修改微信测试公众号接口配置信息的时候:一直提示配置失败, 使用谷歌浏览器开发者工具看一下response返回的是啥 {"errcode":-106,"errmsg":"token check fail"} 如何使用谷歌浏览器查看如下图,下图是我...
  • /** * 审核填写的URL */ public function checkUrl(){ //获得参数 signature nonce token timestamp echostr $nonce = $_GET('nonce'); $token = 'sudi'; ...
  • 接入微信公众平台开发,接口测试账号的配置以及使用花生壳进行外网映射操作 首先使用新花生壳软件将本地计算机进行动态域名绑定 http://hsk.oray.com/download/ 进入微信公众平台测试账号管理,可通过微信扫码...
  • 说明:我的是springboot项目 1. pom.xml添加依赖 <!-- https://mvnrepository.com/artifact/org.dom4j/dom4j 微信基本设置token认证--> <dependency> <groupId>.../groupId>...
  • 接入微信公众平台开发,开发者需要按照如下步骤完成:1、填写服务器配置2、验证服务器地址的有效性3、依据接口文档实现业务逻辑①、在微信公众号配置中填写正确的url地址接口,以及自己想要生成的Token②、验证...
  • 公众号信息 appid:是公众号开发识别码,配合开发者密码可调用公众号接口能力。 appsecret:是校验公众号开发者身份的密码,具有极高的安全性。 url接入校验配置 URL:就是指我们自己的服务器地址(公网可...
  • 公众号开发接口配置失败终极处理
1 2 3 4 5 ... 20
收藏数 54,311
精华内容 21,724
热门标签
关键字:

公众号接口配置