微信公眾號開發之根據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,然后測試如下

結果(淚奔中……)結果又是沒有權限,因為我們用的是測試賬號,測試賬號現在已經沒有群發功能權限了

查詢微信公眾號開發文檔中的【全局返回碼說明】確認的確是沒有這個接口的權限,哎

如果您覺得此文有幫助,可以小小打賞一下,持續更新更有動力喲!

謝謝觀看,下回我們繼續不見不散!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM