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.pswp.cn/diannao/36485.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/36485.shtml
英文地址,請注明出處:http://en.pswp.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…