2017-01-16 15:47:38 u014783753 阅读数 3039
  • 微信沙箱开发微信社交立减金接口升级

    会员免费看,http://edu.csdn.net/lecturer/842右侧可办理会员卡。微信沙箱也叫微信仿真测试系统,微信沙箱开发是子恒老师《子恒说微信开发》视频教程的第18部。详细讲解了微信沙箱开发过程,内容包含微信沙箱作用,获取微信沙箱验签秘钥KEY,在沙箱中实现社交立减金接口升级等等。欢迎反馈,微信号:QQ68183131

    7545 人正在学习 去看看 秦子恒



微信页面分享到朋友圈、分享朋友等等,默认的是有分享格式的,比如分享给朋友,默认的图标是页面的第一张图片,内容是该页面的url,这个显然有些场景是不满足的。对于挑剔的产品经理一定是会有自己的设计的,比如图片、内容等。

微信js-sdk提供了关于这部分的接口,现将过程说明如下。

文档路径,在登录公众号后路径如下:点击打开链接,在左侧“微信网页开发”--“微信JS-SDK说明文档”菜单栏中

点击“3.2 获取“分享给朋友”按钮点击状态及自定义分享内容接口”我们可以看到如下内容:

wx.onMenuShareAppMessage({
    title: '', // 分享标题
    desc: '', // 分享描述
    link: '', // 分享链接
    imgUrl: '', // 分享图标
    type: '', // 分享类型,music、video或link,不填默认为link
    dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
    success: function () { 
        // 用户确认分享后执行的回调函数
    },
    cancel: function () { 
        // 用户取消分享后执行的回调函数
    }
});
在以上代码片段中我们看到了我们可以定义“微信分享视图”中的这些项:标题、描述、连接、图片以及类型。为了举例,我们只说标题和描述。

看了以上代码段,问题来了,wx这个对象我们怎么定义以及怎么配置呢?
在改说明文档下的步骤一、步骤二和步骤三说明了我们怎么使用wx这个对象以及怎么配置,如下:

JSSDK使用步骤
步骤一:绑定域名
先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
备注:登录后可在“开发者中心”查看对应的接口权限。
步骤二:引入JS文件
在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.0.0.js
如需使用摇一摇周边功能,请引入 http://res.wx.qq.com/open/js/jweixin-1.1.0.js
备注:支持使用 AMD/CMD 标准模块加载方法加载
步骤三:通过config接口注入权限验证配置
所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。
wx.config({
    debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    appId: '', // 必填,公众号的唯一标识
    timestamp: , // 必填,生成签名的时间戳
    nonceStr: '', // 必填,生成签名的随机串
    signature: '',// 必填,签名,见附录1
    jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});

以上代码段我们需要注意wx.config({})中定义的参数:

debug我们不再赘述

appId,就是公众号的Id

timestamp,暂时看就是一个时间戳文本

nonceStr,暂时看就是一个随机串,

jsApiList,需要使用的js接口列表,这个看上去也没有什么问题,应该是js接口列表中列出的接口的一个array

需要我们注意的是signature以及signature和timestamp和nonceStr的关系。根据以上代码段列出的备注,我们看附录一。

附录一描述如下

附录1-JS-SDK使用权限签名算法
jsapi_ticket
生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket 。
1.参考以下文档获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token):../15/54ce45d8d30b6bf6758f68d2e95bc627.html
2.用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket):https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
成功返回如下JSON:
{
"errcode":0,
"errmsg":"ok",
"ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
"expires_in":7200
}
获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了。
通过阅读以上代码段说明的文本,我们可以看出来,要想生成signature这个参数,不许要生成ticket这个“票据”。

需要我们注意的是,生成这个“票据”又需要我们获得access_token,根据以上../15/54....这段说明我们看下怎么生成access_token这个参数。

说明如下:

获取access token
access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。

公众平台的API调用所需的access_token的使用及生成方式说明:

1、为了保密appsecrect,第三方需要一个access_token获取和刷新的中控服务器。而其他业务逻辑服务器所使用的access_token均来自于该中控服务器,不应该各自去刷新,否则会造成access_token覆盖而影响业务;
2、目前access_token的有效期通过返回的expire_in来传达,目前是7200秒之内的值。中控服务器需要根据这个有效时间提前去刷新新access_token。在刷新过程中,中控服务器对外输出的依然是老access_token,此时公众平台后台会保证在刷新短时间内,新老access_token都可用,这保证了第三方业务的平滑过渡;
3、access_token的有效时间可能会在未来有调整,所以中控服务器不仅需要内部定时主动刷新,还需要提供被动刷新access_token的接口,这样便于业务服务器在API调用获知access_token已超时的情况下,可以触发access_token的刷新流程。
如果第三方不使用中控服务器,而是选择各个业务逻辑点各自去刷新access_token,那么就可能会产生冲突,导致服务不稳定。

公众号可以使用AppID和AppSecret调用本接口来获取access_token。AppID和AppSecret可在微信公众平台官网-开发者中心页中获得(需要已经成为开发者,且帐号没有异常状态)。注意调用所有微信接口时均需使用https协议。

接口调用请求说明

http请求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
参数说明

参数	是否必须	说明
grant_type	是	获取access_token填写client_credential
appid	是	第三方用户唯一凭证
secret	是	第三方用户唯一凭证密钥,即appsecret
返回说明

正常情况下,微信会返回下述JSON数据包给公众号:

{"access_token":"ACCESS_TOKEN","expires_in":7200}
参数	说明
access_token	获取到的凭证
expires_in	凭证有效时间,单位:秒

错误时微信会返回错误码等信息,JSON数据包示例如下(该示例为AppID无效错误):

{"errcode":40013,"errmsg":"invalid appid"}
通过以上代码段列出的文本我们很快可以看到,只要传入appid和appsecret以及grant_type这三个参数给列出的url既可以获得返回的access_token这个参数,这里我们不再赘述。

需要注意的是我在处理这块儿的时候想当然的使用oauth认证的access_token来获取“票据”,最后证明返回一直是invalid,即参数错误是不行的。不行的方式如下:

Get:
https://api.weixin.qq.com/sns/oauth2/access_token
传入:
appid
secretid
以及code
其中code是微信回调方法传入的,这里我们不再赘述
事实证明,这种方式获得access_token不能获得“票据”

必须用以上的以上代码段描述的方式获得。谢谢。

根据文档描述,在获得代码段后我们就可以生成“签名了”,其中签名的算法如下:

签名算法
签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。
即signature=sha1(string1)。 示例:
noncestr=Wm3WZYTPz0wzccnW
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg
timestamp=1414587457
url=http://mp.weixin.qq.com?params=value
步骤1. 对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1:
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW×tamp=1414587457&url=http://mp.weixin.qq.com?params=value
步骤2. 对string1进行sha1签名,得到signature:
0f9de62fce790f9a083d5c99e95740ceb90c27ed
以上文本不难理解,认真读取后按照方法做就能获得相应的签名。

需要注意的是:

注意事项

1.签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。

2.签名用的url必须是调用JS接口页面的完整URL。

3.出于安全考虑,开发者必须在服务器端实现签名的逻辑。

以上的1步骤也就回答了signature和noncestr和timestamp的关系。

至此我们就能争取的配置wx.config,不出意外的情况下,调用“发送给朋友”的接口就能个性化配置分享的试图了。


这里附上后端生成signature的java实现

