java发送图文到公众号

这两天接到了一个新任务,通过后台管理编写文章,发送到官网的同时,推送一份到公众号,研究了一下微信的文档,发现不难,只需要有几个注意点就可以了。
注意:

  1. 微信公众号只能访问微信自己上传的图片链接,外网链接会自动屏蔽。
  2. 微信公众号自己上传的图片返回的链接,只能用于腾讯域内访问,外网是访问不了的。
  3. 微信公众号分为服务号和订阅号,服务号每个月只能群发4次文章,订阅号是每天可以发1次,但是服务号和订阅号是可以1次发1~8篇文章的哦,这对于咱们测试来说就很麻烦,所以我们可以申请一个测试账号,用于测试开发,测试账号的权限也是最大的,很多API都可以调用,我把申请的流程放到下面。

注意这几点就可以了,好了接下来我们进入到正文!

这是微信公众号开发文档链接:微信公众号开发文档链接 ,可以结合文档看,毕竟他老是在更新。

一、申请微信公众号测试账号

登录公众号以后,按照这个步骤就可以申请测试公众号了,没有公众号的先去自己申请一个,这里就不多赘述了(建议个人开发的话用订阅号哈,服务号申请比较麻烦)。
在这里插入图片描述

二、开发准备工作

一、项目所需要的依赖

			<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.16</version></dependency><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.43</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>

因为我是用redis做了微信access_token的缓存,所以用到了redis,看各位自己的需求,直接存静态对象里也行。

二、涉及到的微信接口

public class WeChatConstant {public static final String APP_ID = "";public static final String SECRET = "";public static final String ACCESS_TOKEN = "access-_token";//获取tokenpublic static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";//上传图文图片永久素材public static final String UPLOAD_FILE_IMAGE_URL = "https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=%s";public static final String UPLOAD_FILE_OTHER_TYPE_URL = "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=%s&type=%s";//建立草稿箱public static final String CREATE_DRAFT_URL = "https://api.weixin.qq.com/cgi-bin/draft/add?access_token=%s";//发布草稿箱public static final String PUSH_DRAFT_URL = "https://api.weixin.qq.com/cgi-bin/freepublish/submit?access_token=%s";//群发草稿箱消息public static final String SEND_ALL_DRAFT_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token=%s";
}

三、实现代码

上传公众号,分为几个步骤,上图片。
在这里插入图片描述
根据图片可以看到,所有的接口都是需要accessToken的,所以我们先获取accessToken。

一、 获取AccessToken

@Resourceprivate RedisCache redisCache;public String getAccessToken() {String url = String.format(WeChatConstant.ACCESS_TOKEN_URL, WeChatConstant.APP_ID, WeChatConstant.SECRET);String result = HttpUtil.get(url);log.info("获取AccessToken,返回结果:{}",result);JSONObject jsonObject = JSON.parseObject(result);if (!jsonObject.containsKey("access_token")) {throw new RuntimeException(result);}String access_token = jsonObject.getString("access_token");String expires_in = jsonObject.getString("expires_in");redisCache.setCacheObject(WeChatConstant.ACCESS_TOKEN,access_token,Integer.parseInt(expires_in), TimeUnit.SECONDS);return access_token;}

二、上传文本内的图片素材

这个是用来上传富文本内图片到微信的接口,是不占用微信公众号素材库的,但是图片需要小于1M,详细介绍可以看官网文档。

   @Overridepublic String uploadImageTextWeChatImage(String path) {String accessToken = redisCache.getCacheObject(WeChatConstant.ACCESS_TOKEN);if(StrUtil.isBlank(accessToken)) {accessToken = getAccessToken();}String upload = String.format(WeChatConstant.UPLOAD_FILE_IMAGE_URL, accessToken);Map<String, Object> map = new HashMap<>(1);File file = new File(path);map.put("media",file);String result = HttpUtil.post(upload, map);log.info("上传微信图文内永久素材,返回结果:{}",result);JSONObject jsonObject = JSON.parseObject(result);String url = jsonObject.getString("url");if(StrUtil.isBlank(url)) {throw new ServiceException("上传富文本内图片到微信错误,错误原因:" + jsonObject.toString());}return url;}

三、上传其他类型文件

这个是用来上传文章标题图片的,也可以上传其他类型的文件,比如视频等,需要按照官方文档类型上传。

   @Overridepublic String uploadOtherTypeWeChat(String path, String type) {String accessToken = redisCache.getCacheObject(WeChatConstant.ACCESS_TOKEN);if(StrUtil.isBlank(accessToken)) {accessToken = getAccessToken();}String upload = String.format(WeChatConstant.UPLOAD_FILE_OTHER_TYPE_URL, accessToken,type);Map<String, Object> map = new HashMap<>(1);File file = new File(path);map.put("media",file);String result = HttpUtil.post(upload, map);log.info("上传其他类型永久素材,返回结果:{}",result);JSONObject jsonObject = JSON.parseObject(result);String mediaId = jsonObject.getString("media_id");if(StrUtil.isBlank(mediaId)) {throw new ServiceException("上传标题图片到微信错误,错误原因:" + jsonObject.toString());}return mediaId;}

四、上传文章到草稿箱

草稿箱实体类

   @Data@Accessors(chain = true)public class DraftVo implements Serializable {private String title;private String author;private String digest;private String content;private String content_source_url;private String thumb_media_id;}
   @Overridepublic String uploadDraftWeChat(DraftVo vo) {String accessToken = redisCache.getCacheObject(WeChatConstant.ACCESS_TOKEN);if(StrUtil.isBlank(accessToken)) {accessToken = getAccessToken();}String upload = String.format(WeChatConstant.CREATE_DRAFT_URL, accessToken);Map<String, Object> map = new HashMap<>(1);map.put("articles", Arrays.asList(vo));String json = JSON.toJSONString(map);String result = HttpUtil.post(upload, json);log.info("上传文章到草稿箱,返回结果:{}",result);JSONObject jsonObject = JSON.parseObject(result);String mediaId = jsonObject.getString("media_id");if(StrUtil.isBlank(mediaId)) {throw new ServiceException("上传文章到微信草稿箱错误,错误原因:" + jsonObject.toString());}return mediaId;}

五、群发草稿箱的内容到公众号

@Overridepublic String sendAllDraftWeChat(String mediaId) {String accessToken = redisCache.getCacheObject(WeChatConstant.ACCESS_TOKEN);if(StrUtil.isBlank(accessToken)) {accessToken = getAccessToken();}String upload = String.format(WeChatConstant.SEND_ALL_DRAFT_URL, accessToken);Map<String, Object> map = new HashMap<>(4);Map<String, Object> filterMap = new HashMap<>(2);filterMap.put("is_to_all",true);filterMap.put("tag_id","");map.put("filter",filterMap);Map<String, Object> mpnews = new HashMap<>(1);mpnews.put("media_id",mediaId);map.put("mpnews",mpnews);map.put("msgtype","mpnews");map.put("send_ignore_reprint","1");String json = JSON.toJSONString(map);String result = HttpUtil.post(upload, json);log.info("群发草稿箱的文章到公众号,返回结果:{}",result);JSONObject jsonObject = JSON.parseObject(result);Integer errcode = Integer.parseInt(jsonObject.getString("errcode"));if (errcode != 0) {throw new ServiceException("群发文章错误,错误原因:" + jsonObject.getString("errmsg"));}return jsonObject.getString("msg_id");}

六、Service层接口

public interface WeChatService {/*** 获取token*/public String getAccessToken();/*** 上传文本内的图片素材* @param path * @return*/public String uploadImageTextWeChatImage(String path);/*** 上传其他类型文件* @return */public String uploadOtherTypeWeChat(String path,String type);/*** 上传文章到草稿箱* @param vo* @return */public String uploadDraftWeChat(DraftVo vo);/*** 群发草稿箱的内容到公众号* @param mediaId* @return*/public String sendAllDraftWeChat(String mediaId);
}

好了到这里就已经可以发送文章到公众号了,有什么问题可以在下面给我留言,我看到了会一一回复的哦~,如果对你有用的话请大家动一下发财的小手,收藏、关注、点赞一下哈。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/36485.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32单片机实现串口IAP升级

一.概述 1.要实现串口IAP升级&#xff0c;首先要编写一个bootloader程序&#xff0c;然后再写支持IAP的app程序&#xff1b; 2.keil下bootloader的程序rom和ram设置 3.app程序要用bin文件 注&#xff1a;本文以STM32H743举例&#xff0c;其他stm32单片机IAP升级原理类似。 …

达梦数据库的系统视图v$database

达梦数据库的系统视图v$database 基础信息 OS版本&#xff1a; Red Hat Enterprise Linux Server release 7.9 (Maipo) DB版本&#xff1a; DM Database Server 64 V8 DB Version: 0x7000c 03134284132-20240115-215128-20081在达梦数据库&#xff08;Dameng Database&#xf…

Java——Lambda表达式

1. 背景 Lambda表达式是JavaSE 8中一个重要的新特性。Lambda表达式允许你通过表达式来代替功能接口。 Lambda表达式就和方法一样&#xff0c;它提供了一个正常的参数列表和一个使用这些参数的主体(body&#xff0c;可以是一个表达式或一个代码块)。 Lambda 表达式&#xff08;…

C# YoloV8 模型效果验证工具(OnnxRuntime+ByteTrack推理)

C# YoloV8 模型效果验证工具(OnnxRuntimeByteTrack推理) 目录 效果 项目 代码 下载 效果 模型效果验证工具 项目 代码 using ByteTrack; using OpenCvSharp; using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using Sys…

远程服务器配置(堡垒机samba/ssh等)

分配了新的服务器后&#xff0c;要下载代码首先要配置ssh。有以下两种方式&#xff1a; 拷贝原本服务器的在本地的重新生成ssh&#xff0c;再跟服务器密钥配对&#xff08;如未备份.gitconfig&#xff0c;还需重新配置git账号邮箱。&#xff09; ssh配置 如果是拷贝过来的.ss…

【win11】Mouse without Borders安装问题以管理员权限安装msi文件

【win11】Mouse without Borders安装问题&以管理员权限安装msi文件 Mouse without Borders安装问题解决&以管理员权限安装msi文件启动Windows Installer服务以管理员权限安装msi文件 参考文献 Mouse without Borders安装问题 在win11下我双击MouseWithoutBorders2.2.1…

nodejs使用mysql模块自动断开

背景 第二天早上来的时候&#xff0c;发现接口返回异常Cannot enqueue Query after fatal error 从日志看上去&#xff0c;接口是正常运行的&#xff0c;搜索一下之后发现是数据库的问题&#xff0c;连接断开了 原因 MySQL中有一个名叫wait_timeout的变量&#xff0c;表示操…

由监官要求下架docker hub镜像导致无法正常拉取镜像

问题&#xff1a;下载docker镜像超时 error pulling image configuration: download failed after attempts6: dial tcp 202.160.128.205:443: i/o timeout解决办法&#xff1a;配置daemon.json [rootbogon aihuidi]# cat /etc/docker/daemon.json {"registry-mirrors&qu…

java springboot过滤器

在Spring Boot应用中添加自定义过滤器&#xff0c;可以通过实现Filter接口或继承OncePerRequestFilter类来创建过滤器&#xff0c;并使用FilterRegistrationBean将其注册到Spring容器中。 以下是一个简单的示例&#xff1a; 1. 创建过滤器类 首先&#xff0c;创建一个实现Fil…

C++基础语法:类构造函数

前言 "打牢基础,万事不愁" .C的基础语法的学习 引入 类是实现面向对象思想的主要方法.前面提到:类是函数的变种,类可以通过调用静态方法或者成员函数来实现逻辑.多数情况下使用成员函数.构造函数是生成类对象成员的必须条件,对此做一些构造函数的归纳 构造函数的目…

【日志消息类的编写】

