微信開發-素材/消息管理接口
本文是 微信公眾號開發者模式介紹及接入 的後續,如沒看過前文的話,可能看本文會有些懵逼。本文主要介紹微信公眾平臺的素材、消息管理接口的開發。由於個人的訂閱號是沒有大多數接口的權限的,所以我們需要使用微信官方提供的測試號來進行開發。測試號的申請可參考下文:
- 使用微信測試賬號對網頁進行授權
圖文消息
本小節我們來開發回復圖文消息的功能,官方文檔地址如下:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140543
回復圖文消息所需傳遞的參數如下:
註:多圖文消息不會顯示Description參數的信息
官方的圖文消息示例數據結構如下:
<xml> <ToUserName> <![CDATA[toUser]]> </ToUserName> <FromUserName> <![CDATA[fromUser]]> </FromUserName> <CreateTime>12345678</CreateTime> <MsgType> <![CDATA[news]]> </MsgType> <ArticleCount>2</ArticleCount> <Articles> <item> <Title> <![CDATA[title1]]> </Title> <Description> <![CDATA[description1]]> </Description> <PicUrl> <![CDATA[picurl]]> </PicUrl> <Url> <![CDATA[url]]> </Url> </item> <item> <Title> <![CDATA[title]]> </Title> <Description> <![CDATA[description]]> </Description> <PicUrl> <![CDATA[picurl]]> </PicUrl> <Url> <![CDATA[url]]> </Url> </item> </Articles> </xml>
圖文消息都在Articles標簽內,而每個item標簽都包含一條圖文消息,有多少個item標簽就代表有多少條圖文消息。
在開發回復圖文消息的時候,我們需要使用到一張圖片來作為圖文消息的封面,找一個圖片文件放在工程的resources/static目錄下即可,並確保能夠在外網上訪問:
看完了官方的示例數據及文檔,那麽我們就來開發一下圖文消息的回復吧。首先是創建一個基類,封裝通用的字段,代碼如下:
package org.zero01.weixin.mqdemo.vo; import com.thoughtworks.xstream.annotations.XStreamAlias; import lombok.Getter; import lombok.Setter; /** * @program: mq-demo * @description: 圖文消息基類 * @author: 01 * @create: 2018-07-02 20:24 **/ @Getter @Setter public class BaseMassage { /** * 接收方賬號 */ @XStreamAlias("ToUserName") private String toUserName; /** * 發送方賬號 */ @XStreamAlias("FromUserName") private String fromUserName; /** * 消息創建時間 (整型) */ @XStreamAlias("CreateTime") private long createTime; /** * 消息類型 */ @XStreamAlias("MsgType") private String msgType; }
然後是具體的封裝每條圖文消息字段的對象,代碼如下:
package org.zero01.weixin.mqdemo.vo;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Getter;
import lombok.Setter;
/**
* @program: mq-demo
* @description: 圖文消息對象
* @author: 01
* @create: 2018-07-02 20:19
**/
@Getter
@Setter
public class NewsItem{
@XStreamAlias("Title")
private String title;
@XStreamAlias("Description")
private String description;
@XStreamAlias("PicUrl")
private String picUrl;
@XStreamAlias("Url")
private String url;
}
接著是包含每條圖文消息的容器對象,代碼如下:
package org.zero01.weixin.mqdemo.vo;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
/**
* @program: mq-demo
* @description: 圖文消息容器對象
* @author: 01
* @create: 2018-07-02 20:29
**/
@Getter
@Setter
public class NewsMessage extends BaseMassage{
@XStreamAlias("ArticleCount")
private int articleCount;
@XStreamAlias("Articles")
private List<NewsItem> articles;
}
將圖文消息結構都封裝成一個個的類後,就是需要組裝圖文消息以及將組裝好的圖文消息轉換成xml格式的數據,發送給微信服務器了。所以我們需要在MessageUtil類中,新增如下兩個方法:
/**
* 圖文消息轉換為xml
*
* @param newsMessage
* @return
*/
public static String newsMessageToXml(NewsMessage newsMessage) {
XStream xStream = new XStream();
xStream.processAnnotations(new Class[]{NewsItem.class, NewsMessage.class});
xStream.alias("xml", newsMessage.getClass());
xStream.alias("item", NewsItem.class);
return xStream.toXML(newsMessage);
}
/**
* 組裝圖文消息
*
* @param toUserName
* @param fromUserName
* @return
*/
public static String initNewsMessage(String toUserName, String fromUserName) {
List<NewsItem> newsItemList = new ArrayList<>();
NewsMessage newsMessage = new NewsMessage();
NewsItem newsItem = new NewsItem();
newsItem.setTitle("圖文消息");
newsItem.setDescription("這是一個圖文消息");
newsItem.setPicUrl("http://zero.mynatapp.cc/code.jpg");
newsItem.setUrl("www.baidu.com");
newsItemList.add(newsItem);
newsMessage.setToUserName(fromUserName);
newsMessage.setFromUserName(toUserName);
newsMessage.setCreateTime(System.currentTimeMillis());
newsMessage.setMsgType(MessageTypeEnum.MSG_NEWS.getMsgType());
newsMessage.setArticles(newsItemList);
newsMessage.setArticleCount(newsItemList.size());
return newsMessageToXml(newsMessage);
}
最後修改WeChatMqController中的text方法,增加一條判斷,判斷當用戶輸入數字1時,則回復圖文消息。代碼如下:
@PostMapping("/common")
public String text(@RequestBody String xmlStr) {
// 將xml格式的數據,轉換為 AllMessage 對象
AllMessage allMessage = MessageUtil.xmlToAllMessage(xmlStr);
// 是否是文本消息類型
if (allMessage.getMsgType().equals(MessageTypeEnum.MSG_TEXT.getMsgType())) {
// 用戶輸入數字1時,回復圖文消息
if ("1".equals(allMessage.getContent())) {
return MessageUtil.initNewsMessage(allMessage.getToUserName(), allMessage.getFromUserName());
}
// 自動回復用戶所發送的文本消息
return MessageUtil.autoReply(allMessage, ContentEnum.CONTENT_PREFIX.getContent() + allMessage.getContent());
}
// 是否是事件推送類型
else if (allMessage.getMsgType().equals(MessageTypeEnum.MSG_EVENT.getMsgType())) {
// 是否為訂閱事件
if (EventType.EVENT_SUBSCRIBE.getEventType().equals(allMessage.getEvent())) {
// 自動回復歡迎語
return MessageUtil.autoReply(allMessage, ContentEnum.CONTENT_SUBSCRIBE.getContent());
}
} else {
// 暫不支持文本以外的消息回復
return MessageUtil.autoReply(allMessage, ContentEnum.CONTENT_NONSUPPORT.getContent());
}
return MessageUtil.autoReply(allMessage, ContentEnum.CONTENT_NONSUPPORT.getContent());
}
完成以上代碼的編寫後,啟動SpringBoot,打開微信公眾號,測試結果如下:
access_token的獲取
本小節我們來看看如何獲取access_token,官方文檔地址如下:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183
access_token是什麽?官方的定義如下:
access_token是公眾號的全局唯一接口調用憑據,公眾號調用各接口時都需使用access_token。開發者需要進行妥善保存。access_token的存儲至少要保留512個字符空間。access_token的有效期目前為2個小時,需定時刷新,重復獲取將導致上次獲取的access_token失效。
調用接口獲取access_token需要傳遞的參數說明如下:
獲取access_token成功後,接口所返回的參數說明如下:
從文檔中我們可以看到,調用接口獲取access_token時需要傳遞appid和secret,appid和secret可以在公眾號的基本配置頁面中獲取,如下:
然後我們還需要安裝提示,設置一下白名單的ip,即你機器的ip,不然是無法調用接口獲取access_token的,如下:
將appid、secret以及獲取access_token的接口url,配置到SpringBoot的配置文件中,如下:
wechat:
mpAppid: wx8ed1xxxxxx9513dd
mpAppSecret: 0c1b5b7ea5xxxxxxxxx14cb5b61258
accessTokenUrl: https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
在工程中新建一個config包,在該包下新建一個 WeXinConfig 配置類,用於加載配置文件中所配置的appid和secret:
package org.zero01.weixin.mqdemo.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @program: mq-demo
* @description: 微信公眾號配置類
* @author: 01
* @create: 2018-07-03 20:50
**/
@Data
@Configuration
@ConfigurationProperties(prefix = "wechat")
public class WeXinConfig {
private String mpAppid;
private String mpAppSecret;
private String accessTokenUrl;
}
因為我們需要序列化json數據以及發送http請求給微信服務器,所以需要使用到一些工具包,在maven的pom.xml文件中,加入如下依賴:
<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160810</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.5</version>
</dependency>
在util包下新建一個 WeiXinUtil 工具類,在該類中封裝get、post請求方法,以及獲取access_token的方法。代碼如下:
package org.zero01.weixin.mqdemo.util;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.zero01.weixin.mqdemo.config.WeXinConfig;
import org.zero01.weixin.mqdemo.vo.AccessToken;
import java.io.IOException;
/**
* @program: mq-demo
* @description:
* @author: 01
* @create: 2018-07-03 21:04
**/
@Component
public class WeiXinUtil {
private static WeXinConfig wxConfig;
public WeXinConfig getWeXinConfig() {
return wxConfig;
}
@Autowired
public void setWeXinConfig(WeXinConfig wxConfig) {
WeiXinUtil.wxConfig = wxConfig;
}
/**
* get請求
*
* @param url
* @return
*/
public static JSONObject doGet(String url) throws IOException {
CloseableHttpClient client = HttpClientBuilder.create().build();
HttpGet httpGet = new HttpGet(url);
HttpResponse response = client.execute(httpGet);
String result = EntityUtils.toString(response.getEntity(), "utf-8");
return new JSONObject(result);
}
/**
* post請求
*
* @param url
* @param outStr
* @return
*/
public static JSONObject doPost(String url, String outStr) throws IOException {
CloseableHttpClient client = HttpClientBuilder.create().build();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new StringEntity(outStr, "utf-8"));
HttpResponse response = client.execute(httpPost);
String result = EntityUtils.toString(response.getEntity(), "utf-8");
return new JSONObject(result);
}
/**
* 獲取access_token
*
* @return
* @throws IOException
*/
public static AccessToken getAccessToken() throws IOException {
AccessToken token = new AccessToken();
// 替換appid和secret
String url = wxConfig.getAccessTokenUrl()
.replace("APPID", wxConfig.getMpAppid())
.replace("APPSECRET", wxConfig.getMpAppSecret());
JSONObject jsonObject = doGet(url);
token.setToken(jsonObject.getString("access_token"));
token.setExpiresIn(jsonObject.getInt("expires_in"));
return token;
}
}
完成以上代碼的編寫後,新建一個測試類,測試一下是否能正常獲取到access_token。測試代碼如下:
package org.zero01.weixin.mqdemo.util;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.zero01.weixin.mqdemo.vo.AccessToken;
import java.io.IOException;
import static org.junit.Assert.*;
@RunWith(SpringRunner.class)
@SpringBootTest
public class WeiXinUtilTest {
@Test
public void getAccessToken() throws IOException {
AccessToken accessToken = WeiXinUtil.getAccessToken();
System.out.println("access_token: " + accessToken.getToken());
System.out.println("有效時間: " + accessToken.getExpiresIn());
}
}
運行以上測試用例後,控制臺輸出如下:
access_token: 11_AMxhxO9soXndEc6XI-0hG0CWQ_oVQjaiPol6P2eMDLrSYpIrbiNMjHEDFwoOiKwG-ckgwPTHCiWypzK_reZohT7H5UdEYUmdlU_qq-oGQefv9q9A4mEkFV5WyiEFK5q5SsvsLR5QIKcjf1BhLDEfAIAAST
有效時間: 7200
從測試結果中,可以看到,成功獲取到了access_token,並且這個access_token的有效期是7200秒,也就是兩個小時,和官方文檔描述的一致。
一般在實際的項目開發中,我們都會把這個access_token緩存起來,緩存到本地或者nosql數據庫中,然後每隔1.5個小時或2個小時的時候,就重新獲取一次access_token,刷新緩存。這樣做是為了避免在每個邏輯點都去重新獲取access_token,因為這樣會導致服務的不穩定,而且微信也規定了獲取access_token的接口每天只能調用2000次,如果每個邏輯點都去重新獲取access_token的話,不僅會導致服務不穩定,還容易把調用次數給花完。如下:
圖片消息回復
本小節我們來看看如何進行圖片消息的回復,官方文檔地址如下:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140543
回復圖片消息所需傳遞的參數如下:
官方的圖文消息示例數據結構如下:
<xml>
<ToUserName>
<![CDATA[toUser]]>
</ToUserName>
<FromUserName>
<![CDATA[fromUser]]>
</FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType>
<![CDATA[image]]>
</MsgType>
<Image>
<MediaId>
<![CDATA[media_id]]>
</MediaId>
</Image>
</xml>
從所需傳遞的參數列表中可以看到,回復圖片消息時需要傳遞一個MediaId,這是通過素材管理中的接口上傳多媒體文件,得到的id。所以在開發回復圖片消息的接口前,我們還需要開發一個上傳多媒體文件的接口,以此來獲得MediaId。關於素材管理接口的官方文檔地址如下:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1444738726
新增臨時素材接口調用說明如下:
上傳素材成功後,返回的參數如下:
有一點要說明的是,個人的訂閱號是沒有素材管理接口的權限的,所以我們需要將之前配置的appid和AppSecret配置為測試號的,不然接口會調用失敗,如果是已認證的服務號就可以直接使用。
由於需要上傳圖片素材才能發送圖片消息,所以首先需要在 WexinUtil 中,新增一個 upload 方法,用於上傳臨時圖片素材並返回素材的media_id。
但是在寫代碼前,需要先將上傳臨時素材的接口url地址配置到SpringBoot的配置文件中,如下:
wechat:
...
uploadUrl: https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE
然後在配置類裏加上這個配置的字段,如下:
...
public class WeXinConfig {
...
private String uploadUrl;
}
upload 方法代碼如下:
/**
* 上傳臨時素材
*
* @param filePath 需要上傳的文件所在路徑
* @param accessToken access_token
* @param type 素材類型
* @return media_id
* @throws IOException
*/
public static String upload(String filePath, String accessToken, String type, String key) throws IOException {
File file = new File(filePath);
if (!(file.exists() || file.isFile())) {
throw new IOException("文件不存在");
}
String url = wxConfig.getUploadUrl()
.replace("ACCESS_TOKEN", accessToken)
.replace("TYPE", type);
URL urlObj = new URL(url);
// 打開連接
HttpURLConnection connection = (HttpURLConnection) urlObj.openConnection();
// 設置屬性
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
// 設置頭信息
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Charset", "UTF-8");
// 設置邊界
String boundary = "----------" + System.currentTimeMillis();
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
StringBuilder sb = new StringBuilder();
sb.append("--").append(boundary).append("\r\n")
.append("Content-Disposition;form-data;name=\"file\";filename=\"")
.append(file.getName())
.append("\"\r\n")
.append("Content-Type:application/octet-stream\r\n\r\n");
byte[] head = sb.toString().getBytes("UTF-8");
// 獲得輸出流
OutputStream output = new DataOutputStream(connection.getOutputStream());
// 輸出表頭
output.write(head);
// 文件正文部分
// 把文件以流文件的方式,推入到url中
DataInputStream input = new DataInputStream(new FileInputStream(file));
int bytes = 0;
byte[] bufferOutput = new byte[1024];
while ((bytes = input.read(bufferOutput)) != -1) {
output.write(bufferOutput, 0, bytes);
}
input.close();
// 結尾部分,定義最後數據分割線
byte[] foot = ("\r\n--" + boundary + "--\r\n").getBytes("utf-8");
output.write(foot);
output.flush();
output.close();
StringBuilder buffer = new StringBuilder();
String result = null;
try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
String line = null;
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
result = buffer.toString();
} catch (IOException e) {
e.printStackTrace();
}
JSONObject jsonObject = new JSONObject(result);
log.info("response data: {}", jsonObject);
return jsonObject.getString(key);
}
在測試類中新增一個測試方法,測試代碼如下:
@Test
public void upload() throws IOException {
String filePath = "Z:/v2-9b17df91629f842edd472d7cfcaa9c4b_hd.jpg";
AccessToken accessToken = WeiXinUtil.getAccessToken();
String mediaId = WeiXinUtil.upload(filePath, accessToken.getToken(), "image");
System.out.println(mediaId);
}
控制臺輸出結果如下:
mediaId: 5_PCrofX1_KIpSfWzJE-tu7AxQjxw6zlQ44oBuUkM_PZ6FiPeDY0a7vcWU2zdap9
獲取到media_id後,就可以開始開發回復圖片消息功能了,首先根據官方給出的數據結構,封裝好各個實體類。Image類代碼如下:
package org.zero01.weixin.mqdemo.vo;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
@Data
public class Image {
@XStreamAlias("MediaId")
private String mediaId;
}
ImageMessage類代碼如下:
package org.zero01.weixin.mqdemo.vo;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
@Data
public class ImageMessage extends BaseMassage {
@XStreamAlias("Image")
private Image image;
}
然後在MessageUtil中新增如下兩個方法:
/**
* 將圖片消息轉換為xml
*
* @param imageMessage
* @return
*/
public static String imageMessageToXml(ImageMessage imageMessage) {
XStream xStream = new XStream();
xStream.processAnnotations(new Class[]{ImageMessage.class, Image.class});
xStream.alias("xml", imageMessage.getClass());
return xStream.toXML(imageMessage);
}
/**
* 組裝圖片消息對象
*
* @param toUserName
* @param fromUserName
* @return
*/
public static String initImageMessage(String toUserName, String fromUserName) {
Image image = new Image();
image.setMediaId("5_PCrofX1_KIpSfWzJE-tu7AxQjxw6zlQ44oBuUkM_PZ6FiPeDY0a7vcWU2zdap9");
ImageMessage imageMessage = new ImageMessage();
imageMessage.setFromUserName(toUserName);
imageMessage.setToUserName(fromUserName);
imageMessage.setMsgType(MessageTypeEnum.MSG_IMAGE.getMsgType());
imageMessage.setCreateTime(System.currentTimeMillis());
imageMessage.setImage(image);
return imageMessageToXml(imageMessage);
}
最後修改WeChatMqController中的text方法,增加一條判斷,判斷當用戶輸入數字2時,則回復圖片消息。代碼如下:
...
if ("1".equals(allMessage.getContent())) {
return MessageUtil.initNewsMessage(allMessage.getToUserName(), allMessage.getFromUserName());
} else if ("2".equals(allMessage.getContent())) {
return MessageUtil.initImageMessage(allMessage.getToUserName(), allMessage.getFromUserName());
}
...
完成以上代碼的編寫後,重啟SpringBoot,打開微信公眾號,測試結果如下:
音樂消息回復
在上一小節中,我們介紹了如何開發回復圖片消息的功能,而其他類似的消息回復都是差不多的,這裏就不一一去贅述了。本小節我們來看看如何進行音樂消息回復的開發,官方文檔地址如下:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140543
回復音樂消息所需傳遞的參數如下:
官方的圖文消息示例數據結構如下:
<xml>
<ToUserName>
<![CDATA[toUser]]>
</ToUserName>
<FromUserName>
<![CDATA[fromUser]]>
</FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType>
<![CDATA[music]]>
</MsgType>
<Music>
<Title>
<![CDATA[TITLE]]>
</Title>
<Description>
<![CDATA[DESCRIPTION]]>
</Description>
<MusicUrl>
<![CDATA[MUSIC_Url]]>
</MusicUrl>
<HQMusicUrl>
<![CDATA[HQ_MUSIC_Url]]>
</HQMusicUrl>
<ThumbMediaId>
<![CDATA[media_id]]>
</ThumbMediaId>
</Music>
</xml>
開發音樂消息回復,我們需要一個音樂文件,找一個mp3文件放在工程的resources/static目錄下即可,並確保能夠在外網上訪問:
根據官方給出的數據結構,封裝好各個實體類。Music 實體類代碼如下:
package org.zero01.weixin.mqdemo.vo;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
@Data
public class Music {
@XStreamAlias("Title")
private String title;
@XStreamAlias("Description")
private String description;
@XStreamAlias("MusicUrl")
private String musicUrl;
@XStreamAlias("HQMusicUrl")
private String hQMusicUrl;
@XStreamAlias("ThumbMediaId")
private String thumbMediaId;
}
MusicMessage 實體類代碼如下:
package org.zero01.weixin.mqdemo.vo;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
@Data
public class MusicMessage extends BaseMassage {
@XStreamAlias("Music")
private Music music;
}
由於音樂消息需要傳遞一個ThumbMediaId,也就是縮略圖的媒體id。所以我們需要修改之前的測試代碼,以此獲取thumb_media_id,如下:
@Test
public void upload() throws IOException {
String filePath = "Z:/v2-9b17df91629f842edd472d7cfcaa9c4b_hd.jpg";
AccessToken accessToken = WeiXinUtil.getAccessToken();
String thumbMediaId = WeiXinUtil.upload(filePath, accessToken.getToken(), "thumb","thumb_media_id");
System.out.println("thumb_media_id: " + thumbMediaId);
}
執行以上測試方法,控制臺輸出的結果如下:
thumb_media_id: Iu9puUGeFcS8HWyBGepJfeGoLDV_sWg8vJTeG-akMhcSGrqFjvoimMhCfjWw8F53
復制好thumb_media_id,然後在MessageUtil中新增如下兩個方法:
/**
* 將音樂消息轉換為xml
*
* @param musicMessage
* @return
*/
public static String musicMessageToXml(MusicMessage musicMessage) {
XStream xStream = new XStream();
xStream.processAnnotations(new Class[]{MusicMessage.class, Music.class});
xStream.alias("xml", musicMessage.getClass());
return xStream.toXML(musicMessage);
}
/**
* 組裝音樂消息對象
*
* @param toUserName
* @param fromUserName
* @return
*/
public static String initMusicMessage(String toUserName, String fromUserName) {
Music music = new Music();
music.setTitle("音樂消息");
music.setDescription("這是一個音樂消息");
music.setThumbMediaId("Iu9puUGeFcS8HWyBGepJfeGoLDV_sWg8vJTeG-akMhcSGrqFjvoimMhCfjWw8F53");
music.setMusicUrl("http://zero.mynatapp.cc/Unravel.mp3");
music.setHQMusicUrl("http://zero.mynatapp.cc/Unravel.mp3");
MusicMessage musicMessage = new MusicMessage();
musicMessage.setFromUserName(toUserName);
musicMessage.setToUserName(fromUserName);
musicMessage.setMsgType(MessageTypeEnum.MSG_MUSIC.getMsgType());
musicMessage.setCreateTime(System.currentTimeMillis());
musicMessage.setMusic(music);
return musicMessageToXml(musicMessage);
}
最後修改WeChatMqController中的text方法,增加一條判斷,判斷當用戶輸入數字3時,則回復音樂消息。代碼如下:
...
if ("1".equals(allMessage.getContent())) {
return MessageUtil.initNewsMessage(allMessage.getToUserName(), allMessage.getFromUserName());
} else if ("2".equals(allMessage.getContent())) {
return MessageUtil.initImageMessage(allMessage.getToUserName(), allMessage.getFromUserName());
} else if ("3".equals(allMessage.getContent())) {
return MessageUtil.initMusicMessage(allMessage.getToUserName(), allMessage.getFromUserName());
}
...
完成以上代碼的編寫後,重啟SpringBoot,打開微信測試公眾號進行測試,測試結果如下:
點擊音樂消息,打開後效果如下:
註:我這用的是pc端的微信,是可以正常播放的,但實際手機端很有可能無法播放,這也是微信的一個小坑
微信開發-素材/消息管理接口