import java.util.UUID;
import java.util.Map;
import java.util.HashMap;
import java.util.Formatter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.io.UnsupportedEncodingException;  

class Sign {
    public static void main(String[] args) {
        String jsapi_ticket = "jsapi_ticket";

        // 注意 URL 一定要动态获取,不能 hardcode
        String url = "http://example.com";
        Map<String, String> ret = sign(jsapi_ticket, url);
        for (Map.Entry entry : ret.entrySet()) {
            System.out.println(entry.getKey() + ", " + entry.getValue());
        }
    };

    public static Map<String, String> sign(String jsapi_ticket, String url) {
        Map<String, String> ret = new HashMap<String, String>();
        String nonce_str = create_nonce_str();
        String timestamp = create_timestamp();
        String string1;
        String signature = "";

        //注意这里参数名必须全部小写,且必须有序
        string1 = "jsapi_ticket=" + jsapi_ticket +
                  "&noncestr=" + nonce_str +
                  "×tamp=" + timestamp +
                  "&url=" + url;
        System.out.println(string1);

        try
        {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(string1.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());
        }
        catch (NoSuchAlgorithmException e)
        {
            e.printStackTrace();
        }
        catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
        }

        ret.put("url", url);
        ret.put("jsapi_ticket", jsapi_ticket);
        ret.put("nonceStr", nonce_str);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);

        return ret;
    }

    private static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash)
        {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }

    private static String create_nonce_str() {
        return UUID.randomUUID().toString();
    }

    private static String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }
}





2019-03-28 16:35:37 QWERTY1994 阅读数 119
  • 微信沙箱开发微信社交立减金接口升级

    会员免费看,http://edu.csdn.net/lecturer/842右侧可办理会员卡。微信沙箱也叫微信仿真测试系统,微信沙箱开发是子恒老师《子恒说微信开发》视频教程的第18部。详细讲解了微信沙箱开发过程,内容包含微信沙箱作用,获取微信沙箱验签秘钥KEY,在沙箱中实现社交立减金接口升级等等。欢迎反馈,微信号:QQ68183131

    7545 人正在学习 去看看 秦子恒

需要分页的网页引入下面jsp

weixin.jsp

<%--
  Created by IntelliJ IDEA.
  User: 
  Date: 2019/2/20
  Time: 15:12
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--<%@ include file="/WEB-INF/views/modules/cms/front/include/taglib.jsp"%>--%>
<!-- 必须引入的文件-->
<script src="http://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>

<!-- 组装微信配置信息js文件-->
<%--<script src="${ctxStatic}/weixin/wxShare_data.js"></script>--%>

<!-- 微信分享时调用对应的接口js文件-->
<%--<script src="${ctxStatic}/weixin/wxShare.js"></script>--%>

<script>
    //后台获取授权等信息的接口
    var url = "http://" + window.location.host + "/f/weixinShare/getWxShareData";
    // 分享网页图片地址
    var shareImageUrl="http://xxxx/xxxx.jpg";
    //分享网页后显示的标题
    var title="xxxxx";
    //分享网页的简介
    var desc= "xxxxx";
    //点击分享后页面跳转的页面
    var link="http://xxxxx/f/xxxxx";
    //上面这些数据也可以在后台动态生成
    $.ajax({
        url: url,//后台给你提供的接口
        type: "Post",
        // data: "{ 'url': '"+link+"' }",
        async: false,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (data) {
            wx.config({
                debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                appId: data.appId, // 必填,公众号的唯一标识
                timestamp: data.timestamp, // 必填,生成签名的时间戳
                nonceStr: data.nonceStr, // 必填,生成签名的随机串
                signature: data.signature,// 必填,签名
                jsApiList: ['updateAppMessageShareData', 'updateTimelineShareData', 'onMenuShareWeibo','onMenuShareAppMessage','onMenuShareTimeline','onMenuShareQQ','onMenuShareQZone'] // 必填,需要使用的JS接口列表
            });
            wx.ready(function () {
                // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,
                // 则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
                //需在用户可能点击分享按钮前就先调用
                // 自定义“分享给朋友”及“分享到QQ”按钮的分享内容
                wx.updateAppMessageShareData({
                    title: title, // 分享标题
                    desc: desc, // 分享描述
                    link: link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
                    imgUrl: shareImageUrl, // 分享图标
                    success: function () {
                        // 设置成功
                    }
                });
                //自定义“分享到朋友圈”及“分享到QQ空间”按钮的分享内容
                wx.updateTimelineShareData({
                    title: title, // 分享标题
                    link: link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
                    imgUrl: shareImageUrl, // 分享图标
                    success: function () {
                        // 设置成功
                    }
                });
                //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口
                wx.onMenuShareWeibo({
                    title: title, // 分享标题
                    desc: desc, // 分享描述
                    link: link, // 分享链接
                    imgUrl: shareImageUrl, // 分享图标
                    success: function () {
                        // 用户确认分享后执行的回调函数
                    },
                    cancel: function () {
                        // 用户取消分享后执行的回调函数
                    }
                });

                // 获取“分享给朋友”按钮点击状态及自定义分享内容接口(即将废弃)
                wx.onMenuShareAppMessage({
                    title: title, // 分享标题
                    desc: desc, // 分享描述
                    link: link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
                    imgUrl: shareImageUrl, // 分享图标
                    type: 'link', // 分享类型,music、video或link,不填默认为link
                    dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
                    success: function () {
                        // 用户点击了分享后执行的回调函数
                    }
                });
                //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口(即将废弃)
                wx.onMenuShareTimeline({
                    title: title, // 分享标题
                    link: link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
                    imgUrl: shareImageUrl, // 分享图标
                    success: function () {
                        // 用户点击了分享后执行的回调函数
                    }
                });
                //获取“分享到QQ”按钮点击状态及自定义分享内容接口(即将废弃)
                wx.onMenuShareQQ({
                    title: title, // 分享标题
                    desc: desc, // 分享描述
                    link: link, // 分享链接
                    imgUrl: shareImageUrl, // 分享图标
                    success: function () {
                        // 用户确认分享后执行的回调函数
                    },
                    cancel: function () {
                        // 用户取消分享后执行的回调函数
                    }
                });
                //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口(即将废弃)
                wx.onMenuShareQZone({
                    title: title, // 分享标题
                    desc: desc, // 分享描述
                    link: link, // 分享链接
                    imgUrl: shareImageUrl, // 分享图标
                    success: function () {
                        // 用户确认分享后执行的回调函数
                    },
                    cancel: function () {
                        // 用户取消分享后执行的回调函数
                    }
                });
            });
            wx.error(function (res) {
                // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
                //alert(res);
            });
        },
        error: function (error) {
            layer.msg(error)
        }
    });

</script>

后台获取签名授权等信息的方法

下面的签名每天获取有次数限制,微信的签名2个小时内有效, 此处我用的是Memcached缓存起来,各位可以自行实现



import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.thinkgem.jeesite.common.config.Global;
import com.thinkgem.jeesite.common.memcached.MemcachedUtil;
import com.thinkgem.jeesite.common.utils.CacheUtils;
import com.thinkgem.jeesite.common.web.BaseController;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

/**
 * 微信分享
 */
@Controller
@RequestMapping(value = "/f/weixinShare")
public class CourseWeixinShare extends BaseController {
    // 微信分享入口
    @RequestMapping(value = "getWxShareData")
    @ResponseBody
    public Map getWxShareData(HttpServletRequest request, HttpServletResponse response) throws Exception {
        Map<String,Object> returnMap = new HashMap<>();

        String ticket = "";
        String[] wxInfo = new String[]{Global.getConfig("appId"),Global.getConfig("appsecret")};//设置appid 和 appsecret

        String ticketResString = this.getShareJsapiTicket(wxInfo);

        if (StringUtils.isNotEmpty(ticketResString)) {
          //  JSONObject ticketJSONObject = JSONObject.fromObject(ticketResString);

            Gson gson =new Gson();
            Map<String,Object> ticketJSONObject = gson.fromJson(ticketResString,Map.class);
            if ((Double)ticketJSONObject.get("errcode") == 0) {
//                ticket = JSONObject.fromObject(ticketResString).optString("ticket", "");
                if(ticketJSONObject.get("ticket")!=null){
                    ticket = (String) ticketJSONObject.get("ticket");
                }

            }
        }

        if (StringUtils.isEmpty(ticket)) {
            returnMap.put("errcode", "10002");
            returnMap.put("errmsg", "ticket_error");
//            this.responseWrite(jsonObject.toString());
            return returnMap;
        }

        String noncestr = this.createNonceStr();
        int timestamp = this.createTimestamp();
        String requestRefererURL = request.getHeader("referer");
        logger.warn("requestRefererURL: " + requestRefererURL);

        String signature = this.createSignature(noncestr, ticket, timestamp, requestRefererURL);

        returnMap.put("errcode", 0);
        returnMap.put("errmsg", "");
        returnMap.put("appId", wxInfo[0]); // appId
        returnMap.put("timestamp", timestamp);
        returnMap.put("nonceStr", noncestr);
        returnMap.put("signature", signature);
        return returnMap;

    }

    /**
     * 微信分享,获取Js api Ticket
     * @param wxInfo
     * @return
     * @throws Exception
     */
    private String getShareJsapiTicket(String[] wxInfo) throws Exception {

        String jsapiTicket = null;
        if(CacheUtils.get("jsapiTicket_addTime") !=null &&( System.currentTimeMillis() - (Long) CacheUtils.get("jsapiTicket_addTime"))<7080*1000){//不超过2个小时的缓存有效
            jsapiTicket = (String) CacheUtils.get("jsapiTicket");
            this.logger.warn(" from memcached jsapiTicket: " + jsapiTicket);
            return jsapiTicket;
        }else{
            String accessToken = this.getWeiXinAccessToken(wxInfo);
            if (StringUtils.isEmpty(accessToken)) { // 获取 accessToken 失败
                this.logger.warn(" accessToken is empty.");
                JsonObject jsonObject = new JsonObject();
                jsonObject.addProperty("errcode", "10000");
                jsonObject.addProperty("errmsg", "access_error");
                return jsonObject.toString();
            }

            String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+ accessToken + "&type=jsapi";
            jsapiTicket = this.httpReqExecute(url);
            this.logger.warn(" from weixin api jsapiTicket is: " + jsapiTicket);

            if(StringUtils.isNotEmpty(jsapiTicket)) {
                // 向memcached里写内容,第二个参数为过期时间,单位为:秒 两个小时失效
//            remoteMemcachedClient.set(siteId + "_jsapiTicket", 7200, jsapiTicket);
                CacheUtils.put("jsapiTicket",jsapiTicket);
                CacheUtils.put("jsapiTicket_addTime",System.currentTimeMillis());//设置 缓存的时间
                return jsapiTicket;
            }
            return null;
        }
    }

    /**
     * 微信分享,获取access_token
     * 先从memcached获取
     * @param wxInfo 0:appId 1:secret
     * @return
     * @throws Exception
     */
    private String getWeiXinAccessToken(String[] wxInfo) throws Exception {
        String access_token = MemcachedUtil.get("ParentsSpace_access_token");
        if(StringUtils.isNotBlank(access_token)){
            return  access_token;
        }
       /* if( CacheUtils.get("access_token_addTime")!=null && (System.currentTimeMillis() - (Long)CacheUtils.get("access_token_addTime")) <7080*1000 ){//不超过2个小时的缓存有效
            return (String) CacheUtils.get("access_token");
        }*/else{//失效了 就重新请求
            String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + wxInfo[0] + "&secret=" + wxInfo[1];

            String result = this.httpReqExecute(url);
            this.logger.warn("from weixin api accessToken: " + result);
            try {
                if(StringUtils.isNotEmpty(result)) {
                    // 解析respContent,并获取其中的更新的key,
                    Gson gson =new Gson();
                    Map<String,String> resultMap =  gson.fromJson(result,Map.class);

//                String accessToken = JSONObject.fromObject(result).optString("access_token", "");
                    String accessToken = "";
                    if(resultMap.get("access_token")!=null){
                        accessToken = resultMap.get("access_token");
                        //缓存起来
                      /*  CacheUtils.put("access_token_addTime",System.currentTimeMillis());
                        CacheUtils.put("access_token",accessToken);*/
                      //缓存118分钟
                        MemcachedUtil.set("ParentsSpace_access_token",accessToken,118*60);
                    }
                    return accessToken;
                }
            } catch (Exception e) {
                logger.error("getAccessToken error in WeiXinShareAction", e);
            }
            return null;
        }
    }

    /**
     * 数据签名
     * @param nocestr
     * @param ticket
     * @param timestamp
     * @param url
     * @return
     */
    private String createSignature(String nocestr, String ticket, int timestamp, String url) {
        // 这里参数的顺序要按照 key 值 ASCII 码升序排序
        String s = "jsapi_ticket=" + ticket + "&noncestr=" + nocestr + "&timestamp=" + timestamp + "&url=" + url;
        return DigestUtils.sha1Hex(s);
    }

    /**
     * 创建随机串 自定义个数0 < ? < 32
     * @return
     */
    private String createNonceStr() {
        String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        String nonceStr = "";
        for (int i = 0; i < 16; i++) {
            int beginIndex = (int) Math.round(Math.random() * 10);
            nonceStr += str.substring(beginIndex, beginIndex + 1);
        }
        return nonceStr;
    }

    /**
     * 创建时间戳
     * @return
     */
    private int createTimestamp() {
        return Calendar.getInstance().get(Calendar.SECOND);
    }

    // 输出信息
    /*private void responseWrite(String content) {
        try {
            getResponse().setCharacterEncoding("utf-8");
            getResponse().getWriter().write(content);
        } catch (Exception e) {
            logger.error("responseWrite error in WeiXinShareAction", e);
        }
    }*/

    // HTTP远程调用
    private String httpReqExecute(String url) {
        String result = "";
//        DefaultHttpClient httpclient = null ;
        HttpClient httpclient = null ;
        try {
            httpclient = HttpClientBuilder.create().build();//获取DefaultHttpClient请求
            HttpPost httppost = new HttpPost(url);
            // 执行
            org.apache.http.HttpResponse response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            if(entity != null && response.getStatusLine().getStatusCode() == 200){
                result =  EntityUtils.toString(entity, "UTF-8");
            }
        } catch (Exception e) {
            logger.error(" WeiXinShareAction 调用微信 API 失败!", e);
        } finally { // 关闭连接,释放资源
            httpclient.getConnectionManager().shutdown();
        }
        return result;
    }
}

 

