zoukankan      html  css  js  c++  java
  • 微信公众号开发之根据OpenID列表群发(十四)

    上一篇我们讲述了《微信公众号开发之根据标签进行群发(十二)》,这次我们讲解一下【根据OpenID列表群发】

    根据OpenID列表群发【订阅号不可用,服务号认证后可用】

    接口调用请求说明

    http请求方式: POST https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token=ACCESS_TOKEN

    POST数据说明

    POST数据示例如下:

    图文消息(注意图文消息的media_id需要通过上述方法来得到):

    {
       "touser":[
        "OPENID1",
        "OPENID2"
       ],
       "mpnews":{
          "media_id":"123dsdajkasd231jhksad"
       },
        "msgtype":"mpnews",
        "send_ignore_reprint":0
    }
    

    文本:

    {
       "touser":[
        "OPENID1",
        "OPENID2"
       ],
        "msgtype": "text",
        "text": { "content": "hello from boxer."}
    }
    

    语音:

    {
       "touser":[
        "OPENID1",
        "OPENID2"
       ],
       "voice":{
          "media_id":"mLxl6paC7z2Tl-NJT64yzJve8T9c8u9K2x-Ai6Ujd4lIH9IBuF6-2r66mamn_gIT"
       },
        "msgtype":"voice"
    }
    

    图片:

    {
       "touser":[
        "OPENID1",
        "OPENID2"
       ],
       "image":{
          "media_id":"BTgN0opcW3Y5zV_ZebbsD3NFKRWf6cb7OPswPi9Q83fOJHK2P67dzxn11Cp7THat"
       },
        "msgtype":"image"
    }
    

    视频:

    请注意,此处视频的media_id需通过POST请求到下述接口特别地得到: https://api.weixin.qq.com/cgi-bin/media/uploadvideo?access_token=ACCESS_TOKEN POST数据如下(此处media_id需通过素材管理->新增素材来得到):

    {
      "media_id": "rF4UdIMfYK3efUfyoddYRMU50zMiRmmt_l0kszupYh_SzrcW5Gaheq05p_lHuOTQ",
      "title": "TITLE",
      "description": "Description"
    }
    

    返回将为

    {
      "type":"video",
      "media_id":"IhdaAQXuvJtGzwwc0abfXnzeezfO0NgPK6AQYShD8RQYMTtfzbLdBIQkQziv2XJc",
      "created_at":1398848981
    }
    

    然后,POST下述数据(将media_id改为上一步中得到的media_id),即可进行发送

    {
       "touser":[
        "OPENID1",
        "OPENID2"
       ],
       "mpvideo":{
          "media_id":"123dsdajkasd231jhksad",
          "title":"TITLE",
          "description":"DESCRIPTION"
       },
        "msgtype":"mpvideo"
    }
    

    卡券:

    {
       "touser":[
        "OPENID1",
        "OPENID2"
       ],
        "wxcard": {"card_id":"123dsdajkasd231jhksad"}
        "msgtype":"wxcard"
    }
    
    参数是否必须说明
    touser 填写图文消息的接收者,一串OpenID列表,OpenID最少2个,最多10000个
    mpnews 用于设定即将发送的图文消息
    media_id 用于群发的图文消息的media_id
    msgtype 群发的消息类型,图文消息为mpnews,文本消息为text,语音为voice,音乐为music,图片为image,视频为video,卡券为wxcard
    title 消息的标题
    description 消息的描述
    thumb_media_id 视频缩略图的媒体ID
    send_ignore_reprint 图文消息被判定为转载时,是否继续群发。 1为继续群发(转载),0为停止群发。 该参数默认为0。

    返回说明

    返回数据示例(正确时的JSON返回结果):

    {
       "errcode":0,
       "errmsg":"send job submission success",
       "msg_id":34182, 
       "msg_data_id": 206227730
    }
    
    参数说明
    type 媒体文件类型,分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb),次数为news,即图文消息
    errcode 错误码
    errmsg 错误信息
    msg_id 消息发送任务的ID
    msg_data_id 消息的数据ID,,该字段只有在群发图文消息时,才会出现。可以用于在图文分析数据接口中,获取到对应的图文消息的数据,是图文分析数据接口中的msgid字段中的前半部分,详见图文分析数据接口中的msgid字段的介绍。

    请注意:在返回成功时,意味着群发任务提交成功,并不意味着此时群发已经结束,所以,仍有可能在后续的发送过程中出现异常情况导致用户未收到消息,如消息有时会进行审核、服务器不稳定等。此外,群发任务一般需要较长的时间才能全部发送完毕,请耐心等待。

    错误时微信会返回错误码等信息,请根据错误码查询错误信息

    一、在SendUtil中添加发送的字符串和发送接口两个方法

    package com.xu.wemall.components.weixin;
    
    import com.alibaba.fastjson.JSONArray;
    import com.alibaba.fastjson.JSONObject;
    import com.xu.wemall.commons.constants.URIConstant;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.web.client.RestTemplate;
    
    import java.util.List;
    
    /**
     * 功能:群发工具类
     */
    @Slf4j
    @Component
    public class SendUtil {
    
        @Autowired
        private RestTemplate restTemplate;
    
        @Autowired
        private AccessTokenUtil accessTokenUtil;
    
        private String createSendAllString(boolean isToAll, String tagId, String mediaId, String msgtype){
    
            JSONObject data = new JSONObject();
    
            JSONObject filter = new JSONObject();
            filter.put("is_to_all",isToAll);
            if(tagId != null){
                filter.put("tag_id",tagId);
            }
    
            JSONObject type = new JSONObject();
            if(mediaId != null){
                type.put("media_id",mediaId);
            }
            data.put("filter",filter);
    
            //图文消息
            if(msgtype.equalsIgnoreCase("mpnews")){
                data.put("mpnews",type);
                data.put("send_ignore_reprint",1);
            }else if(msgtype.equalsIgnoreCase("text")){
                data.put("text",type);   //文本
            }else if(msgtype.equalsIgnoreCase("voice")){
                data.put("voice",type);   //声音
            }else if(msgtype.equalsIgnoreCase("image")){
                data.put("image",type);   //图片
            }else if(msgtype.equalsIgnoreCase("mpvideo")){
                data.put("mpvideo",type);   //声音
            }else if(msgtype.equalsIgnoreCase("wxcard")) {
                data.put("wxcard", type);   //卡券
            }
    
            if(msgtype !=null){
                data.put("msgtype",msgtype);
            }
            return data.toJSONString();
    
        }
    
    
        private String createSendString(List<String> openIdList, String mediaId, String msgtype){
    
            JSONObject data = new JSONObject();
    
            JSONArray touser = new JSONArray();
            touser.addAll(openIdList);
            data.put("touser",touser);
    
            JSONObject type = new JSONObject();
            if(mediaId != null){
                type.put("media_id",mediaId);
            }
    
            //图文消息
            if(msgtype.equalsIgnoreCase("mpnews")){
                data.put("mpnews",type);
                data.put("send_ignore_reprint",1);
            }else if(msgtype.equalsIgnoreCase("text")){
                data.put("text",type);   //文本
            }else if(msgtype.equalsIgnoreCase("voice")){
                data.put("voice",type);   //声音
            }else if(msgtype.equalsIgnoreCase("image")){
                data.put("image",type);   //图片
            }else if(msgtype.equalsIgnoreCase("mpvideo")){
                data.put("mpvideo",type);   //声音
            }else if(msgtype.equalsIgnoreCase("wxcard")) {
                data.put("wxcard", type);   //卡券
            }
    
            if(msgtype !=null){
                data.put("msgtype",msgtype);
            }
            return data.toJSONString();
    
        }
    
        /**
         *根据标签进行群发
         */
        public String sendByTagId(boolean isToAll, String tagId, String mediaId, String msgtype) {
    
            String accessToken = accessTokenUtil.getAccessToken();
            if (accessToken != null) {
                log.info("URL{}", URIConstant.SEND_ALL_URL);
                String url = URIConstant.SEND_ALL_URL.replace("ACCESS_TOKEN", accessToken);
                log.info("SEND_ALL_URL:{}", url);
    
                //将菜单对象转换成JSON字符串
                String dataString = this.createSendAllString(isToAll, tagId, mediaId, msgtype);
                log.info("dataString:{}",dataString);
    
                //发起POST请求创建菜单
                String jsonObject = restTemplate.postForObject(url, dataString,String.class);
    
                return jsonObject;
            }
            return null;
        }
    
    
        /**
         *根据OpenID列表群发
         */
        public String sendByOpenId(List<String> touser, String mediaId, String msgtype) {
    
            String accessToken = accessTokenUtil.getAccessToken();
            if (accessToken != null) {
                log.info("URL{}", URIConstant.SEND_URL);
                String url = URIConstant.SEND_URL.replace("ACCESS_TOKEN", accessToken);
                log.info("SEND_URL:{}", url);
    
                //将菜单对象转换成JSON字符串
                String dataString = this.createSendString(touser, mediaId, msgtype);
                log.info("dataString:{}",dataString);
    
                //发起POST请求创建菜单
                String jsonObject = restTemplate.postForObject(url, dataString,String.class);
    
                return jsonObject;
            }
            return null;
        }
    
    
    }
    
    二、在SendController中添加swagger方法

    package com.xu.wemall.controller.weixin;
    
    import com.xu.wemall.components.weixin.SendUtil;
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiImplicitParam;
    import io.swagger.annotations.ApiImplicitParams;
    import io.swagger.annotations.ApiOperation;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.List;
    
    /**
     * 类名称: SendController
     * 类描述: 群发API
     */
    @Slf4j
    @RestController
    @Api(tags = "群发接口")
    @RequestMapping(value = "/send")
    public class SendController {
    
        @Autowired
        private SendUtil sendUtil;
    
        /**
         * 根据标签进行群发
         */
        @ApiOperation(value = "根据标签进行群发")
        @RequestMapping(value = "/sendByTagId", method = RequestMethod.POST)
        @ApiImplicitParams({
                @ApiImplicitParam(name="isToAll",value="用于设定是否向全部用户发送,值为true或false,选择true该消息群发给所有用户,选择false可根据tag_id发送给指定群组的用户", paramType="query",dataType="String"),
                @ApiImplicitParam(name="tagId",value="群发到的标签的tag_id,参见用户管理中用户分组接口,若is_to_all值为true,可不填写tag_id", paramType="query",dataType="String"),
                @ApiImplicitParam(name="mediaId",value="用于群发的消息的media_id"),
                @ApiImplicitParam(name="msgtype",value="群发的消息类型,图文消息为mpnews,文本消息为text,语音为voice,音乐为music,图片为image,视频为video,卡券为wxcard", paramType="query",dataType="Integer")
        })
        public Object sendByTagId(boolean isToAll, String tagId, String mediaId, String msgtype) {
    
            String tempString = sendUtil.sendByTagId(isToAll, tagId, mediaId,msgtype);
            return tempString;
    
        }
    
        /**
         * 根据OpenID列表群发
         */
        @ApiOperation(value = "根据标签进行群发")
        @RequestMapping(value = "/sendByOpenId", method = RequestMethod.POST)
        @ApiImplicitParams({
                @ApiImplicitParam(name="mediaId",value="用于群发的消息的media_id"),
                @ApiImplicitParam(name="msgtype",value="群发的消息类型,图文消息为mpnews,文本消息为text,语音为voice,音乐为music,图片为image,视频为video,卡券为wxcard", paramType="query",dataType="Integer")
        })
        public Object sendByOpenId(@RequestParam(value = "touser") List<String> touser, String mediaId, String msgtype) {
    
            String tempString = sendUtil.sendByOpenId(touser, mediaId,msgtype);
            return tempString;
    
        }
    
    
    }
    

     三,测试

    我们需要先通过获取关注公众号的用户获得至少两个openid,然后测试如下

    结果(泪奔中……)结果又是没有权限,因为我们用的是测试账号,测试账号现在已经没有群发功能权限了

    查询微信公众号开发文档中的【全局返回码说明】确认的确是没有这个接口的权限,哎

    如果您觉得此文有帮助,可以小小打赏一下,持续更新更有动力哟!

    谢谢观看,下回我们继续不见不散!

  • 相关阅读:
    nginx重启命令
    Java中Vector笔记
    JAVA中字符串比较equals()和equalsIgnoreCase()的区别
    HashMap和TreeMap的常用排序方法
    Logger用法
    HashMap和Hashtable的区别
    class.getDeclaredFields()与class.getFields()
    java中 文件压缩处理
    Java远程执行Shell命令
    python 学习笔记 redis操作
  • 原文地址:https://www.cnblogs.com/xulijun137/p/12222165.html
Copyright © 2011-2022 走看看