微信公众号开发--群发图文消息,消息体包含图片地址

本文详细介绍了微信公众号群发功能的实现过程,包括图文消息的预览与正式群发,涉及图片上传、素材管理及接口调用等关键步骤。
                       

今天实现了一下微信公众号的消息群发功能,整个过程还是比较麻烦的,而且有些坑。记录一下。

微信官方文档–高级群发接口

 

在公众平台网站上,为订阅号提供了每天一条的群发权限,为服务号提供每月(自然月)4条的群发权限。而对于某些具备开发能力的公众号运营者,可以通过高级群发接口,实现更灵活的群发能力。

由于群发的次数非常有限。这里是以预览的方式发送给自己。

先看效果

效果

这里写图片描述

这里写图片描述

发送成功的返回结果

{"errcode":0,"errmsg":"preview success"}
  
  • 1

这个是预览,群发和预览差不多。

正式环境的效果(2016年9月21日补图)

这里写图片描述

思路

微信的正确思路

这里写图片描述

我的具体做法

这里写图片描述
这里写图片描述

一些代码

接口地址

    // 图文内的图片地址获取接口地址    private String uploadImageUrl = "https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN";    // 图文封面图片获取接口地址    private String postImageMediaUrl = "http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=image";    // 图文素材上传接口地址    private String postNewsUrl = "https://api.weixin.qq.com/cgi-bin/media/uploadnews?access_token=ACCESS_TOKEN";    // 群发接口地址    private String sendToAllUrl = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token=ACCESS_TOKEN";    // 预览接口地址    private String sendToPreviewUrl = "https://api.weixin.qq.com/cgi-bin/message/mass/preview?access_token=ACCESS_TOKEN";
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

关键代码

    @Test    public void testSendToAll() {        String accessToken = accessTokenUtil.getAccessToken();        // 获取详情的新闻列表        List<NewsArticle> articleList = new ArrayList<>();        // 1.原始的新闻列表        List<NewsArticle> newsList = getArticleList();        if(newsList.size()==0){            logger.info("----------今天没有发文章,任务结束----------");            return;        }        // 2.封装新闻详情,并得到新闻列表        for (NewsArticle article : newsList) {            NewsArticle articleNew = getArticleDetial(article.getUrl());            try {                // 下载封面                String localImage = imageService.saveImageToDisk(articleNew.getImagUrl(), imageSavePath);                // 上传封面                String jsonStr = HttpUtil.sendPost(postImageMediaUrl.replace("ACCESS_TOKEN", accessToken),                        new File(localImage));                JSONObject object = new JSONObject();                logger.info("----------上传封面返回结果:{}----------" + jsonStr);                try {                    object = new JSONObject(jsonStr);                    logger.info("----------得到的图片media_id:{}----------", object.get("media_id"));                    articleNew.setImageMediaId((String) object.get("media_id"));                } catch (Exception e) {                    logger.error("----------上传封面发生错误:{}", e.getMessage());                }            } catch (Exception e) {                logger.error("----------下载封面上传封面过程发生错误:{}", e.getMessage());            }            articleList.add(articleNew);        }        logger.info("----------最终图文列表:{}----------", articleList);        // 3.群发图文消息封装        List<GroupActicle> articles = new ArrayList<>();        for (NewsArticle NewsArticle : articleList) {            GroupActicle article = new GroupActicle();            article.setThumb_media_id(NewsArticle.getImageMediaId());            article.setAuthor(NewsArticle.getAuthor());            article.setTitle(NewsArticle.getTitle());            article.setContent_source_url(NewsArticle.getUrl());            article.setContent(NewsArticle.getContent());            article.setShow_cover_pic(0);            articles.add(article);        }        logger.info("----------图文消息:{}----------", articles);        Map<String, Object> jsonMap = new HashMap<>();        jsonMap.put("articles", articles);        logger.info("----------最终的图文消息json:{}----------", gson.toJson(jsonMap));        // 4.上传群发图文素材        String postNewsResult = HttpUtil.sendPost(postNewsUrl.replace("ACCESS_TOKEN", accessToken),                gson.toJson(jsonMap));        logger.info("----------上传图文素材的返回结果:{}----------", postNewsResult);        JSONObject object = new JSONObject();        String mediaId = "";        try {            object = new JSONObject(postNewsResult);            logger.info("----------得到的media_id:{}----------", object.get("media_id"));            mediaId = (String) object.get("media_id");        } catch (Exception e) {            logger.error("----------上传图文消息发生错误:{}----------", e.getMessage());        }        // 5.选择发送的用户并发送        if (StringUtils.isNotEmpty(mediaId)) {            Filter filter = new Filter(true);            Mpnews mpnews = new Mpnews(mediaId);            SendToAllNews sendAll = new SendToAllNews();            sendAll.setFilter(filter);            sendAll.setMpnews(mpnews);            sendAll.setMsgtype("mpnews");            // TODO 正式环境用sendToAll            SendToOpenIdPreview sendToPreview = new SendToOpenIdPreview("omSsruLEtGPgxjaJTyurGQwQNh8Q");            sendToPreview.setMpnews(mpnews);            sendToPreview.setMsgtype("mpnews");            logger.info("----------预览的json:{}----------", gson.toJson(sendToPreview));            // TODO 正式环境换成sendToAllUrl            String sentAllResult = HttpUtil.sendPost(sendToPreviewUrl.replace("ACCESS_TOKEN", accessToken),                    gson.toJson(sendToPreview));            logger.info("----------预览结果:{}----------", sentAllResult);        }    }
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86

注意

微信群发接口图文消息里面包含图片地址,群发之后图文消息内图片无法显示

官方解释

 

请注意,在图文消息的具体内容中,将过滤外部的图片链接,开发者可以通过下述接口上传图片得到URL,放到图文内容中使用。
  上传图文消息内的图片获取URL 请注意,本接口所上传的图片不占用公众号的素材库中图片数量的5000个的限制。图片仅支持jpg/png格式,大小必须在1MB以下。

所以图文消息中图片的src属性必须是腾讯的域名
也就是说必须是以
http://mmbiz.qpic.cn/
开头的,这个需要我们调用如下接口地址

    // 图文内的图片上传接口地址    private String uploadImageUrl = "https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN";
  
  • 1
  • 2

如果遇到如下错误

{"errcode":40007,"errmsg":"invalid media_id hint: [51TBDa0350sz63]"}
  
  • 1

上传图片的接口地址为下面的

    // 图文封面图片上传接口地址    private String postImageMediaUrl = "http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=image";
  
  • 1
  • 2

参考下面的文章

微信上传图文消息invalid media_id hint,thumb_media_id怎么获取

2017年7月23日更新

今天我的群发消息遇到问题了,好久没有整理了,好多人都说群发消息有问题,我今天把我的代码贴出来供大家参考,敏感信息我已经屏蔽,有些实体类也没给出,只是一个思路,仅供参考

package com.jrbac.service.wechat;import java.io.File;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.regex.Matcher;import java.util.regex.Pattern;import org.apache.commons.lang3.StringUtils;import org.json.JSONException;import org.json.JSONObject;import org.jsoup.Jsoup;import org.jsoup.nodes.Document;import org.jsoup.nodes.Element;import org.jsoup.select.Elements;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import com.google.gson.Gson;import com.google.gson.GsonBuilder;import com.jrbac.dao.MessagePushDao;import com.jrbac.model.wechat.message.GroupSendMessage;import com.jrbac.model.wechat.messsend.CdptsArticle;import com.jrbac.model.wechat.messsend.SendToAllNews;import com.jrbac.model.wechat.messsend.SendToOpenIdPreview;import com.jrbac.util.HttpUtil;import com.jrbac.util.ImageUtil;import com.jrbac.util.PropertiesUtil;import com.jrbac.util.wechat.AccessTokenUtil;@Servicepublic class SendToAllService {    // 获取accessToken的    @Autowired    private AccessTokenUtil accessTokenUtil;    // 读取配置文件的    @Autowired    private PropertiesUtil prop;    // 将图片下载到本地的    @Autowired    private WechatImageDownloadService imageService;    // 已群发的消息    @Autowired    private MessagePushDao messagePush;    private final Logger logger = LoggerFactory.getLogger(this.getClass());    private final Gson gson = new GsonBuilder().disableHtmlEscaping().create();    // 图文内的图片上传接口地址    private String uploadImageUrl = "https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN";    // 图文封面图片上传接口地址    private String postImageMediaUrl = "http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=image";    // 图文素材上传接口地址    private String postNewsUrl = "https://api.weixin.qq.com/cgi-bin/media/uploadnews?access_token=ACCESS_TOKEN";    // 群发接口地址    private String sendToAllUrl = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token=ACCESS_TOKEN";    // 群发预览接口地址    private String sendToPreviewUrl = "https://api.weixin.qq.com/cgi-bin/message/mass/preview?access_token=ACCESS_TOKEN";    // 照片下载路径    private String imageSavePath = "/usr/tmp/images/";    public void doSend() {        List<CdptsArticle> toSendNewsList = new ArrayList<>();        // 1.获取新闻列表        toSendNewsList = getArticleListFromCdpts();        // 再去获取一次,有时候第一次获取不到,不知道为什么        if (toSendNewsList.size() == 0) {            toSendNewsList = getArticleListFromCdpts();        }        // 2.移除已发送的新闻        toSendNewsList = removeAlreadySentArticle(toSendNewsList);        if (toSendNewsList.size() == 0) {            logger.info("----------没有文章需要群发----------");            return;        }        // 最多群发8条消息        if (toSendNewsList.size() > 8) {            toSendNewsList = toSendNewsList.subList(0, 8);        }        logger.info("----------群发的消息----------");        for (CdptsArticle article : toSendNewsList) {            logger.info("----------{}----------", article.getTitle());        }        // 3.上传并设置封面图片        toSendNewsList = setCoverImage(toSendNewsList);        // 4.群发图文消息json封装        String groupSendMessageJsonStr = getGroupSendMessageJsonStr(toSendNewsList);        // 5.上传群发图文消息        String mediaId = uploadGroupSendMessage(groupSendMessageJsonStr);        // 5.群发        if (StringUtils.isNotEmpty(mediaId)) {            String mode = prop.get("active");            if (StringUtils.isNotBlank(mode) && mode.equals("dev")) {                logger.info("测试环境,预览");                String openId = "你的测试openid";                sendToPreview(toSendNewsList, openId, mediaId);            } else {                logger.info("正式环境,群发");                sendToAll(toSendNewsList, mediaId);            }        }    }    public void sendToPreview(List<CdptsArticle> toSendNewsList, String openId, String mediaId) {        String accessToken = accessTokenUtil.getAccessToken();        SendToOpenIdPreview sendToPreview = new SendToOpenIdPreview(openId, mediaId);        String sendToPreviewJsonStr = gson.toJson(sendToPreview);        logger.info("----------预览的的json:{}----------", sendToPreviewJsonStr);        String sentToPreviewResult = HttpUtil.sendPost(sendToPreviewUrl.replace("ACCESS_TOKEN", accessToken),                sendToPreviewJsonStr);        logger.info("----------预览发送结果:{}----------", sentToPreviewResult);        checkSendResult(toSendNewsList, sentToPreviewResult);    }    public void sendToAll(List<CdptsArticle> toSendNewsList, String mediaId) {        String accessToken = accessTokenUtil.getAccessToken();        SendToAllNews sendToAll = new SendToAllNews(mediaId);        String sendToAllJsonStr = gson.toJson(sendToAll);        logger.info("----------群发的json数据:{}----------", sendToAllJsonStr);        String sentToAllResult = HttpUtil.sendPost(sendToAllUrl.replace("ACCESS_TOKEN", accessToken), sendToAllJsonStr);        logger.info("----------群发结果:{}----------", sentToAllResult);        checkSendResult(toSendNewsList, sentToAllResult);    }    /**     * 查看消息群发结果,并保存群发数据     *      * @param toSendNewsList     * @param sentToAllResult     */    private void checkSendResult(List<CdptsArticle> toSendNewsList, String sentToAllResult) {        try {            JSONObject object = new JSONObject(sentToAllResult);            int errorCode = (Integer) object.get("errcode");            if (errorCode == 0) {                for (CdptsArticle articleSend : toSendNewsList) {                    messagePush.addArticleToPushed(articleSend);                }            } else {                logger.error("---------群发发生了异常{},---------", sentToAllResult);            }        } catch (JSONException e) {            logger.error("---------群发结果json解析异常:{}\n----------jsonStr:{}---------", e.getMessage(), sentToAllResult);        }    }    private String uploadGroupSendMessage(String groupSendMessageJsonStr) {        String accessToken = accessTokenUtil.getAccessToken();        String postNewsResult = HttpUtil.sendPost(postNewsUrl.replace("ACCESS_TOKEN", accessToken),                groupSendMessageJsonStr);        logger.info("----------上传群发图文消息的返回结果:{}----------", postNewsResult);        String mediaId = "";        try {            JSONObject object = new JSONObject(postNewsResult);            mediaId = (String) object.get("media_id");        } catch (JSONException e) {            logger.error("上传群发图文消息发生错误{}", postNewsResult);        }        return mediaId;    }    private String getGroupSendMessageJsonStr(List<CdptsArticle> toSendNewsList) {        List<GroupSendMessage> groupSendMessageList = new ArrayList<>();        for (CdptsArticle cdptsArticle : toSendNewsList) {            GroupSendMessage groupSendMessage = new GroupSendMessage();            groupSendMessage.setThumb_media_id(cdptsArticle.getImageMediaId());            groupSendMessage.setAuthor(cdptsArticle.getAuthor());            groupSendMessage.setTitle(cdptsArticle.getTitle());            groupSendMessage.setContent_source_url(cdptsArticle.getUrl());            groupSendMessage.setContent(cdptsArticle.getContent());            groupSendMessage.setShow_cover_pic(0);            groupSendMessageList.add(groupSendMessage);        }        logger.info("----------最终封装的图文消息列表:{}----------", groupSendMessageList);        Map<String, Object> jsonMap = new HashMap<>();        jsonMap.put("articles", groupSendMessageList);        String groupSendMessageJsonStr = gson.toJson(jsonMap);        logger.info("----------最终要发送的图文消息json数据:{}----------", groupSendMessageJsonStr);        return groupSendMessageJsonStr;    }    /**     * 设置图文消息的封面图片     *      * @param newsList     * @return     */    private List<CdptsArticle> setCoverImage(List<CdptsArticle> newsList) {        String accessToken = accessTokenUtil.getAccessToken();        // 3.将待发送的新闻填充        List<CdptsArticle> detialArticleList = new ArrayList<>();        // 4.封装新闻详情,并得到新闻列表        for (CdptsArticle article : newsList) {            CdptsArticle articleWithDetial = getArticleDetialAndReplaceImage(article.getUrl());            try {                // 下载封面图片到本地                String localImage = imageService.saveImageToDisk(articleWithDetial.getImageUrl(), imageSavePath);                ImageUtil.thumbImage(localImage);                // 上传封面到微信                String jsonStr = HttpUtil.sendPost(postImageMediaUrl.replace("ACCESS_TOKEN", accessToken),                        new File(localImage));                logger.info("----------上传封面图片返回结果:{}----------" + jsonStr);                try {                    JSONObject object = new JSONObject(jsonStr);                    logger.info("----------得到的封面图片media_id:{}----------", object.get("media_id"));                    articleWithDetial.setImageMediaId((String) object.get("media_id"));                } catch (Exception e) {                    logger.error("----------上传封面发生错误:{}", e.getMessage());                }            } catch (Exception e) {                logger.error("----------下载封面,上传封面到微信过程发生错误:{}", e.getMessage());            }            detialArticleList.add(articleWithDetial);        }        logger.info("----------最终群发图文列表:{}----------", detialArticleList);        return detialArticleList;    }    /**     * 从新闻列表中删除已发送的文章     *      * @return     */    public List<CdptsArticle> removeAlreadySentArticle(List<CdptsArticle> articleList) {        List<CdptsArticle> messagePushed = messagePush.queryMessagePushed();        // 已发送的        List<String> urlPushedList = new ArrayList<>();        for (CdptsArticle article : messagePushed) {            urlPushedList.add(article.getUrl());        }        // 删除已发送的        Iterator<CdptsArticle> iterator = articleList.iterator();        while (iterator.hasNext()) {            CdptsArticle article = iterator.next();            if (urlPushedList.contains(article.getUrl())) {                iterator.remove();            }        }        return articleList;    }    /**     * 官网获取新闻列表     *      * @return     */    public List<CdptsArticle> getArticleListFromCdpts() {        // 新闻列表地址        String url = prop.get("allNewsHome");        logger.info("----------获取群发消息列表地址:{}----------", url);        List<CdptsArticle> articleList = new ArrayList<>();        // 得到页面        String result = HttpUtil.sendGet(url);        Document doc = Jsoup.parse(result);        String weiSchoolPrefix = prop.get("weischool");        // 内容页面        Elements elements = doc.select("div.m_right");        for (Element element : elements) {            Elements contentElements = element.getElementsByTag("ul");            for (Element contents : contentElements) {                // System.out.println("内容:");                Elements liContent = contents.getElementsByTag("li");                for (Element content : liContent) {                    CdptsArticle article = new CdptsArticle();                    // System.out.println(content);                    String time = content.getElementsByTag("span").first().text();                    // System.out.println(content.getElementsByTag("span").first().text());                    article.setTime(time);                    String title = content.getElementsByTag("a").first().text();                    article.setTitle(title);                    String originalUrl = content.select("a[href]").attr("href");                    article.setUrl(weiSchoolPrefix + originalUrl);                    articleList.add(article);                }            }        }        logger.info("----------获取到的新闻列表:{}----------", articleList);        return articleList;    }    // 图片校验    private static boolean isImage(String imageSrc) {        String reg = ".+(.JPEG|.jpeg|.JPG|.jpg|.GIF|.gif|.BMP|.bmp|.PNG|.png)$";        Pattern pattern = Pattern.compile(reg);        Matcher matcher = pattern.matcher(imageSrc.toLowerCase());        return (matcher.find());    }    /**     * 获取新闻详情并替换图片为微信的     *      * @param articleUrl     * @return     */    private CdptsArticle getArticleDetialAndReplaceImage(String articleUrl) {        String accessToken = accessTokenUtil.getAccessToken();        CdptsArticle article = new CdptsArticle();        article.setUrl(articleUrl);        // 具体页面        String remoteUrl = prop.get("remoteDomain") + "/Article/Index/" + articleUrl.split("/Article/Index/")[1];        logger.info("----------获取页面详情url:{}----------", remoteUrl);        // 得到页面        String result = HttpUtil.sendGet(remoteUrl);        Document doc = Jsoup.parse(result);        // 内容页面        Elements elements = doc.select("div.m_right");        for (Element element : elements) {            // System.out.println("原始内容:\n" + element);            // 作者信息            Element pageInfo = element.select("p.D_infor").remove(0);            // 标题            Element titleInfo = element.select("h1.D_title").remove(0);            article.setTitle(titleInfo.text());            String page = pageInfo.toString();            // System.out.println("作者相关信息:\n" + page);            // 所在板块            String module = element.getElementsByTag("h2").first().select("a[href]").text();            // 页面内容            String content = element.select("div.r_cont").html();            // 替换所有的图片路径            Elements images = element.select("div.r_cont").select("img");            for (Element image : images) {                String imageUrl = image.attr("src");                if(!isImage(imageUrl)){// 不是图片格式,直接删掉                    // image.attr("src", prop.get("localhost") + "/assets/image/school/bg.jpg");                    image.remove();                    continue;                }else{                    if (imageUrl.startsWith("http://")) {                        continue;                    } else if (imageUrl.startsWith("/Upload")) {                        image.attr("src", prop.get("remoteDomain") + image.attr("src"));                    } else {                        image.attr("src", prop.get("localhost") + "/assets/image/school/bg.jpg");                    }                }                // if (!image.attr("src").startsWith("http://")) {                // image.attr("src", prop.get("remoteDomain") +                // image.attr("src"));                // }            }            content = element.select("div.r_cont").html();            // 作者相关            // 作者相关            Elements info = element.getElementsByTag("p").first().getElementsByTag("span");            article.setTime(info.get(0).text().replace("发表时间: ", ""));            article.setAuthor(info.get(1).text().replace("发布人:", ""));            article.setCount(info.get(2).text().replace("点击率:", ""));            article.setModule(module);            // System.out.println("[所在板块]\t" + module);            String contents = content.replace(page, "").replace(titleInfo.toString(), "");            // System.out.println("[页面内容]\t" + contents);            Document docImage = Jsoup.parse(contents);            Elements elementImage = docImage.select("img");            if (elementImage.size() == 0) {                article.setImageUrl(prop.get("localhost") + "/assets/image/school/bg.jpg");            } else {                article.setImageUrl(elementImage.get(0).attr("src"));            }            for (Element imageElement : elementImage) {                try {                    // 下载文件                    logger.info("----------下载页面中的图片src:{}----------", imageElement.attr("src"));                    String imageRealPath = imageService.saveImageToDisk(imageElement.attr("src"), imageSavePath);                    logger.info("----------图片保存路径:{}----------", imageRealPath);                    // 压缩处理                    ImageUtil.thumbImage(imageRealPath);                    // 上传到微信                    logger.info("----------上传到微信----------");                    String responseStr = HttpUtil.sendPost(uploadImageUrl.replace("ACCESS_TOKEN", accessToken),                            new File(imageRealPath));                    logger.info("----------上传结果:{}----------", responseStr);                    JSONObject object = new JSONObject();                    try {                        object = new JSONObject(responseStr);                        logger.info("----------得到上传图片的url:{}----------", object.get("url"));                        imageElement.attr("src", (String) object.get("url"));                    } catch (Exception e) {                        logger.error("----------上传图片到微信发生了错误:{}" + responseStr);                    }                } catch (Exception e) {                    logger.error("----------下载图片并上传到微信过程发生了错误:{}" + e.getMessage());                }            }            String contentFinal = docImage.select("div.D_cont").html();            article.setContent(contentFinal);        }        logger.info("----------获取页面详情返回结果:{}----------", article);        return article;    }}
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400

参考文献

 

微信开发文档–群发接口

   

微信上传图文消息invalid media_id hint,thumb_media_id怎么获取

           
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值