2018-04-24 20:02:24 qq_39879632 阅读数 565
  • 微信沙箱开发微信社交立减金接口升级

    会员免费看,http://edu.csdn.net/lecturer/842右侧可办理会员卡。微信沙箱也叫微信仿真测试系统,微信沙箱开发是子恒老师《子恒说微信开发》视频教程的第18部。详细讲解了微信沙箱开发过程,内容包含微信沙箱作用,获取微信沙箱验签秘钥KEY,在沙箱中实现社交立减金接口升级等等。欢迎反馈,微信号:QQ68183131

    7545 人正在学习 去看看 秦子恒

Java微信分享,步骤是

1、根据当前的url,获取signature,nonceStr,timestamp 和appId。 
2、通过signature,nonceStr,timestamp 和appId来配置微信 wx.config。 
3、通过wx.ready实现微信分享功能。

1、html端

引入微信JS-SDK.

<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>

//分享核心js代码
$(document).ready(function () {
    //通过ajax,在页面加载的时候获取微信分享接口signature,nonceStr,timestamp 和appId
    $.ajax({
        type: "post",
        url: "/weixin/share",
        dataType: "json",
        data:"url="+window.location.href,
        success: function (data) {
            wx.config({
                debug: false,
                appId: data.appId,
                timestamp: data.timestamp,
                nonceStr: data.nonceStr,
                signature: data.signature,
                jsApiList: ['onMenuShareAppMessage', 'onMenuShareTimeline', 'hideAllNonBaseMenuItem', 'showMenuItems']
                // 功能列表,我们要使用JS-SDK的什么功能
            });
            wx.ready(function () {
                // 获取“分享给朋友”按钮点击状态及自定义分享内容接口
                wx.onMenuShareAppMessage({
                    title: "分享自定义标题", // 分享标题
                    desc: "分享自定义描述", // 分享描述
                    link: "http://localhost/weixin/share?openId=1",//分享点击之后的链接
                    imgUrl:'/images/photo/1.jpg', // 分享图标
                    type: 'link', // 分享类型,music、video或link,不填默认为link
                    success: function () {
                        //成功之后的回调
                    }
                });
                wx.hideAllNonBaseMenuItem();
                wx.showMenuItems({
                    menuList: ['menuItem:share:appMessage', 'menuItem:share:timeline'] // 要隐藏的菜单项,只能隐藏“传播类”和“保护类”按钮,所有menu项见附录3
                });
                wx.onMenuShareTimeline({
                    title: "分享自定义标题", // 分享标题
                    desc: "分享自定义描述", // 分享描述
                    link: "http://localhost/weixin/share?openId=1",//分享点击之后的链接
                    imgUrl:'/images/photo/1.jpg', // 分享图标
                    type: 'link', // 分享类型,music、video或link,不填默认为link
                    success: function () {
                        //成功之后的回调
                    }
                    cancel: function () {
                        // 用户取消分享后执行的回调函数
                    }
                });
            });
            wx.error(function (res) {
                //打印错误消息。及把 debug:false,设置为debug:ture就可以直接在网页上看到弹出的错误提示
            });
        }
    })
});

2、Java代码,获取 signature,nonceStr,timestamp 和appId

    @RequestMapping(value = "/share", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> share(HttpServletRequest request) {
        String urlTemp = "http://" + request.getServerName() + request.getContextPath();
        String urlpath = "http://" + request.getServerName();
        String appUrl = request.getParameter("url");
        if (request.getParameter("code") != null) {
            appUrl += "&code=" + request.getParameter("code");
        }
        if (request.getParameter("state") != null) {
            appUrl += "&state=" + request.getParameter("state");
        }
        return WxConfigUtil.getSignature(appUrl, ContentValues.APPID, ContentValues.SECRET, urlTemp, urlpath);
    }

工具类我就把整个贴上来了,其中有些方法是没有用到的。

getSignature()整个方法是微信分享中的核心方法,用来获取signature,nonceStr,timestamp 和appId这几个核心参数。

package com.blog.common.util;

import com.alibaba.fastjson.JSONObject;
import com.blog.common.model.Token;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;


/**
 * 公众平台通用接口工具类
 *
 * @author james
 * @date 2015-02-27
 */
public class WxConfigUtil {
    // 获取access_token的接口地址(GET) 限2000(次/天)
    public final static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
    // 获取jsapi_ticket的接口地址(GET) 限2000(次/天)
    public final static String jsapi_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
    // 缓存添加的时间
    public static String cacheAddTime = null;
    // token,ticket缓存
    public static Map<String, Token> TOKEN_TICKET_CACHE = new HashMap<String, Token>();
    // token对应的key
    private static final String TOKEN = "token";
    // ticket对应的key
    private static final String TICKET = "ticket";

    /**
     * 外部获取签名入口类
     *
     * @param appUrl    应用的url
     * @return
     */
    public static Map<String, Object> getSignature(String appUrl, String appId, String secret, String url, String urlpath) {
        // 生成签名的随机串
        String noncestr = RandomUtil.getStringRandom(4);
        if (appUrl == null || "".equals(appUrl)) {
            return null;
        }
        String signature = null;
        Token accessTocken = getToken(appId, secret, System.currentTimeMillis() / 1000);
        Token accessTicket = getTicket(accessTocken.getToken(), System.currentTimeMillis() / 1000);
        signature = signature(accessTicket.getTicket(), cacheAddTime, noncestr, appUrl);
        System.out.println("-=-=-=-=-=-=-=-=appUrl:" + appUrl);
        System.out.println("-=-=-=-=-=-=-=-=token:" + accessTocken.getToken());
        System.out.println("-=-=-=-=-=-=-=-=ticket:" + accessTicket.getTicket());
        System.out.println("-=-=-=-=-=-=-=-=signature:" + signature);
        System.out.println("-=-=-=-=-=-=-=-=timestamp:" + cacheAddTime);
        Map<String, Object> map = new HashMap<>();
        map.put("appId", appId);
        map.put("timestamp", cacheAddTime);
        map.put("nonceStr", noncestr);
        map.put("appUrl", appUrl);
        map.put("signature", signature);
        map.put("url", url);
        map.put("urlpath", urlpath);
        return map;
    }

    /**
     * 获得Token
     *
     * @return
     */
    public static String getToken(String appId, String secret) {
        Token accessTocken = getToken(appId, secret, System.currentTimeMillis() / 1000);
        return accessTocken.getToken();
    }

    /**
     * 签名
     *
     * @param timestamp
     * @return
     */
    private static String signature(String jsapi_ticket, String timestamp, String noncestr, String url) {
        jsapi_ticket = "jsapi_ticket=" + jsapi_ticket;
        timestamp = "timestamp=" + timestamp;
        noncestr = "noncestr=" + noncestr;
        url = "url=" + url;
        String[] arr = new String[]{jsapi_ticket, noncestr, timestamp, url};
        // 将token、timestamp、nonce,url参数进行字典序排序
        Arrays.sort(arr);
        StringBuilder content = new StringBuilder();
        for (int i = 0; i < arr.length; i++) {
            content.append(arr[i]);
            if (i != arr.length - 1) {
                content.append("&");
            }
        }
        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;
        return tmpStr;
    }

    /**
     * 获取access_token
     *
     * @param appid     凭证
     * @param appsecret 密钥
     * @return
     */
    public static Token getToken(String appid, String appsecret, long currentTime) {
        Token tockenTicketCache = getTokenTicket(TOKEN);
        Token Token = null;

        if (tockenTicketCache != null && (currentTime - tockenTicketCache.getAddTime() <= tockenTicketCache.getExpiresIn())) {// 缓存存在并且没过期
            System.out.println("==========缓存中token已获取时长为:" + (currentTime - tockenTicketCache.getAddTime()) + "毫秒,可以重新使用");
            return tockenTicketCache;
        }
        System.out.println("==========缓存中token不存在或已过期===============");
        String requestUrl = access_token_url.replace("APPID", appid).replace("APPSECRET", appsecret);
        JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
        // 如果请求成功
        if (null != jsonObject) {
            Token = new Token();
            Token.setToken(jsonObject.getString("access_token"));
            Token.setExpiresIn(jsonObject.getIntValue("expires_in") / 2);// 正常过期时间是7200秒,此处设置3600秒读取一次
            System.out.println("==========tocket缓存过期时间为:" + Token.getExpiresIn() + "毫秒");
            Token.setAddTime(currentTime);
            updateToken(TOKEN, Token);
        }
        return Token;
    }

    /**
     * 获取ticket
     *
     * @param token
     * @return
     */
    private static Token getTicket(String token, long currentTime) {
        Token tockenTicketCache = getTokenTicket(TICKET);
        Token Token = null;
        if (tockenTicketCache != null && (currentTime - tockenTicketCache.getAddTime() <= tockenTicketCache.getExpiresIn())) {// 缓存中有ticket
            System.out.println("==========缓存中ticket已获取时长为:" + (currentTime - tockenTicketCache.getAddTime()) + "毫秒,可以重新使用");
            return tockenTicketCache;
        }
        System.out.println("==========缓存中ticket不存在或已过期===============");
        String requestUrl = jsapi_ticket_url.replace("ACCESS_TOKEN", token);
        JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
        // 如果请求成功
        if (null != jsonObject) {
            Token = new Token();
            Token.setTicket(jsonObject.getString("ticket"));
            Token.setExpiresIn(jsonObject.getIntValue("expires_in") / 2);// 正常过期时间是7200秒,此处设置3600秒读取一次
            System.out.println("==========ticket缓存过期时间为:" + Token.getExpiresIn() + "毫秒");
            Token.setAddTime(currentTime);
            updateToken(TICKET, Token);
        }
        return Token;
    }

    /**
     * 发起https请求并获取结果
     *
     * @param requestUrl    请求地址
     * @param requestMethod 请求方式(GET、POST)
     * @param outputStr     提交的数据
     * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
     */
    private static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
        JSONObject jsonObject = null;
        StringBuffer buffer = new StringBuffer();
        try {
            // 创建SSLContext对象,并使用我们指定的信任管理器初始化
            TrustManager[] tm = {new MyX509TrustManager()};
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();

            URL url = new URL(requestUrl);
            HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
            httpUrlConn.setSSLSocketFactory(ssf);

            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);
            // 设置请求方式(GET/POST)
            httpUrlConn.setRequestMethod(requestMethod);

            if ("GET".equalsIgnoreCase(requestMethod))
                httpUrlConn.connect();

            // 当有数据需要提交时
            if (null != outputStr) {
                OutputStream outputStream = httpUrlConn.getOutputStream();
                // 注意编码格式,防止中文乱码
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }

            // 将返回的输入流转换成字符串
            InputStream inputStream = httpUrlConn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            // 释放资源
            inputStream.close();
            inputStream = null;
            httpUrlConn.disconnect();
            jsonObject = JSONObject.parseObject(buffer.toString());
            // jsonObject = JSONObject.fromObject(buffer.toString());
        } catch (ConnectException ce) {
            System.out.println("Weixin server connection timed out.");
        } catch (Exception e) {
            System.out.println("https request error:{}" + e.getMessage());
        }
        return jsonObject;
    }

    /**
     * 将字节数组转换为十六进制字符串
     *
     * @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;
    }

    /**
     * 从缓存中读取token或者ticket
     *
     * @return
     */
    private static Token getTokenTicket(String key) {
        if (TOKEN_TICKET_CACHE != null && TOKEN_TICKET_CACHE.get(key) != null) {
            System.out.println("==========从缓存中获取到了" + key + "成功===============");
            return TOKEN_TICKET_CACHE.get(key);
        }
        return null;
    }

    /**
     * 更新缓存中token或者ticket
     *
     * @return
     */
    private static void updateToken(String key, Token accessTocken) {
        if (TOKEN_TICKET_CACHE != null && TOKEN_TICKET_CACHE.get(key) != null) {
            TOKEN_TICKET_CACHE.remove(key);
            System.out.println("==========从缓存中删除" + key + "成功===============");
        }
        TOKEN_TICKET_CACHE.put(key, accessTocken);
        cacheAddTime = String.valueOf(accessTocken.getAddTime());// 更新缓存修改的时间
        System.out.println("==========更新缓存中" + key + "成功===============");
    }

}

友情链接:https://blog.csdn.net/shrmuscles/article/details/77987185https://blog.csdn.net/qq_29057491/article/details/61191566

2019-11-08 14:01:48 sinat_27535209 阅读数 93
  • 微信沙箱开发微信社交立减金接口升级

    会员免费看,http://edu.csdn.net/lecturer/842右侧可办理会员卡。微信沙箱也叫微信仿真测试系统,微信沙箱开发是子恒老师《子恒说微信开发》视频教程的第18部。详细讲解了微信沙箱开发过程,内容包含微信沙箱作用,获取微信沙箱验签秘钥KEY,在沙箱中实现社交立减金接口升级等等。欢迎反馈,微信号:QQ68183131

    7545 人正在学习 去看看 秦子恒

安卓微信的api,个人微信开发API协议,微信 ipad sdk,微信ipad协议,微信web版接口api,微信网页版接口,微信电脑版sdk,微信开发sdk,微信开发API,微信协议,微信接口文档sdk,替代微信ipad协议的api接口,网页个人微信api分享,微信机器人SDK接口API,个人微信号API接口,微信群API接口

