微信公眾號最新修改了素材的管理模式,提供了兩類素材的管理:臨時素材和永久素材的管理,原先的素材管理就是臨時素材管理,永久素材可以永久保留在微信服務器上,微信素材可以在上傳後,進行圖片文件或者圖文消息的發送,關注的公眾號可以在素材有效期內查看相關的資源,對於永久素材,那就不會存在過期的問題,只是純粹數量上限的限制。本文綜合兩方面進行介紹素材管理的各種接口和實現。
關於素材的官方說明:
臨時素材:
公眾號經常有需要用到一些臨時性的多媒體素材的場景,例如在使用接口特別是發送消息時,對多媒體文件、多媒體消息的獲取和調用等操作,是通過media_id來進行的。素材管理接口對所有認證的訂閱號和服務號開放。通過本接口,公眾號可以新增臨時素材(即上傳臨時多媒體文件)。對於臨時素材,每個素材(media_id)會在開發者上傳或粉絲發送到微信服務器3天後自動刪除。素材的格式大小等要求與公眾平台官網一致。具體是,圖片大小不超過2M,支持bmp/png/jpeg/jpg/gif格式,語音大小不超過5M,長度不超過60秒,支持mp3/wma/wav/amr格式。
永久素材:
除了3天就會失效的臨時素材外,開發者有時需要永久保存一些素材,屆時就可以通過本接口新增永久素材。新增的永久素材也可以在公眾平台官網素材管理模塊中看到。永久素材的數量是有上限的,請謹慎新增。圖文消息素材和圖片素材的上限為5000,其他類型為1000。
素材管理包含了下面截圖的相關功能:
我們定義一個IMediaApi接口,用來定義相關的接口處理。
1)上傳臨時文件
對於上傳臨時文件,官方的接口定義如下所示。
接口調用請求說明
http請求方式: POST/FORM,需使用https https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE 調用示例(使用curl命令,用FORM表單方式上傳一個多媒體文件): curl -F [email protected] "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE"
對於上傳臨時文件的處理,我們可以定義它的接口如下所示。
/// <summary> /// 上傳的臨時多媒體文件。格式和大小限制,如下: /// 圖片(image): 1M,支持JPG格式 /// 語音(voice):2M,播放長度不超過60s,支持AMR\MP3格式 /// 視頻(video):10MB,支持MP4格式 /// 縮略圖(thumb):64KB,支持JPG格式。 /// 媒體文件在後台保存時間為3天,即3天後media_id失效。 /// </summary> /// <param name="accessToken">調用接口憑證</param> /// <param name="type">媒體文件類型,分別有圖片(image)、語音(voice)、視頻(video)和縮略圖(thumb)</param> /// <param name="file">form-data中媒體文件標識,有filename、filelength、content-type等信息</param> /// <returns></returns> UploadJsonResult UploadTempMedia(string accessToken, UploadMediaFileType type, string file);
根據官方接口的說明,我們需要上傳一個文件,並指定它的類型TYPE就可以了。
具體代碼如下所示。
public UploadJsonResult UploadTempMedia(string accessToken, UploadMediaFileType type, string file) { string url = string.Format("http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token={0}&type={1}", accessToken, type.ToString()); UploadJsonResult result = JsonHelper<UploadJsonResult>.PostFile(url, file); return result; }
其中JsonHelper類的PostFile就是發送一個文件流,我們進一步可以看它的實現思路如下所示。
/// <summary> /// 提交文件並解析返回的結果 /// </summary> /// <param name="url">提交文件數據的鏈接地址</param> /// <param name="file">文件地址</param> /// <returns></returns> public static T PostFile(string url, string file, NameValueCollection nvc = null) { HttpHelper helper = new HttpHelper(); string content = helper.PostStream(url, new string[] { file }, nvc); VerifyErrorCode(content); T result = JsonConvert.DeserializeObject<T>(content); return result; }
上面代碼主要就是通過POST一個文件流,並獲得響應的結果字符串內容,然後我們分析其中是否有錯誤代碼,如果沒有,我們把字符串結果解析為對應的實體對象就可以了。
其中返回結果的實體類信息UploadJsonResult的類定義如下所示。
/// <summary> /// 上傳多媒體文件的返回結果 /// </summary> public class UploadJsonResult : BaseJsonResult { /// <summary> /// 媒體文件類型,分別有圖片(image)、語音(voice)、視頻(video)和縮略圖(thumb,主要用於視頻與音樂格式的縮略圖) /// </summary> public UploadMediaFileType type { get; set; } /// <summary> /// 媒體文件上傳後,獲取時的唯一標識 /// </summary> public string media_id { get; set; } /// <summary> /// 媒體文件上傳時間戳 /// </summary> public long created_at { get; set; } }
這個接口的調用實例代碼如下所示。
private void btnUpload_Click(object sender, EventArgs e) { string file = FileDialogHelper.OpenImage(false); if (!string.IsNullOrEmpty(file)) { IMediaApi mediaBLL = new MediaApi(); UploadJsonResult result = mediaBLL.UploadTempMedia(token, UploadMediaFileType.image, file); if (result != null) { this.image_mediaId = result.media_id; Console.WriteLine("{0} {1}", result.media_id, result.created_at); } else { Console.WriteLine("上傳文件失敗"); } } }
2)獲取臨時素材文件
上傳文件是上傳一個文件流,並獲得對應的返回結果,主要就是一個media_Id的內容;而獲取素材文件則是一個逆過程,通過一個media_id的參數獲取一個文件流保存到本地的過程。
獲取臨時文件接口的官方定義如下所示。
接口調用請求說明
http請求方式: GET,https調用 https://api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID 請求示例(示例為通過curl命令獲取多媒體文件) curl -I -G "https://api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID"
對於獲取臨時文件,我們定義的接口如下所示。
/// <summary> /// 獲取臨時素材 /// </summary> /// <param name="accessToken">調用接口憑證</param> /// <param name="mediaId">媒體文件ID</param> /// <param name="stream"></param> Stream GetTempMedia(string accessToken, string mediaId, ref string fileName);
我們獲得文件流的同時,也返回一個文件名參數(不過一般情況下,我們獲取不到文件名)。
它的實現代碼如下所示,主要邏輯就是解析返回結果,獲取返回的文件流。
/// <summary> /// 獲取臨時素材 /// </summary> /// <param name="accessToken">調用接口憑證</param> /// <param name="mediaId">媒體文件ID</param> /// <param name="stream"></param> public Stream GetTempMedia(string accessToken, string mediaId, ref string fileName) { string url = string.Format("http://file.api.weixin.qq.com/cgi-bin/media/get?access_token={0}&media_id={1}", accessToken, mediaId); HttpHelper helper = new HttpHelper(); Stream stream = helper.GetStream(url, ref fileName, null); return stream; }
獲取素材文件的實例代碼如下所示。
private void btnDownload_Click(object sender, EventArgs e) { if (!string.IsNullOrEmpty(image_mediaId)) { IMediaApi mediaBLL = new MediaApi(); string fileName = ""; Stream stream = mediaBLL.GetTempMedia(token, image_mediaId, ref fileName); if (stream != null) { string filePath = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, fileName); using (var fileStream = File.Create(filePath)) { byte[] buffer = new byte[1024]; int bytesRead = 0; while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) != 0) { fileStream.Write(buffer, 0, bytesRead); } fileStream.Flush(); } stream.Close(); } Console.WriteLine("下載文件:" + (File.Exists(fileName) ? "成功" : "失敗")); } }
根據官方接口的描述,我們可以把新增永久素材接口定義為三種:新增圖文素材、其他類型永久素材和視頻素材三種接口。
接口調用請求說明
http請求方式: POST https://api.weixin.qq.com/cgi-bin/material/add_news?access_token=ACCESS_TOKEN
調用示例
{ "articles": [{ "title": TITLE, "thumb_media_id": THUMB_MEDIA_ID, "author": AUTHOR, "digest": DIGEST, "show_cover_pic": SHOW_COVER_PIC(0 / 1), "content": CONTENT, "content_source_url": CONTENT_SOURCE_URL }, //若新增的是多圖文素材,則此處應還有幾段articles結構 ] }
接口調用請求說明
通過POST表單來調用接口,表單id為media,包含需要上傳的素材內容,有filename、filelength、content-type等信息。請注意:圖片素材將進入公眾平台官網素材管理模塊中的默認分組。
http請求方式: POST http://api.weixin.qq.com/cgi-bin/material/add_material?access_token=ACCESS_TOKEN 調用示例(使用curl命令,用FORM表單方式新增一個其他類型的永久素材): curl -F [email protected] "http://file.api.weixin.qq.com/cgi-bin/material/add_material?access_token=ACCESS_TOKEN"
在上傳視頻素材時需要POST另一個表單,id為description,包含素材的描述信息,內容格式為JSON,格式如下:
{ "title":VIDEO_TITLE, "introduction":INTRODUCTION }
新增永久視頻素材的調用示例:
curl "http://file.api.weixin.qq.com/cgi-bin/material/add_material?access_token=ACCESS_TOKEN" -F [email protected] -F description='{"title":VIDEO_TITLE, "introduction":INTRODUCTION}'
根據上面的說明,我們定義新增永久圖文素材的接口代碼如下所示。
/// <summary> /// 新增永久圖文素材 /// </summary> /// <param name="accessToken">調用接口憑證</param> /// <param name="newsList">圖文消息組</param> /// <returns></returns> MaterialResult UploadMaterialNews(string accessToken, List<NewsUploadJson> newsList);
定義新增其他永久素材接口如下:
/// <summary> /// 新增其他類型永久素材(圖片(image)、語音(voice)和縮略圖(thumb)) /// </summary> /// <param name="accessToken">調用接口憑證</param> /// <param name="type">媒體文件類型,分別有圖片(image)、語音(voice)、視頻(video)和縮略圖(thumb)</param> /// <param name="file">form-data中媒體文件標識,有filename、filelength、content-type等信息</param> /// <returns></returns> MaterialResult UploadMaterialMedia(string accessToken, UploadMediaFileType type, string file);
定義新增視頻永久素材接口如下所示:
/// <summary> /// 在上傳視頻素材時需要POST另一個表單,id為description,包含素材的描述信息,內容格式為JSON. /// </summary> /// <param name="accessToken">調用接口憑證</param> /// <param name="file">form-data中媒體文件標識,有filename、filelength、content-type等信息</param> /// <param name="title">視頻標題</param> /// <param name="introduction">視頻描述</param> /// <returns></returns> MaterialResult UploadMaterialVideo(string accessToken, string file, string title, string introduction);
這幾個接口都沒有太多難度,不過在微信接口討論組裡面,很多人對於上傳永久素材的操作總是不成功,覺得可能是微信API本身的問題,其實不然,這個接口我還是測試通過了,並且在服務器上看到對應的素材信息,具體我們來看看上傳其他類型素材的接口實現代碼。
/// <summary> /// 新增其他類型永久素材(圖片(image)、語音(voice)和縮略圖(thumb)) /// </summary> /// <param name="accessToken">調用接口憑證</param> /// <param name="type">媒體文件類型,分別有圖片(image)、語音(voice)、視頻(video)和縮略圖(thumb)</param> /// <param name="file">form-data中媒體文件標識,有filename、filelength、content-type等信息</param> /// <returns></returns> public MaterialResult UploadMaterialMedia(string accessToken, UploadMediaFileType type, string file) { string url = string.Format("http://api.weixin.qq.com/cgi-bin/material/add_material?access_token={0}&type={1}", accessToken, type.ToString()); MaterialResult result = JsonHelper<MaterialResult>.PostFile(url, file); return result; }
注意這個URL是http而不是https,有點特殊。
另外,我們在使用POST文件流的時候,HttpWebRequest對象的內容一定要設置好,主要是需要和微信定義的media這個保持一直才可以。如下是HttpHelper 輔助類裡面的PostStream的部分代碼,供參考。
永久素材上傳後的結果可以在微信公眾號後台進行查看到,具體界面如下所示。
對於永久素材的接口,我們還可以根據微信API的要求,完善永久素材的更新、刪除、獲取素材,以及獲取素材總數、獲取圖文素材列表等功能,由於大多數操作類似,不需要一一列出,希望再次拋磚引玉,使得大家能夠更好了解、利用好微信公眾號的素材管理接口,從而實現我們更加豐富的數據管理。
如果對這個《C#開發微信門戶及應用》系列感興趣,可以關注我的其他文章,系列隨筆如下所示:
C#開發微信門戶及應用(25)-微信企業號的客戶端管理功能
C#開發微信門戶及應用(24)-微信小店貨架信息管理
C#開發微信門戶及應用(23)-微信小店商品管理接口的封裝和測試
C#開發微信門戶及應用(22)-微信小店的開發和使用
C#開發微信門戶及應用(21)-微信企業號的消息和事件的接收處理及解密
C#開發微信門戶及應用(20)-微信企業號的菜單管理
C#開發微信門戶及應用(19)-微信企業號的消息發送(文本、圖片、文件、語音、視頻、圖文消息等)
C#開發微信門戶及應用(18)-微信企業號的通訊錄管理開發之成員管理
C#開發微信門戶及應用(17)-微信企業號的通訊錄管理開發之部門管理
C#開發微信門戶及應用(16)-微信企業號的配置和使用
C#開發微信門戶及應用(15)-微信菜單增加掃一掃、發圖片、發地理位置功能
C#開發微信門戶及應用(14)-在微信菜單中采用重定向獲取用戶數據
C#開發微信門戶及應用(13)-使用地理位置擴展相關應用
C#開發微信門戶及應用(12)-使用語音處理
C#開發微信門戶及應用(11)--微信菜單的多種表現方式介紹
C#開發微信門戶及應用(10)--在管理系統中同步微信用戶分組信息
C#開發微信門戶及應用(9)-微信門戶菜單管理及提交到微信服務器
C#開發微信門戶及應用(8)-微信門戶應用管理系統功能介紹
C#開發微信門戶及應用(7)-微信多客服功能及開發集成
C#開發微信門戶及應用(6)--微信門戶菜單的管理操作
C#開發微信門戶及應用(5)--用戶分組信息管理
C#開發微信門戶及應用(4)--關注用戶列表及詳細信息管理
C#開發微信門戶及應用(3)--文本消息和圖文消息的應答
C#開發微信門戶及應用(2)--微信消息的處理和應答
C#開發微信門戶及應用(1)--開始使用微信接口