精华内容
下载资源
问答
  • Java实现微信统一服务消息

    千次阅读 2018-09-26 17:11:01
    下发小程序和公众号统一的服务消息,官方文档...统一服务消息接口能成功推送小程序模板消息,可以跳转到小程序页面。 统一服务消息接口能成功推送公众号模板消息,但是跳转小程序目前不行。经测试minipr...

    下发小程序和公众号统一的服务消息,官方文档https://developers.weixin.qq.com/miniprogram/dev/api/open-api/uniform-message/sendUniformMessage.html

    统一服务消息接口能成功推送小程序模板消息,可以跳转到小程序页面。

    统一服务消息接口能成功推送公众号模板消息,但是跳转小程序目前不行。经测试miniprogram本应该跳转到小程序页面,但未生效,而url跳转网页是可以的。有详情的为添加了url的,无详情的为未添加url只有miniprogram的。官方文档写到的参数都是必填,其实urlminiprogram都不是必填项,可参考服务号的模板消息与小程序的模板消息。

    下面是小程序模板消息效果,通过服务通知发送

    /**
    	 * 统一服务消息
    	 * 小程序模板消息,发送服务通知
    	 * @param token 小程序ACCESS_TOKEN
    	 * @param touser 用户openid,可以是小程序的openid,也可以是公众号的openid
    	 * @param template_id 小程序模板消息模板id
    	 * @param page 小程序页面路径
    	 * @param formid 小程序模板消息formid
    	 * @param data 小程序模板消息formid
    	 * @param emphasis_keyword 小程序模板放大关键词
    	 * @return
    	 * @author HGL
    	 */
    	public static JSONObject sendWeappMessage(String token,String touser,String template_id,
    			String page,String formid,JSONObject data){
    		JSONObject obj = new JSONObject();
    		JSONObject weapp_template_msg = new JSONObject();
    		JSONObject result = new JSONObject();
    		try {
    			String url = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token="+token;
    			obj.put("touser", touser);
    			weapp_template_msg.put("template_id", template_id);
    			weapp_template_msg.put("page", page);
    			weapp_template_msg.put("form_id", formid);
    			weapp_template_msg.put("data", data);
    			weapp_template_msg.put("emphasis_keyword", data.getJSONObject("keyword1").getString("value"));
    			obj.put("weapp_template_msg", weapp_template_msg);
    			result = HttpClientUtil.Post(url, obj);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		return result;
    	}
    	
    	/**
    	 * 统一服务消息
    	 * 公众号模板消息,发送公众号通知
    	 * @param token 小程序ACCESS_TOKEN
    	 * @param touser 用户openid,可以是小程序的openid,也可以是公众号的openid
    	 * @param appid 公众号appid
    	 * @param template_id 公众号模板消息模板id
    	 * @param url 公众号模板消息所要跳转的url
    	 * @param weappid 公众号模板消息所要跳转的小程序appid,小程序的必须与公众号具有绑定关系
    	 * @param pagepath 公众号模板消息所要跳转的小程序页面
    	 * @param data 公众号模板消息的数据
    	 * @return
    	 * @author HGL
    	 */
    	public static JSONObject sendMpMessage(String token,String touser,String appid,
    			String template_id,String url,String weappid,String pagepath,JSONObject data){
    		JSONObject result = new JSONObject();
    		JSONObject obj = new JSONObject();
    		JSONObject mp_template_msg = new JSONObject();
    		JSONObject miniprogram = new JSONObject();
    		try {
    			String path = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token="+token;
    			obj.put("touser", touser);
    			mp_template_msg.put("appid",appid);
    			mp_template_msg.put("template_id", template_id);
    			mp_template_msg.put("url",url);
    			miniprogram.put("appid", weappid);
    			miniprogram.put("pagepath", pagepath);
    			mp_template_msg.put("miniprogram", miniprogram);
    			mp_template_msg.put("data", data);
    			obj.put("mp_template_msg", mp_template_msg);
    			result = HttpClientUtil.Post(path, obj);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		return result;
    	}

     

    HttpClientUtil

    package com.fh.util;
    
    import java.io.IOException;
    
    import net.sf.json.JSONObject;
    
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.config.RequestConfig;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.util.EntityUtils;
    
    public class HttpClientUtil {
    	
    	/**
    	 * 
    	 * @param url
    	 * @param jsonObj
    	 * @return
    	 * @throws ClientProtocolException
    	 * @throws IOException
    	 */
    	public static JSONObject Post(String url,JSONObject jsonObj) throws ClientProtocolException, IOException{
    		HttpPost httpPost = new HttpPost(url); 
    		StringEntity entity = new StringEntity(jsonObj.toString(), "utf-8");
    		entity.setContentEncoding("UTF-8");
    		entity.setContentType("application/json");
    		httpPost.setEntity(entity);
    		DefaultHttpClient httpClient = new DefaultHttpClient();
    		HttpResponse response=httpClient.execute(httpPost);
    		String result = EntityUtils.toString(response.getEntity(), "UTF-8");
    		//输出调用结果
    		if(response != null && response.getStatusLine().getStatusCode() == 200) { 
    			// 生成 JSON 对象
    			JSONObject obj = JSONObject.fromObject(result);
    			return obj;
    		}
    		return null;
    		
    	}
    }
    

     

    展开全文
  • 小程序统一服务消息实现

    千次阅读 2019-03-05 20:18:14
    总体思路:运营后台处理某个任务时,推送相关消息到绑定了小程序的微信账户的服务通知里。需要用到用户的openid和用户在小程序中有交互动作产生的formId。 后台表结构设计: 小程序中的代码(taro-ui): &...

    总体思路:运营后台处理某个任务时,推送相关消息到绑定了小程序的微信账户的服务通知里。需要用到用户的openid和用户在小程序中有交互动作产生的formId。

    后台表结构设计:

     

    小程序中的代码(taro-ui):

    <View className="orderInfo">
              <View
                className="infoItem"
                onClick={this.navigateTo.bind(this, '/pages/order/unHandleOrder')}
              >
                <AtForm className="tb-submitForm"
                  onSubmit={this.onSubmit.bind(this)}
                  reportSubmit
                >
                  <AtButton formType='submit'  className="num tb-submitBtn">{orderCount}</AtButton>
                </AtForm>
                <View className="infoTip">处理订单</View>
              </View>
              <View className="vLine" />
              <View className="infoItem" onClick={this.navigateTo.bind(this, '/pages/me/msgCenter')}>
                <AtForm className="tb-submitForm"
                  onSubmit={this.onSubmit.bind(this)}
                  reportSubmit
                >
                  <AtButton formType='submit'  className="num tb-submitBtn">{msgCount}</AtButton>
                </AtForm>
                <View className="infoTip">未读消息</View>
              </View>
            </View>

     

      //表单提交事件,用于采集用户form_id
      onSubmit (event) {
        this.props.dispatch(action('app/updateUserFormId', event.detail.formId));
      }

    app.js:

    *updateUserFormId({ payload }, { select, call, put }) {
          try {
            const wechatId = yield select(state => state.app.openid);
            const formId = payload;
    
            console.log('updateUserFormId print formId : ' + formId);
            console.log('updateUserFormId print wechatId : ' + wechatId);
            const data = {
              urlParms: '/sys/api/v1/user/updateUserFormId',
              bodys: { wechatId, formId },
            };
            const res = yield call(request, data);
            if (res.code == 0) {
              // nothing to do
            } else {
              Taro.showToast({
                title: res.message,
                icon: 'none',
                duration: 2000,
              });
            }
          } catch (e) {
            console.log(e);
          }
        },

    后台代码:

    1)保存formId

    /**
    	 * 更新用户的formId
    	 * @author xxx
    	 * @date 2019-03-05 17:31:57
    	 * @param formId
    	 * @param wechatId
    	 * @return
    	 */
    	@RequestMapping("/updateUserFormId")
    	@ResponseBody
    	@HttpSecurityAnnotation(typeValue = MethodType.USER_SERVICE,openLog=true)
    	public String updateUserFormId(@NotBlank(message="formId不能为空") @Bodys(value="formId")String formId,
                    @NotBlank(message="wechatId不能为空") @Bodys(value="wechatId")String wechatId){
    		try{
    			userService.updateUserFormId(wechatId,formId);
    		}catch(Exception e){
    			log.error("更新用户的formId失败!",e);
    			return JSONUtil.wrapResponse(JSONUtil.ResponseCode.FAILURE,e.getMessage());
    		}
    		return JSONUtil.wrapResponse(JSONUtil.ResponseCode.SUCCESS,"更新用户的formId成功");
    	}

    1)发送模板消息:

    if(addOperation){	//	新增对账单,发送消息到买方微信(拥有对账权限的买方账号)。
    			String open = env.getProperty("wechat.uniformMessage.open","off");
    			if("off".equals(open)){	//发送统一服务消息开关已关闭
    				return;
    			}
    			//小程序跳转页面
    			String page = env.getProperty("wechat.duizhangdan.page","pages/me/index");
    
    			//7天 = 7 * 24 = 168小时,这里去掉1小时。
    			//当前时间往前推167个小时,如果用户的的formId最后更新时间大于这个时间,则说明formId有效。
    			//formId目前有效期微信给出的是7天。
    			Date newDate = DateUtils.addHours(new Date(),-167);
    
    			List<PersonVO> personList = this.userService.getMbrCellphones(ECAuthConstant.BLANACE_ACC, blanace.getBuyerId());
    			if(!personList.isEmpty()){
    				JSONObject data = new JSONObject();
    				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    
    				Map<String,Object> keyMap1 = new HashMap<String,Object>();
    				keyMap1.put("value",blanace.getBuyerName());
    				//添加客户名称
    				data.put("keyword1",keyMap1);
    
    				Map<String,Object> keyMap2 = new HashMap<String,Object>();
    				keyMap2.put("value",blanace.getSellerName());
    				//添加卖方名称
    				data.put("keyword2",keyMap2);
    
    				Map<String,Object> keyMap3 = new HashMap<String,Object>();
    				keyMap3.put("value",blanace.getMonth());
    				//添加对账月份
    				data.put("keyword3",keyMap3);
    
    				Map<String,Object> keyMap4 = new HashMap<String,Object>();
    				keyMap4.put("value",sdf.format(blanace.getCreateTime()));
    				//添加创建时间
    				data.put("keyword4",keyMap4);
    
    				for(PersonVO personVO : personList){
    					if(StringUtils.isEmpty(personVO.getWechatFormId())){
                            logger.warn("用户的微信formId为空,不发送消息!用户名[" + personVO.getPersonName() + "]");
    						continue;
                        }
                        if(personVO.getWechatFormIdModifyTime().before(newDate)){
                            //formId认为无效了,则不用发送了。
                            logger.warn("用户的微信formId时间已失效,不发送消息!用户名[" + personVO.getPersonName() + "]");
                            continue;
    					}
    
    					final UniformMsg uniformMsg = new UniformMsg();
    					uniformMsg.setTouser(personVO.getWechatId());
    					//uniformMsg.setTouser("oZaHr4iznKdHEjGremZZfvPS3X3k");
    					uniformMsg.setForm_id(personVO.getWechatFormId());
    					//uniformMsg.setForm_id("7821c2ceb9e848f1a95a2af8ce5f5a1c");
    					uniformMsg.setTemplate_id(env.getProperty("wechat.duizhangdan.template_id"));
    					uniformMsg.setPage(page); //小程序跳转页面
    					uniformMsg.setData(data);
    					this.taskExecutor.execute(new Runnable() {
    						public void run() {
    							wechatService.sendUniformMessage(uniformMsg);
    						}
    					});
    				}
    			}
    		}

    IWechatService.java:

        @Autowired
        private Environment env;
    
        @Autowired
        private RedisTemplate redisTemplate;
    
        private volatile Boolean init = false;
    
        private String appid;
        private String secret;
    
        //获取微信accessToken接口地址
        private String accessTokenIp;
    
        //获取微信发送统一模板消息接口地址
        private String uniformMessageIp;
    
    
        private void init(){
            init = true;
            appid = env.getProperty("wechat.appid");
            secret = env.getProperty("wechat.secret");
            accessTokenIp = env.getProperty("wechat.accesstoken.ip");
            uniformMessageIp = env.getProperty("wechat.uniformMessage.ip");
        }
    
    
        @Override
        public String getAccessToken() throws Exception{
            if(!init){
                init();
            }
    
            NameValuePair[] nameValuePairs = new NameValuePair[3];
    
            NameValuePair nameValuePair = new NameValuePair();
            nameValuePair.setName("appid");
            nameValuePair.setValue(this.appid);
    
            NameValuePair nameValuePair2 = new NameValuePair();
            nameValuePair2.setName("secret");
            nameValuePair2.setValue(this.secret);
    
            NameValuePair nameValuePair3 = new NameValuePair();
            nameValuePair3.setName("grant_type");
            nameValuePair3.setValue("client_credential");
    
            nameValuePairs[0] = nameValuePair;
            nameValuePairs[1] = nameValuePair2;
            nameValuePairs[2] = nameValuePair3;
    
            HttpClient client = new HttpClient();
            GetMethod method = new GetMethod(this.accessTokenIp);
            method.addRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            method.setQueryString(nameValuePairs);
    
            client.executeMethod(method);
            String retValue = method.getResponseBodyAsString();
            method.releaseConnection();
            JSONObject jsonObject = JSONObject.parseObject(retValue);
            if(jsonObject.get("errcode") != null){
                logger.warn("微信小程序接口,获取accessToken失败,原因:{}",jsonObject.get("errmsg"));
                return null;
            }
            logger.info("打印accessToken jsonObject:{}",jsonObject.toJSONString());
    
            //将微信accessToken放入redis中
            redisTemplate.opsForValue().set("wechatAccessToken",jsonObject.get("access_token"));
            return (String)jsonObject.get("access_token");
        }
    
    
    
        @Override
        public void sendUniformMessage(UniformMsg uniformMsg) {
            if(StringUtils.isEmpty(uniformMessageIp)){
                init();
            }
            Double randomNum = Math.random();
            String redisAccesssToken = (String) redisTemplate.opsForValue().get("wechatAccessToken");
            if(StringUtils.isEmpty(redisAccesssToken)){
                try {
                    this.getAccessToken();
                } catch (Exception e) {
                    logger.error("发送统一模板消息,获取accessToken异常!",e);
                    throw new RuntimeException("发送统一模板消息,获取accessToken异常!");
                }
            }
            redisAccesssToken = (String) redisTemplate.opsForValue().get("wechatAccessToken");
    
            uniformMsg.getWeapp_template_msg().put("template_id",uniformMsg.getTemplate_id());
            uniformMsg.getWeapp_template_msg().put("page",uniformMsg.getPage());
            uniformMsg.getWeapp_template_msg().put("form_id",uniformMsg.getForm_id());
            uniformMsg.getWeapp_template_msg().put("data",uniformMsg.getData());
            uniformMsg.getWeapp_template_msg().put("emphasis_keyword","");
    
            Map<String,Object> submitMap = Maps.newHashMap();
            submitMap.put("touser",uniformMsg.getTouser());
            submitMap.put("weapp_template_msg",uniformMsg.getWeapp_template_msg());
            //请求url
            String postUrl = this.uniformMessageIp + "?access_token=" + redisAccesssToken;
            //执行请求发送
            logger.info("[" + randomNum + "]submitMap:{}", JSON.toJSONString(submitMap));
            String retValue = "";
            try{
                retValue = this.httpsRequest(postUrl,"POST",JSON.toJSONString(submitMap));
            }catch(Exception e){
                logger.error(e.getMessage(),e);
                return;
            }
            logger.info("[" + randomNum + "]打印retValue:{}",retValue);
            logger.info("[" + randomNum + "]打印accessToken:{}",redisAccesssToken);
            //得到返回结果
            JSONObject jsonObject = JSONObject.parseObject(retValue);
            if(jsonObject.get("errcode") != null && (int)jsonObject.get("errcode") != 0){
                logger.warn("[" + randomNum + "]微信小程序接口,发送统一模板消息失败,原因:{}",jsonObject.get("errmsg"));
                if(DJECConstants.WechatUniformMsgErrcodeEnum.ACCESS_TOKEN_INVALID.getCode() == (int)jsonObject.get("errcode")){
                    logger.info("[" + randomNum + "]accessToken失效,重新获取token,再调一次。");
                    try {
                        redisAccesssToken = this.getAccessToken();
                    } catch (Exception e) {
                        logger.error(e.getMessage(),e);
                        return;
                    }
                    postUrl = this.uniformMessageIp + "?access_token=" + redisAccesssToken;
                    try{
                        //retValue = this.doPost(postUrl,JSON.toJSONString(submitMap));
                        retValue = this.httpsRequest(postUrl,"POST",JSON.toJSONString(submitMap));
                    }catch(Exception e){
                        logger.error(e.getMessage(),e);
                        return;
                    }
                    logger.info("[" + randomNum + "]打印retValue(第二次):{}",retValue);
                    //得到返回结果
                    jsonObject = JSONObject.parseObject(retValue);
                    if(jsonObject.get("errcode") != null && (int)jsonObject.get("errcode") !=0) {
                        logger.warn("[" + randomNum + "]微信小程序接口,发送统一模板消息(第二次)失败,原因:{}", jsonObject.get("errmsg"));
                        return;
                    }
                    logger.info("[" + randomNum + "]发送服务消息成功(第二次)。");
                }
                return;
            }
            logger.info("[" + randomNum + "]发送服务消息成功。");
        }
    
        //通用方法,执行请求连接。
        public String httpsRequest(String requestUrl, String requestMethod, String outputStr){
            try {
                URL url = new URL(requestUrl);
                HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
                conn.setDoOutput(true);
                conn.setDoInput(true);
                conn.setUseCaches(false);
                // 设置请求方式(GET/POST)
                conn.setRequestMethod(requestMethod);
                conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
                // 当outputStr不为null时向输出流写数据
                if (null != outputStr) {
                    OutputStream outputStream = conn.getOutputStream();
                    // 注意编码格式
                    outputStream.write(outputStr.getBytes("UTF-8"));
                    outputStream.close();
                }
                // 从输入流读取返回内容
                InputStream inputStream = conn.getInputStream();
                InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
                String str = null;
                StringBuffer buffer = new StringBuffer();
                while ((str = bufferedReader.readLine()) != null) {
                    buffer.append(str);
                }
                // 释放资源
                bufferedReader.close();
                inputStreamReader.close();
                inputStream.close();
                conn.disconnect();
                return buffer.toString();
            } catch (ConnectException ce) {
                logger.error("连接超时:{}",ce);
            } catch (Exception e) {
                logger.error("https请求异常:{}",e);
            }
            return null;
        }

    方法httpsRequest参考了:https://blog.csdn.net/wave_zf/article/details/82463715

    UniformMsg.java:

    import com.alibaba.fastjson.JSONObject;
    
    /**
     * 微信小程序统一发送模板消息对象
     * @author XXXX
     * @date 2019年3月1日 18:14:15
     */
    public class UniformMsg {
    
        /**
         * 微信小程序模板ID
         */
        private String template_id;
    
        /**
         * 微信用户绑定的小程序openid
         */
        private String touser;
    
        /**
         * 跳转至小程序的页面路径
         */
        private String page;
    
        /**
         * 表单提交场景下,为 submit 事件带上的 formId
         */
        private String form_id;
    
        /**
         * 模板需要放大的关键词,不填则默认无放大
         */
        private String emphasis_keyword;
    
        private JSONObject weapp_template_msg = new JSONObject();
    
        private JSONObject data = new JSONObject();
    
        public String getTemplate_id() {
            return template_id;
        }
    
        public void setTemplate_id(String template_id) {
            this.template_id = template_id;
        }
    
        public String getTouser() {
            return touser;
        }
    
        public void setTouser(String touser) {
            this.touser = touser;
        }
    
        public String getPage() {
            return page;
        }
    
        public void setPage(String page) {
            this.page = page;
        }
    
        public String getForm_id() {
            return form_id;
        }
    
        public void setForm_id(String form_id) {
            this.form_id = form_id;
        }
    
        public String getEmphasis_keyword() {
            return emphasis_keyword;
        }
    
        public void setEmphasis_keyword(String emphasis_keyword) {
            this.emphasis_keyword = emphasis_keyword;
        }
    
        public JSONObject getData() {
            return data;
        }
    
        public void setData(JSONObject data) {
            this.data = data;
        }
    
        public JSONObject getWeapp_template_msg() {
            return weapp_template_msg;
        }
    
        public void setWeapp_template_msg(JSONObject weapp_template_msg) {
            this.weapp_template_msg = weapp_template_msg;
        }
    }

    restful工具测试:

     

    request body json结构:

    {
        "touser" : "oZaHr4iznKdHEjGremZZfvPS3X3k",
        "weapp_template_msg" : {
            "data":{
                "keyword1":{
                    "value":"娄底建材工程有限公司"
                },
                "keyword2":{
                    "value":"2019-02"
                }
            },
            "template_id":"mfFyTYNfYJhEOKxbW5hPSYOvlhcztM3qoclq6SHJ04s",
            "form_id" : "70aff62c35a64ece84a281797cad095f",
            "page" : "pages/order/statementAccount"
        }
    }

     

    微信接收效果:

    展开全文
  • 注意:新发布的小程序不在支持统一服务消息,需要使用订阅消息功能 小程序模板消息接口将于2020年1月10日下线,开发者可使用订阅消息功能 1。获取模板id 首先要公众平台 登录上小程序管理平台 找到订阅消息》 ...

    注意:新发布的小程序不在支持统一服务消息,需要使用订阅消息功能

    小程序模板消息接口将于2020年1月10日下线,开发者可使用订阅消息功能

     

    1。获取模板id

    首先要公众平台 登录上小程序管理平台

    找到订阅消息》 添加我的模

     

    添加一个 获取到模板id

    如: -QQQNKEVORnwRUmwotyQQoZ_ObaSjkA44Qfn6AtIJUx

    2 ,授权

    https://developers.weixin.qq.com/miniprogram/dev/api/open-api/subscribe-message/wx.requestSubscribeMessage.html

    通过微信 api wx.requestSubscribeMessage(Object object)

    用户授权模板可以推送消息

     

    3 .服务端发送模板消息

    subscribeMessage.send

    https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html

     

     

    # todo 获取access_token

    def get_token():

    # APPID, SECRET = 'wx8fe512646732596d', '8725fc1e12b9750e3c90a38d3201dec2'

    url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}'.format(APPID,

    SECRET)

    respon = requests.get(url)

    content = respon.content

     

    content = content.decode('utf-8')

    data = json.loads(content)

    return data.get("access_token")

     

     

    # 微信模板

    MessageTemplates = ["-QQQNKEVORnwRUmwotyQQoZ_ObaSjkA44Qfn6AtIJUg",]

     

    def subscribeMessage_send(touser,template_id=MessageTemplates[0],json_data=None,page=None):

    """订阅消息发送服务消息"""

    # https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html#HTTPS%20调用

    token = get_token()

    if not token:

    return False

    url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={}".format(token)

     

    data = {}

    data["touser"] = touser

    data["template_id"] = template_id

    data["miniprogram_state"] = "formal"

     

    if page:

    data["page"] = page

     

    data["data"] = json_data

    try:

    response = requests.post(url,json=data,)

    content = response.content.decode('utf-8')

    data = json.loads(content)

    print(data)

    return data

    except Exception as e:

    return {'errcode': 2, 'errmsg': '通信失败'}

     

    测试:

     

    json_data= {

    "thing1": {

    "value": "339208499"

    },

    "thing2": {

    "value": "TIT创意园"

    },

    "date3": {

    "value": "2015年01月05日"

    }}

    subscribeMessage_send("o_Ezd4km_mrPxdMJ19ff0oU8ASuA", template_id=MessageTemplates[0], json_data=json_data, page="pages/today/today")

     

     

    展开全文
  • 工信部统一 Android 消息推送标准

    千次阅读 2019-06-25 14:54:45
    目录 一、介绍 二、推送技术发展 1、轮询方式 2、SMS短信推送方式 ...联盟核心任务是:探索推送行业创新,促进终端生产厂商、应用开发厂商和第三方服务提供商等进行深入合作,整合行业资源,助推形成统...

    目录

    一、介绍

    二、推送技术发展

    1、轮询方式

    2、SMS短信推送方式

    3、长连接推送方式

    三、统一推送

    四、作用

    五、具体时间表


    一、介绍

    统一推送联盟成立于2017年10月,挂靠单位是电信终端产业协会(TAF),接受工业和信息化部业务指导,住所设在北京。联盟核心任务是:探索推送行业创新,促进终端生产厂商、应用开发厂商和第三方服务提供商等进行深入合作,整合行业资源,助推形成统一的推送体系,创造绿色环境,减少与终端用户的利益冲突,提升整体行业形象,降低整体行业的实现成本,形成自律基础上的产业链协同发展,实现产业的共同繁荣。

      统一推送联盟是在自愿、平等、互利、合作的基础上,由国内外消息推送产业相关的企、事业单位、社团组织、高等院校、科研院所等自愿结成的跨行业、开放性、非营利性的社会组织。本联盟旨在促进相关主体之间的交流和深度合作,促进供需对接和知识共享,形成优势互补,有效推进消息推送产业的发展,切实解决产业现实问题。

     

    二、推送技术发展

    “推送”这一概念在1996年由PointCast 网络公司提出,旨在为用户提供更准确、更实时的消息推送。Google公司在2009年开发了C2DM(Cloud toDevice Messaging)推送技术以供Android平台的应用提供方进行消息推送。而后,苹果公司推出了APNS(Apple Push Notification service)推送技术,统一了IOS平台的推送业务。伴随着推送技术的发展,推送技术主要经历3个阶段,从轮询方式、SMS短信推送方式逐渐发展到长连接推送方式。

    1、轮询方式

    轮询是由客户端主动发起请求的推送方式。客户端通过与服务器的网络连接,以定时任务的方式询问服务器端是否有新的推送消息。这种方式的效率取决于请求频率的设计,如果请求频率过高,会消耗较多的资源;而若请求频率较低,则消息的延时较高,实时性得不到保证。

    2、SMS短信推送方式

    短信方式通过运营商的短信通道将消息发往客户设备。通过编码可以保证消息的保密性,应用再利用手机系统的短信拦截功能,获取推送消息,反向解码后推送给用户。短信方式的由于通过运营商渠道,推送的稳定性得以保障。但同时,由于要向运营商按推送量进行付费,因此成本较高,通常作为补充手段应用。

    3、长连接推送方式

    长连接推送方式是最为通用也是受到研究最多的推送方式。不同于“轮询”的消息传递方式,服务方通过保持与客户端的长连接,掌握了消息推送的主动权。客户端按一定频率向客户端发送一个心跳以保持长连接,当消息推送时直接通过长连接发送消息。长连接的推送方式,保证了消息推送的实时性。相比于“轮询”方式,长连接推送节省了客户端电量、流量等资源消耗。当然,当大量设备与服务器保持长连接时,服务器端的压力陡增,必须优化服务器以保持高并发下的良好性能。苹果公司的APNS推送方式、Google的C2DM推送方式以及基于MQTT协议或XMPP协议的推送都是基于长连接的方式进行消息的推送。

     

    三、统一推送

    由于一些特殊的原因,在国内的用户无法享受到谷歌安卓系统提供的 GMS 消息推送服务,不少国产安卓软件接收消息依靠后台服务存在,也由此出现了用户反映的耗电以及占用内存问题,不过未来这一问题有望得到全面解决。

    工信部旗下泰尔终端实验室发布消息称,各个终端厂商的系统级推送通道不可避免的存在差异性,因此,开发者同时接入、维护多条推送通道存在着一定的困难。在此背景下,泰尔终端实验室联合包括华为、OPPO、vivo、小米、三星、魅族、金立、努比亚、谷歌、百度、阿里巴巴、腾讯、个推、极光等国外内主要相关企业共同制定安卓统一推送服务(Unified Push Service,简称UPS)技术标准,旨在为国内的消息推送服务建立统一的标准,为终端用户提供更好的手机使用体验,为应用开发者更好解决消息推送需求,并取得了阶段性成果。

     

    四、作用

    “统一推送的标准”,对于消息推送会增强管理。例如,通过推送消息的相互拉起明确不被允许,利用透传消息拉起App的行为也被禁止。同时,为了保证用户体验,原则上也不支持推送消息的定制化(包括消息样式的定制化以及提示音的个性化,通知栏图标不允许使用外链),保证消息推送的公平性和用户界面的一致性。

     

    五、具体时间表

    201931日,联盟开始统一推送标准符合性测试。

    20191231日,现有各推送通道兼容统一推送标准。

     


     

    展开全文
  • 在做服务类小程序时,通常会遇到客户在客户端下单后,接单商家需要有新订单消息提醒的功能。由于小程序模板消息已下线无法使用,而小程序中的订阅消息需要...因此最终选择的方案为统一服务消息uniformMessage.send。
  • 经过测试发现是json格式出错。 公众微信平台下可以找到: 入参:{ "touser":"youropenid", "mp_template_msg":{"appid":"服务号APPID","template_id":"服务号模板编号","miniprogram":{"appid":"小程序APPID","page...
  • 整理自翟佳在 QCon2018 北京站的演讲,在本次演讲中,翟佳介绍了 Apache Pulsar 的架构、特性和其生态系统的组成,并展示了 Apache Pulsar 在消息、计算和存储三个方面进行的协调、抽象和统一。 - Messaging:...
  • redis消息队列性能测试及知识点整理

    万次阅读 2016-08-22 09:47:51
    消息队列性能测试 发送测试 接收测试 结论与比较 四.健壮性 持久化方案 RDB方式 AOF方式 优缺点 主从复制 原理 特点 配置 集群方案 一.概述 Redis是一个开源(BSD许可),内存存储的数据...
  • 首先在微信端配置好模板消息 内容如下,注意{{*.DATA}} 是固定写法,占位符,是需要被替换掉的内容。 {{first.DATA}} 订单商品:{{keyword1.DATA}} 订单编号:{{keyword2.DATA}} 支付金额:{{keyword3.DATA}}...
  • 服务接口统一返回的格式GOOD

    千次阅读 2016-10-25 18:24:10
    1.14.1 统一返回的格式 很明显地,默认情况下,我们选择了 JSON 作为统一的格式返回接口结果。这里简单说明一下选取JSON统一返回的原因: JSON当前很流行,且普通接口都采用此格式返回JSON在绝大部分开发语言中都...
  • 初识emqx消息服务器

    千次阅读 2019-04-16 18:15:17
    EMQ X R3.0 (Erlang/Enterprise/Elastic ...MQTT是一个由IBM主导开发的物联网传输协议,它被设计用于轻量级的发布/订阅式消息传输,旨在为低带宽和不稳定的网络环境中的物联网设备提供可靠的网络服务。它的核心设计...
  • 开发微信公众号的时候,我们经常会使用微信公众平台的测试号来进行调试,因为测试号的可用接口比较全,不然只有经过认证的服务号才可以调用比较高级的接口。 从开始搞一个微信公众平台测试号开始。 打开微信公众平台...
  • 1、Kafka是什么 Apache Kafka是一个开源消息系统,由Scala写成。是由Apache软件基金会...该项目的目标是为处理实时数据提供一个统一、高通量、低等待的平台。  Kafka是一个分布式消息队列:生产者、消费者的功能
  • 问:软件测试的原则? 答:https://blog.csdn.net/weixin_30363263/article/details/102986878 问:你在测试中发现了一个 bug ,但是开发经理认为这不是一个 bug ,你应该怎样解决。 1、将问题提交到缺陷...
  • 第三方服务接入云平台的统一方案

    千次阅读 2016-03-08 17:59:19
    今年,我的任务是为公司的私有云平台( PaaS )开发对应的云服务平台(我们称之为插件平台),这个云服务平台的主要任务,是为云平台接入一些服务服务包括但不限于mysql、redis、cdn等存储服务,天气预报等http...
  • 统一服务消息返回错误:{"errcode":40165,"errmsg":"invalid weapp pagepath hint: [bsAWua0201ge30]"} 小程序Canvas绘制图片太大,自动闪退,安卓会有crash问题 小程序Canvas生成图片draw()出现黑屏问题/不...
  • 目录背景需求目标企业微信群聊机器人微信官方文档简单介绍一下名词解释具体实现类清单及功能说明MessageSendServiceEnterpriceWechatRobotMessageSendServiceEnterpriseWeChatRobotMessageSendServiceImplEnterpriseRobotMessageDO测试Demo(使用方式)服务Bean构建测试用例...背景 需求目...
  • 天空之城:统一开发平台

    千次阅读 2012-02-19 14:27:52
    曾经在一家小公司工作一段时间后被一个大集团收购,集团旗下有十多个小公司,于是开始推行一种统一开发平台,统一所有开发人员的开发模式提升规模效应。 我曾使用那个平台进行业务系统开发,一套使用XML自定义的...
  • Kafka、RabbitMQ、RocketMQ等 消息中间件 介绍和对比

    万次阅读 多人点赞 2019-09-05 17:59:00
    文章目录1、前言2、概念2.1、MQ简介2.2、...3.1、Kafka3.2、RabbitMQ3.3、RocketMQ4、测试4.1、测试目的4.2、测试场景4.2.1、Kafka4.2.2、RocketMQ4.2.3、RabbitMQ4.3、测试结论5、消息队列优点对比5.1、各个消息队...
  • 软件测试笔试面试题目完全汇总

    万次阅读 多人点赞 2019-03-06 13:29:37
    1、软件测试的流程 2、web测试和APP测试的区别 仅仅从功能测试的层面上来讲的话,在流程和功能测试上是没有区别的。那么区别在哪里呢? 由于载体不一样,所以系统测试和一些细节可能会不一样。 那么我们就要先...
  • 移动端测试

    千次阅读 2019-10-15 22:50:42
    移动端测试移动端测试移动端测试概述一、移动端的认识1.什么是移动端2.移动端操作系统3....功能测试运行APP应用的前后台切换免登录数据更新离线浏览APP更新定位、照相服务时间测试PUSH测试消息推送测...
  • 在网上很多关于dubbo异常统一处理的博文,90%都是抄来抄去。大多都是先上一段dubbo中对于异常的统一处理的原码,然后说一堆的(甚至有12345,五种)不靠谱方案,最后再说“本篇使用的是方案4”,然后再对所谓的方案4...
  • 测试开发笔记

    万次阅读 多人点赞 2019-11-14 17:11:58
    测试开发笔记 第一章 测试基础 7 什么是软件测试: 7 ★软件测试的目的、意义:(怎么做好软件测试) 7 3.软件生命周期: 7 第二章 测试过程 8 1.测试模型 8 H模型: 8 V模型 9 2.内部测试 10 3外部测试: 10 验收...
  • 研发团队轻量级内部测试流程

    千次阅读 2014-10-15 08:20:04
    本文中讨论的研发团队内部测试流程是组织研发过程中需要标准化的协作流程中的一种,是一套用于规范需求、开发和测试人员进行服务发布质量控制的流程性指南和说明,确保整个团队对产品质量保证有一个统一认识,促进...
  • APP测试流程和测试

    万次阅读 多人点赞 2017-12-25 22:04:19
    1 APP测试基本流程 1.1流程图 1.2测试周期 测试周期可按项目的开发周期来确定测试时间,一般测试时间为两三周(即15个工作日),根据项目情况以及版本质量可适当缩短或延长测试时间。正式测试前先向...
  • SpringCloud统一配置中心

    千次阅读 2019-04-12 14:36:14
    在微服务中会有很多服务,每个服务中都会有一个配置文件,并且有些配置是一样的。 **例如:**在实际项目中,我们创建了用户和订单两个服务,这两个服务是同一个数据库,那么我们在这两个服务的配置文件都会配置相同...
  • 国内安卓统一推送通道

    千次阅读 2019-03-04 13:39:52
    国内安卓统一推送通道 众所周知,2017年,工信部旗下泰尔终端实验室联合包括华为...简称UPS)技术标准,旨在为国内的消息推送服务建立统一的标准,为终端用户提供更好的手机使用体验,为应用开发者更好解决消息推...
  • 接口测试工具Postman使用实践

    万次阅读 多人点赞 2017-12-05 16:18:55
    接口测试工具Postman使用实践本次chat内容包括: 接口的定义 接口的分类 为何要进行接口测试 接口文档示例 Postman工具简介 借助Postman完成HTTP请求接口测试 Postman + Newman + Jenkins 实现接口自动化测试 一、...
  • c++ 消息分发 消息管理

    千次阅读 2018-07-05 10:13:43
    消息分发机制 当接收到前端发来的消息并解析后 根据包头的消息码来决定分发到哪个模块,以及调用哪个函数步骤1、需要注册消息码 为了之后找到这个消息码需要干什么事步骤2、接收到消息并解析后调用根据解析的包头里...
  • 手机测试之彩信测试

    千次阅读 2008-11-18 11:18:00
    一、什么是彩信: 彩信的英文名是MMS,它是Multimedia Messaging Service的缩写,意为多媒体信息服务,通常又称为彩信。它最大的特色就是支持多媒体功能,能够传递功能全面的内容和信息,这些信息包括文字、图像...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 103,170
精华内容 41,268
关键字:

统一服务消息怎么测试