1、基础消息类型
1、客户端发送的心跳包HeartBeatReq = 1001; 
2、消息接收确认回复(接收或拒绝接收)MsgReceivedAck = 1002; 
3、错误单独提升为一种消息类型Error = 1003; 
4、通用任务执行结果通知TaskResultNotice = 1025; 
2、设备客户端授权类消息
1、设备(手机客户端、客服客户端)获取通信token请求与响应DeviceAuthReq = 1010; 
设备(手机客户端、客服客户端)获取通信token响应DeviceAuthRsp = 1011;
2、设备授权后退出(仅用于服务端内部)DeviceExitNotice = 1012; 
3、账号强制下线通知 AccountForceOfflineNotice = 1013; 
3、手机客户端上传的通知类消息
1、手机客户端微信上线通知 WeChatOnlineNotice = 1020; 
2、手机客户端微信下线通知 WeChatOfflineNotice = 1021; 
3、微信个人号新增好友通知FriendAddNotice = 1022;
4、微信个人号移除好友通知FriendDelNotice = 1023; 
5、微信好友发来聊天消息通知FriendTalkNotice = 1024; 
6、手机上回复好友的聊天消息通知WeChatTalkToFriendNotice = 1026; 
7、有好友请求添加好友的通知FriendAddReqeustNotice = 1027; 
8、手机上发送了朋友圈通知CircleNewPublishNotice = 1031; 
9、手机上删除朋友圈返回通知CircleDelNotice = 1032; 
10、手机检测到有人点赞/取消点赞通知CircleLikeNotice = 1033; 
11、手机检测到有人评论/删除朋友圈通知CircleCommentNotice = 1034; 
12、消息标记为已读PostMessageReadNotice = 1035; 
13、群聊新增通知ChatRoomAddNotice = 1037; 
14、群聊信息变更通知ChatRoomChangedNotice = 1042;
15、群聊删除通知返回ChatRoomDelNotice = 1041; 
16、联系人标签新增,修改通知ContactLabelAddNotice = 1038; 
17、联系人标签删除通知ContactLabelDelNotice = 1044; // 联系人标签删除通知
18、新增公众号通知BizContactAddNotice = 2038; // 新增公众号通知
19、手机端推送当前sdk的安装版本通知PostDeviceInfoNotice = 2027; 
4、服务端、客服客户端发给设备的指令类消息(sdk咨询微信836869520)
1、给好友发消息任务TalkToFriendTask = 1070; 
返回聊天执行结果TalkToFriendTaskResultNotice = 1028; 
2、发送朋友圈任务及结果返回PostSNSNewsTask = 1071; 
返回发送朋友圈数据结果PostSNSNewsTaskResultNotice = 1073; 
3、删除朋友圈任务与结果返回DeleteSNSNewsTask = 1074; 
返回通用任务执行结果
4、主动添加好友任务及返回结果AddFriendsTask = 1072; 
返回通用任务执行结果
5、接受好友请求任务及返回结果AcceptFriendAddRequestTask = 1075; 
返回通用任务执行结果
6、群发消息任务WeChatGroupSendTask = 1076; 
返回通用任务执行结果
7、执行养号动作命令任务WeChatMaintenanceTask = 1077; 
返回通用任务执行结果
8、养号任务停止任务及返回结果PostStopWeChatMaintenanceTask = 1100; 
返回通用任务执行结果
9、清粉任务及返回结果PostFriendDetectTask = 1095; 
返回:每隔一段时间手机端回传检测清粉好友数PostFriendDetectCountNotice = 2028; 
10、终止清粉任务及返回结果PostStopFriendDetectTask = 1096; 
返回通用任务执行结果
11、请求聊天图片或视频消息的详细内容任务与结果返回RequestTalkDetailTask = 1078; 
返回聊天图片或视频消息的详细内容结果RequestTalkDetailTaskResultNotice = 1029; 
12、要求手机上传当前微信二维码任务及返回PullWeChatQrCodeTask = 1079; 
返回手机端微信的二维码PullWeChatQrCodeTaskResultNotice = 1030; 
13、触发手机推送好友列表任务及结果返回TriggerFriendPushTask = 1080; 
返回一:手机端推送好友列表(分页,每页100)FriendPushNotice = 2026;
返回二:手机端推送标签列表
14、触发手机推送朋友圈列表任务及结果返回TriggerCirclePushTask = 1081; 
返回手机朋友圈数据(分页,每页20)CirclePushNotice = 2029; 
15、朋友圈评论删除任务及结果返回CircleCommentDeleteTask = 1082; 
朋友圈评论删除任务反馈 CircleCommentDeleteTaskResultNotice = 1083; 
16、朋友圈评论回复任务及结果返回CircleCommentReplyTask = 1084; 
朋友圈评论回复反馈CircleCommentReplyTaskResultNotice = 1085; 
17、通知手机将某个聊天窗口置为已读TriggerMessageReadTask = 1086; 
无返回
18、消息撤回任务RevokeMessageTask = 1087; 
返回通用任务执行结果
19、转发消息任务ForwardMessageTask = 1088;
返回通用任务执行结果
20、通知手机推送历史聊天记录任务及返回TriggerHistoryMsgPushTask = 1089; 
返回历史消息(分页,每页50)HistoryMsgPushNotice = 2033; 
21、获取群聊二维码任务及结果返回PullChatRoomQrCodeTask = 1090; 
返回群二维码PullChatRoomQrCodeTaskResultNotice = 1043;
22、朋友圈点赞任务及结果返回PostMomentsPraiseTask = 1098; 
返回朋友圈点赞数量PostMomentsPraiseCountNotice = 2030; 
23、停止朋友圈点赞任务PostStopMomentsPraiseTask = 1099; 
返回通用任务执行结果
24、修改联系人备注任务ModifyFriendMemoTask = 1101; 
返回通用任务执行结果
25、领取红包或转账收钱任务及返回TakeLuckyMoneyTask = 1200; 
返回收钱任务执行结果TakeMoneyTaskResultNotice = 1039; 
26、获取指定好友朋友圈任务及返回PullFriendCircleTask = 1201; 
返回手机朋友圈数据CirclePushNotice = 2029; 
27、获取朋友圈的图片任务及返回PullCircleDetailTask = 1202; 
返回朋友圈图片上传信息CircleDetailNotice = 1040; 
28、单条朋友圈点赞任务CircleLikeTask = 1203; 
返回通用任务执行结果
29、触发手机推送群聊列表任务及结果返回TriggerChatroomPushTask = 1210; 
返回一:手机端推送群聊列表(分页,每页2个)ChatroomPushNotice = 2031; 
返回二:群成员(陌生人)信息列表(分页,每页100)ChatRoomMembersNotice = 2034; 
30、请求具体群聊的详细信息任务RequestChatRoomInfoTask = 1211; 
返回ChatRoomAddNotice 群聊新增通知
31、获取联系人详细信息任务及返回
(不一定是好友,如群聊成员)RequestContactsInfoTask = 1212; 
返回联系人信息ContactsInfoNotice = 1036; 
32、群聊管理任务及返回ChatRoomActionTask = 1213; 
返回通用任务执行结果
返回群聊通知类返回结果
33、群内加好友任务AddFriendInChatRoomTask = 1214;
返回通用任务执行结果
34、通讯录加好友任务AddFriendFromPhonebookTask = 1215; 
返回通用任务执行结果
35、删除好友任务及返回DeleteFriendTask = 1216;  
返回通用任务执行结果
微信个人号移除好友通知
36、发红包任务及返回  
github地址https://www.wuliaokankan.cn/url301/138.html