日志消息类编写 由于上篇的代码比较简单&#xff0c;今天就多写两段代码顺便把日志消息类编写完成。 这个类的实现就是&#xff1a;什么时间&#xff0c;哪个线程&#xff0c;哪个文件的哪一行&#xff0c;发生了什么等级的日志&#xff0c;日志机器名字是什么&#xff0c;日…

20240628 每日AI必读资讯

&#x1f4da; Hugging Face 推出新版开源大模型排行榜&#xff0c;中国模型 Qwen-72B 夺冠 - 阿里Qwen-2-72B指令微调版本问鼎全球开源大模型排行榜榜首 - Llama-3-70B 微调版本排名第二&#xff0c;而 Mixtral-8x22B 微调版本位居第四。 - 另外&#xff0c;微软的 Phi-3-M…

三种分布式锁实现方式

目录 1、数据库自增 2、Redis自增 3、Zookeeper 4、其他 4.1、雪花算法 4.2、Tinyid 4.3、Leaf 4.4、数据库号段 1、数据库自增 利用数据库表的自增特性&#xff0c;或主键唯一性&#xff0c;实现分布式ID REPLACE INTO id_table (stub) values (’a‘) ; SELECT LA…

社交App广告优化新篇章:Xinstall引领用户体验升级,助力买量效果提升

随着移动互联网的快速发展&#xff0c;社交App已经成为人们生活中不可或缺的一部分。然而&#xff0c;在竞争激烈的市场环境下&#xff0c;如何有效地进行广告投放&#xff0c;吸引并留住用户&#xff0c;成为了每个社交App运营者面临的重大挑战。今天&#xff0c;我们就来谈谈…

自费5K,测评安德迈、小米、希喂三款宠物空气净化器谁才是高性价比之王

最近&#xff0c;家里的猫咪掉毛严重&#xff0c;简直成了一个活生生的蒲公英&#xff0c;家中、空气中各处都弥漫着猫浮毛甚至所有衣物都覆盖着一层厚厚的猫毛。令人难以置信的是&#xff0c;有时我甚至在抠出的眼屎中都能发现夹杂着几根猫毛。真的超级困扰了。但其实最空气中…

Packer-Fuzzer一款好用的前端高效安全扫描工具

★★免责声明★★ 文章中涉及的程序(方法)可能带有攻击性&#xff0c;仅供安全研究与学习之用&#xff0c;读者将信息做其他用途&#xff0c;由Ta承担全部法律及连带责任&#xff0c;文章作者不承担任何法律及连带责任。 1、Packer Fuzzer介绍 Packer Fuzzer是一款针对Webpack…

4.if 条件判断

1.if-else语句 if #判断条件 :pass else:pass2.if - elif- else if #判断条件 :pass elif #判断条件:pass else:pass3.if语句可以嵌套 if #判断条件 :passif #判断条件 :pass 4.逻辑运算符 and 两个都为真,才是真 or 一个为真 即是真 not 取反 and从左到右,所有值为真,返回…

麒麟系统安装MySQL

搞了一整天&#xff0c;终于搞定了&#xff0c;记录一下。 一、背景 项目的原因&#xff0c;基于JeecgBoot开发的系统需要国产化支持&#xff0c;这就需要在电脑上安装MySQL等支撑软件。 国产化项目的操作系统多是麒麟系统&#xff0c;我的系统如下&#xff1a; arm64架构。…

C#快速开发OPCUA服务器

为方便演示&#xff0c;此时创建一个控制台应用程序。第三方dll(C编写的库opcsrv.dll&#xff0c;他人实现)。 拷贝dll到运行目录下&#xff1a; 拷贝二次封装后的文件到项目目录下&#xff1a; 第一步&#xff1a;创建OpcUa服务器 //第一步&#xff1a;创建OpcUa服务器 OPCSr…

java.util.Optional类介绍

java.util.Optional 是 Java 8 引入的一个容器类,用于表示可能包含或不包含非空值的对象。它的设计初衷是为了减少程序中的空指针异常(NullPointerException),并使代码更加简洁和易读。 Optional 类的介绍 1. 特点 避免显式的 null 检查:使用 Optional 可以避免显式的 n…