SendLuckyMoneyTask = 1217; 返回:通用任务执行结果,成功ErrMsg=sendId
37、获取聊天消息的原始内容(主要是xml内容)任务及返回RequestTalkContentTask = 1218; 
返回聊天消息的原始内容RequestTalkContentTaskResultNotice = 1219; 
38、转发消息内容任务及返回ForwardMessageByContentTask = 1220; 
返回通用任务执行结果
39、群主通过入群申请任务及返回ChatRoomInviteApproveTask = 1221;
返回通用任务执行结果
40、设置联系人标签任务及返回ContactLabelTask = 1224; // 设置联系人标签
返回联系人标签新增,修改通知;
返回通用任务执行结果
41、删除联系人标签任务及返回ContactLabelDeleteTask = 1225; // 删除联系人标签
返回通用任务执行结果
返回联系人标签删除通知
42、语音消息转文字命令及返回VoiceTransTextTask = 1226; // 语音消息转文字
返回:通用任务执行结果,成功ErrMsg=文字内容
43、查找微信联系人任务及返回FindContactTask = 1227; // 查找微信联系人
返回查找微信联系人结果
FindContactTaskResult = 1228; // 查找微信联系人结果
44、同意加入群聊命令及返回AgreeJoinChatRoomTask = 1229; // 同意加入群聊
返回通用任务执行结果
45、清空聊天记录任务及返回ClearAllChatMsgTask= 1230; // 清空聊天记录
返回通用任务执行结果
46、聊天界面发送朋友验证任务及返回(别人把你删掉了,你发消息会出现一个发送朋友验证的链接,此处有用到)
返回通用任务执行结果
47、获取会话列表任务及返回TriggerConversationPushTask = 1232; // 会话列表推送
返回聊天会话列表(分页)ConversationPushNotice = 2035; // 会话列表
48、微信设置(改昵称,头像)任务及返回WechatSettingTask = 1233; // 微信设置:改昵称,头像
返回通用任务执行结果
49、获取加好友请求列表任务及返回结果PullFriendAddReqListTask = 1234; //获取加好友请求列表
返回请求加好友列表FriendAddReqListNotice = 2036; // 加好友请求列表
50、获取公众号列表任务及结果返回TriggerBizContactPushTask = 1235; // 获取公众号列表
返回公众号列表BizContactPushNotice = 2037; // 公众号列表推送
51、获取时间段内的所有聊天消息msgSvrId及结果返回TriggerChatMsgIdsPushTask = 1251;
52、名片加好友任务及结果返回AddFriendNameCardTask = 1236; // 名片加好友
返回通用任务执行结果
53、根据msgSvrId获取聊天消息及结果返回RequestTalkMsgTask = 1252;  // 根据msgSvrId获取聊天消息
返回RequestTalkMsgTaskResultNotice = 1253;  
5、服务端通知执行的命令 微信sdk
1、微信账号登出命令WechatLogoutTask = 1222;
无返回;微信退出会触发微信离线通知(WeChatOfflineNoticeMessage)
2、手机操作指令(重启手机等)PhoneActionTask = 1223; // 手机操作指令
返回:通用任务执行结果,(上传本地文件:ErrMsg=文件url)
3、通知手机客户端软件升级UpgradeDeviceAppNotice = 1094; 
无返回
4、服务端删除设备通知手机端PostDeleteDeviceNotice = 1097; 
无返回
安卓微信的api,个人微信开发API协议,微信 ipad sdk,微信ipad协议,微信web版接口api,微信网页版接口,微信电脑版sdk,微信开发sdk,微信开发API,微信协议,微信接口文档sdk,替代微信ipad协议的api接口,网页个人微信api分享,微信机器人SDK接口API,个人微信号API接口,微信群API接口


2019-10-25 19:15:28 java666668888 阅读数 67
  • 微信沙箱开发微信社交立减金接口升级

    会员免费看,http://edu.csdn.net/lecturer/842右侧可办理会员卡。微信沙箱也叫微信仿真测试系统,微信沙箱开发是子恒老师《子恒说微信开发》视频教程的第18部。详细讲解了微信沙箱开发过程,内容包含微信沙箱作用,获取微信沙箱验签秘钥KEY,在沙箱中实现社交立减金接口升级等等。欢迎反馈,微信号:QQ68183131

    7545 人正在学习 去看看 秦子恒

安卓微信的api,个人微信开发API协议,微信 ipad sdk,微信ipad协议,微信web版接口api,微信网页版接口,微信电脑版sdk,微信开发sdk,微信开发API,微信协议,微信接口文档sdk,替代微信ipad协议的api接口,网页个人微信api分享
1、基础消息类型
1、客户端发送的心跳包HeartBeatReq = 1001; 
2、消息接收确认回复(接收或拒绝接收)MsgReceivedAck = 1002; 
3、错误单独提升为一种消息类型Error = 1003; 
4、通用任务执行结果通知TaskResultNotice = 1025; 
2、设备客户端授权类消息
1、设备(手机客户端、客服客户端)获取通信token请求与响应DeviceAuthReq = 1010; 
设备(手机客户端、客服客户端)获取通信token响应DeviceAuthRsp = 1011;
2、设备授权后退出(仅用于服务端内部)DeviceExitNotice = 1012; 
3、账号强制下线通知 AccountForceOfflineNotice = 1013; 
3、手机客户端上传的通知类消息
1、手机客户端微信上线通知 WeChatOnlineNotice = 1020; 
2、手机客户端微信下线通知 WeChatOfflineNotice = 1021; 
3、微信个人号新增好友通知FriendAddNotice = 1022;
4、微信个人号移除好友通知FriendDelNotice = 1023; 
5、微信好友发来聊天消息通知FriendTalkNotice = 1024; 
6、手机上回复好友的聊天消息通知WeChatTalkToFriendNotice = 1026; 
7、有好友请求添加好友的通知FriendAddReqeustNotice = 1027; 
8、手机上发送了朋友圈通知CircleNewPublishNotice = 1031; 
9、手机上删除朋友圈返回通知CircleDelNotice = 1032; 
10、手机检测到有人点赞/取消点赞通知CircleLikeNotice = 1033; 
11、手机检测到有人评论/删除朋友圈通知CircleCommentNotice = 1034; 
12、消息标记为已读PostMessageReadNotice = 1035; 
13、群聊新增通知ChatRoomAddNotice = 1037; 
14、群聊信息变更通知ChatRoomChangedNotice = 1042;
15、群聊删除通知返回ChatRoomDelNotice = 1041; 
16、联系人标签新增,修改通知ContactLabelAddNotice = 1038; 
17、联系人标签删除通知ContactLabelDelNotice = 1044; // 联系人标签删除通知
18、新增公众号通知BizContactAddNotice = 2038; // 新增公众号通知
19、手机端推送当前sdk的安装版本通知PostDeviceInfoNotice = 2027; 
4、服务端、客服客户端发给设备的指令类消息(sdk咨询微信836869520)
1、给好友发消息任务TalkToFriendTask = 1070; 
返回聊天执行结果TalkToFriendTaskResultNotice = 1028; 
2、发送朋友圈任务及结果返回PostSNSNewsTask = 1071; 
返回发送朋友圈数据结果PostSNSNewsTaskResultNotice = 1073; 
3、删除朋友圈任务与结果返回DeleteSNSNewsTask = 1074; 
返回通用任务执行结果
4、主动添加好友任务及返回结果AddFriendsTask = 1072; 
返回通用任务执行结果
5、接受好友请求任务及返回结果AcceptFriendAddRequestTask = 1075; 
返回通用任务执行结果
6、群发消息任务WeChatGroupSendTask = 1076; 
返回通用任务执行结果
7、执行养号动作命令任务WeChatMaintenanceTask = 1077; 
返回通用任务执行结果
8、养号任务停止任务及返回结果PostStopWeChatMaintenanceTask = 1100; 
返回通用任务执行结果
9、清粉任务及返回结果PostFriendDetectTask = 1095; 
返回:每隔一段时间手机端回传检测清粉好友数PostFriendDetectCountNotice = 2028; 
10、终止清粉任务及返回结果PostStopFriendDetectTask = 1096; 
返回通用任务执行结果
11、请求聊天图片或视频消息的详细内容任务与结果返回RequestTalkDetailTask = 1078; 
返回聊天图片或视频消息的详细内容结果RequestTalkDetailTaskResultNotice = 1029; 
12、要求手机上传当前微信二维码任务及返回PullWeChatQrCodeTask = 1079; 
返回手机端微信的二维码PullWeChatQrCodeTaskResultNotice = 1030; 
13、触发手机推送好友列表任务及结果返回TriggerFriendPushTask = 1080; 
返回一:手机端推送好友列表(分页,每页100)FriendPushNotice = 2026;
返回二:手机端推送标签列表
14、触发手机推送朋友圈列表任务及结果返回TriggerCirclePushTask = 1081; 
返回手机朋友圈数据(分页,每页20)CirclePushNotice = 2029; 
15、朋友圈评论删除任务及结果返回CircleCommentDeleteTask = 1082; 
朋友圈评论删除任务反馈 CircleCommentDeleteTaskResultNotice = 1083; 
16、朋友圈评论回复任务及结果返回CircleCommentReplyTask = 1084; 
朋友圈评论回复反馈CircleCommentReplyTaskResultNotice = 1085; 
17、通知手机将某个聊天窗口置为已读TriggerMessageReadTask = 1086; 
无返回
18、消息撤回任务RevokeMessageTask = 1087; 
返回通用任务执行结果
19、转发消息任务ForwardMessageTask = 1088;
返回通用任务执行结果
20、通知手机推送历史聊天记录任务及返回TriggerHistoryMsgPushTask = 1089; 
返回历史消息(分页,每页50)HistoryMsgPushNotice = 2033; 
21、获取群聊二维码任务及结果返回PullChatRoomQrCodeTask = 1090; 
返回群二维码PullChatRoomQrCodeTaskResultNotice = 1043;
22、朋友圈点赞任务及结果返回PostMomentsPraiseTask = 1098; 
返回朋友圈点赞数量PostMomentsPraiseCountNotice = 2030; 
23、停止朋友圈点赞任务PostStopMomentsPraiseTask = 1099; 
返回通用任务执行结果
24、修改联系人备注任务ModifyFriendMemoTask = 1101; 
返回通用任务执行结果
25、领取红包或转账收钱任务及返回TakeLuckyMoneyTask = 1200; 
返回收钱任务执行结果TakeMoneyTaskResultNotice = 1039; 
26、获取指定好友朋友圈任务及返回PullFriendCircleTask = 1201; 
返回手机朋友圈数据CirclePushNotice = 2029; 
27、获取朋友圈的图片任务及返回PullCircleDetailTask = 1202; 
返回朋友圈图片上传信息CircleDetailNotice = 1040; 
28、单条朋友圈点赞任务CircleLikeTask = 1203; 
返回通用任务执行结果
29、触发手机推送群聊列表任务及结果返回TriggerChatroomPushTask = 1210; 
返回一:手机端推送群聊列表(分页,每页2个)ChatroomPushNotice = 2031; 
返回二:群成员(陌生人)信息列表(分页,每页100)ChatRoomMembersNotice = 2034; 
30、请求具体群聊的详细信息任务RequestChatRoomInfoTask = 1211; 
返回ChatRoomAddNotice 群聊新增通知
31、获取联系人详细信息任务及返回
(不一定是好友,如群聊成员)RequestContactsInfoTask = 1212; 
返回联系人信息ContactsInfoNotice = 1036; 
32、群聊管理任务及返回ChatRoomActionTask = 1213; 
返回通用任务执行结果
返回群聊通知类返回结果
33、群内加好友任务AddFriendInChatRoomTask = 1214;
返回通用任务执行结果
34、通讯录加好友任务AddFriendFromPhonebookTask = 1215; 
返回通用任务执行结果
35、删除好友任务及返回DeleteFriendTask = 1216;  
返回通用任务执行结果
微信个人号移除好友通知
36、发红包任务及返回  
github地址https://www.wuliaokankan.cn/url301/138.html

SendLuckyMoneyTask = 1217; 返回:通用任务执行结果,成功ErrMsg=sendId
37、获取聊天消息的原始内容(主要是xml内容)任务及返回RequestTalkContentTask = 1218; 
返回聊天消息的原始内容RequestTalkContentTaskResultNotice = 1219; 
38、转发消息内容任务及返回ForwardMessageByContentTask = 1220; 
返回通用任务执行结果
39、群主通过入群申请任务及返回ChatRoomInviteApproveTask = 1221;
返回通用任务执行结果
40、设置联系人标签任务及返回ContactLabelTask = 1224; // 设置联系人标签
返回联系人标签新增,修改通知;
返回通用任务执行结果
41、删除联系人标签任务及返回ContactLabelDeleteTask = 1225; // 删除联系人标签
返回通用任务执行结果
返回联系人标签删除通知
42、语音消息转文字命令及返回VoiceTransTextTask = 1226; // 语音消息转文字
返回:通用任务执行结果,成功ErrMsg=文字内容
43、查找微信联系人任务及返回FindContactTask = 1227; // 查找微信联系人
返回查找微信联系人结果
FindContactTaskResult = 1228; // 查找微信联系人结果
44、同意加入群聊命令及返回AgreeJoinChatRoomTask = 1229; // 同意加入群聊
返回通用任务执行结果
45、清空聊天记录任务及返回ClearAllChatMsgTask= 1230; // 清空聊天记录
返回通用任务执行结果
46、聊天界面发送朋友验证任务及返回(别人把你删掉了,你发消息会出现一个发送朋友验证的链接,此处有用到)
返回通用任务执行结果
47、获取会话列表任务及返回TriggerConversationPushTask = 1232; // 会话列表推送
返回聊天会话列表(分页)ConversationPushNotice = 2035; // 会话列表
48、微信设置(改昵称,头像)任务及返回WechatSettingTask = 1233; // 微信设置:改昵称,头像
返回通用任务执行结果
49、获取加好友请求列表任务及返回结果PullFriendAddReqListTask = 1234; //获取加好友请求列表
返回请求加好友列表FriendAddReqListNotice = 2036; // 加好友请求列表
50、获取公众号列表任务及结果返回TriggerBizContactPushTask = 1235; // 获取公众号列表
返回公众号列表BizContactPushNotice = 2037; // 公众号列表推送
51、获取时间段内的所有聊天消息msgSvrId及结果返回TriggerChatMsgIdsPushTask = 1251;
52、名片加好友任务及结果返回AddFriendNameCardTask = 1236; // 名片加好友
返回通用任务执行结果
53、根据msgSvrId获取聊天消息及结果返回RequestTalkMsgTask = 1252;  // 根据msgSvrId获取聊天消息
返回RequestTalkMsgTaskResultNotice = 1253;  
5、服务端通知执行的命令 微信sdk
1、微信账号登出命令WechatLogoutTask = 1222;
无返回;微信退出会触发微信离线通知(WeChatOfflineNoticeMessage)
2、手机操作指令(重启手机等)PhoneActionTask = 1223; // 手机操作指令
返回:通用任务执行结果,(上传本地文件:ErrMsg=文件url)
3、通知手机客户端软件升级UpgradeDeviceAppNotice = 1094; 
无返回
4、服务端删除设备通知手机端PostDeleteDeviceNotice = 1097; 
无返回
安卓微信的api,个人微信开发API协议,微信 ipad sdk,微信ipad协议,微信web版接口api,微信网页版接口,微信电脑版sdk,微信开发sdk,微信开发API,微信协议,微信接口文档sdk,替代微信ipad协议的api接口,网页个人微信api分享


微信开发API

阅读数 80

没有更多推荐了,返回首页