C#開發(fā)微信門戶及應(yīng)用(26)-公眾號微信素材管理

微信公眾號最新修改了素材的管理模式,提供了兩類素材的管理:臨時素材和永久素材的管理朝群,原先的素材管理就是臨時素材管理哭当,永久素材可以永久保留在微信服務(wù)器上,微信素材可以在上傳后配阵,進(jìn)行圖片文件或者圖文消息的發(fā)送馏颂,關(guān)注的公眾號可以在素材有效期內(nèi)查看相關(guān)的資源示血,對于永久素材,那就不會存在過期的問題救拉,只是純粹數(shù)量上限的限制难审。本文綜合兩方面進(jìn)行介紹素材管理的各種接口和實(shí)現(xiàn)。

1亿絮、素材類型和功能點(diǎn)

關(guān)于素材的官方說明:
臨時素材:
公眾號經(jīng)常有需要用到一些臨時性的多媒體素材的場景告喊,例如在使用接口特別是發(fā)送消息時,對多媒體文件派昧、多媒體消息的獲取和調(diào)用等操作黔姜,是通過media_id來進(jìn)行的。素材管理接口對所有認(rèn)證的訂閱號和服務(wù)號開放蒂萎。通過本接口秆吵,公眾號可以新增臨時素材(即上傳臨時多媒體文件)。對于臨時素材五慈,每個素材(media_id)會在開發(fā)者上傳或粉絲發(fā)送到微信服務(wù)器3天后自動刪除纳寂。素材的格式大小等要求與公眾平臺官網(wǎng)一致。具體是泻拦,圖片大小不超過2M毙芜,支持bmp/png/jpeg/jpg/gif格式,語音大小不超過5M争拐,長度不超過60秒腋粥,支持mp3/wma/wav/amr格式。
永久素材:
除了3天就會失效的臨時素材外陆错,開發(fā)者有時需要永久保存一些素材,屆時就可以通過本接口新增永久素材金赦。新增的永久素材也可以在公眾平臺官網(wǎng)素材管理模塊中看到音瓷。永久素材的數(shù)量是有上限的,請謹(jǐn)慎新增夹抗。圖文消息素材和圖片素材的上限為5000绳慎,其他類型為1000。

素材管理包含了下面截圖的相關(guān)功能:


2漠烧、臨時素材的管理接口定義和實(shí)現(xiàn)

我們定義一個IMediaApi接口杏愤,用來定義相關(guān)的接口處理。
1)上傳臨時文件
對于上傳臨時文件已脓,官方的接口定義如下所示珊楼。
接口調(diào)用請求說明

http請求方式: POST/FORM,需使用httpshttps://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE
調(diào)用示例(使用curl命令,用FORM表單方式上傳一個多媒體文件):curl -F media=@test.jpg "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">調(diào)用接口憑證</param>
/// <param name="type">媒體文件類型,分別有圖片(image)把将、語音(voice)轻专、視頻(video)和縮略圖(thumb)</param>
/// <param name="file">form-data中媒體文件標(biāo)識,有filename察蹲、filelength请垛、content-type等信息</param>
/// <returns></returns>
UploadJsonResult UploadTempMedia(string accessToken, UploadMediaFileType type, string file);

根據(jù)官方接口的說明,我們需要上傳一個文件洽议,并指定它的類型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就是發(fā)送一個文件流亚兄,我們進(jìn)一步可以看它的實(shí)現(xiàn)思路如下所示混稽。

/// <summary>
/// 提交文件并解析返回的結(jié)果
/// </summary>
/// <param name="url">提交文件數(shù)據(jù)的鏈接地址</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一個文件流,并獲得響應(yīng)的結(jié)果字符串內(nèi)容审胚,然后我們分析其中是否有錯誤代碼匈勋,如果沒有,我們把字符串結(jié)果解析為對應(yīng)的實(shí)體對象就可以了膳叨。

其中返回結(jié)果的實(shí)體類信息UploadJsonResult的類定義如下所示洽洁。

/// <summary>
/// 上傳多媒體文件的返回結(jié)果
/// </summary>
public class UploadJsonResult : BaseJsonResult
{
    /// <summary>
    /// 媒體文件類型,分別有圖片(image)菲嘴、語音(voice)饿自、視頻(video)和縮略圖(thumb,主要用于視頻與音樂格式的縮略圖)
    /// </summary>
    public UploadMediaFileType type { get; set; }

    /// <summary>
    /// 媒體文件上傳后龄坪,獲取時的唯一標(biāo)識
    /// </summary>
    public string media_id { get; set; }

    /// <summary>
    /// 媒體文件上傳時間戳
    /// </summary>
    public long created_at { get; set; }
}

這個接口的調(diào)用實(shí)例代碼如下所示昭雌。

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)獲取臨時素材文件
上傳文件是上傳一個文件流,并獲得對應(yīng)的返回結(jié)果健田,主要就是一個media_Id的內(nèi)容烛卧;而獲取素材文件則是一個逆過程,通過一個media_id的參數(shù)獲取一個文件流保存到本地的過程妓局。
獲取臨時文件接口的官方定義如下所示唱星。
接口調(diào)用請求說明

http請求方式: GET,https調(diào)用
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">調(diào)用接口憑證</param>
/// <param name="mediaId">媒體文件ID</param>
/// <param name="stream"></param>
Stream GetTempMedia(string accessToken, string mediaId, ref string fileName);

我們獲得文件流的同時间聊,也返回一個文件名參數(shù)(不過一般情況下攒盈,我們獲取不到文件名)。

它的實(shí)現(xiàn)代碼如下所示哎榴,主要邏輯就是解析返回結(jié)果型豁,獲取返回的文件流。

/// <summary>
/// 獲取臨時素材
/// </summary>
/// <param name="accessToken">調(diào)用接口憑證</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;
}

獲取素材文件的實(shí)例代碼如下所示尚蝌。

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) ? "成功" : "失敗"));
    }
}

3迎变、永久素材的管理接口定義和實(shí)現(xiàn)

根據(jù)官方接口的描述,我們可以把新增永久素材接口定義為三種:新增圖文素材飘言、其他類型永久素材和視頻素材三種接口衣形。
1)新增永久圖文素材
接口調(diào)用請求說明

http請求方式: POST
https://api.weixin.qq.com/cgi-bin/material/add_news?access_token=ACCESS_TOKEN

調(diào)用示例

{
  "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
    },
    //若新增的是多圖文素材,則此處應(yīng)還有幾段articles結(jié)構(gòu)
 ]
}

2)新增其他類型永久素材
接口調(diào)用請求說明
通過POST表單來調(diào)用接口姿鸿,表單id為media谆吴,包含需要上傳的素材內(nèi)容,有filename苛预、filelength句狼、content-type等信息。請注意:圖片素材將進(jìn)入公眾平臺官網(wǎng)素材管理模塊中的默認(rèn)分組热某。

http請求方式: POST
http://api.weixin.qq.com/cgi-bin/material/add_material?access_token=ACCESS_TOKEN
調(diào)用示例(使用curl命令腻菇,用FORM表單方式新增一個其他類型的永久素材):curl -F media=@test.jpg "http://file.api.weixin.qq.com/cgi-bin/material/add_material?access_token=ACCESS_TOKEN"

3)新增永久視頻素材
在上傳視頻素材時需要POST另一個表單,id為description昔馋,包含素材的描述信息筹吐,內(nèi)容格式為JSON,格式如下:

{ "title":VIDEO_TITLE, "introduction":INTRODUCTION}

新增永久視頻素材的調(diào)用示例:

curl "http://file.api.weixin.qq.com/cgi-bin/material/add_material?access_token=ACCESS_TOKEN" -F media=@media.file -F description='{"title":VIDEO_TITLE, "introduction":INTRODUCTION}'

根據(jù)上面的說明秘遏,我們定義新增永久圖文素材的接口代碼如下所示丘薛。

/// <summary>
/// 新增永久圖文素材
/// </summary>
/// <param name="accessToken">調(diào)用接口憑證</param>
/// <param name="newsList">圖文消息組</param>
/// <returns></returns>
MaterialResult UploadMaterialNews(string accessToken, List<NewsUploadJson> newsList);

定義新增其他永久素材接口如下:

/// <summary>
/// 新增其他類型永久素材(圖片(image)、語音(voice)和縮略圖(thumb))
/// </summary>
/// <param name="accessToken">調(diào)用接口憑證</param>
/// <param name="type">媒體文件類型垄提,分別有圖片(image)榔袋、語音(voice)周拐、視頻(video)和縮略圖(thumb)</param>
/// <param name="file">form-data中媒體文件標(biāo)識铡俐,有filename、filelength妥粟、content-type等信息</param>
/// <returns></returns>
MaterialResult UploadMaterialMedia(string accessToken, UploadMediaFileType type, string file);

定義新增視頻永久素材接口如下所示:

/// <summary>
/// 在上傳視頻素材時需要POST另一個表單审丘,id為description,包含素材的描述信息勾给,內(nèi)容格式為JSON.
/// </summary>
/// <param name="accessToken">調(diào)用接口憑證</param>
/// <param name="file">form-data中媒體文件標(biāo)識滩报,有filename锅知、filelength、content-type等信息</param>
/// <param name="title">視頻標(biāo)題</param>
/// <param name="introduction">視頻描述</param>
/// <returns></returns>
MaterialResult UploadMaterialVideo(string accessToken, string file, string title, string introduction);

這幾個接口都沒有太多難度脓钾,不過在微信接口討論組里面售睹,很多人對于上傳永久素材的操作總是不成功,覺得可能是微信API本身的問題可训,其實(shí)不然昌妹,這個接口我還是測試通過了,并且在服務(wù)器上看到對應(yīng)的素材信息握截,具體我們來看看上傳其他類型素材的接口實(shí)現(xiàn)代碼飞崖。

/// <summary>
/// 新增其他類型永久素材(圖片(image)、語音(voice)和縮略圖(thumb))
/// </summary>
/// <param name="accessToken">調(diào)用接口憑證</param>
/// <param name="type">媒體文件類型谨胞,分別有圖片(image)固歪、語音(voice)、視頻(video)和縮略圖(thumb)</param>
/// <param name="file">form-data中媒體文件標(biāo)識胯努,有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康聂,有點(diǎn)特殊贰健。
另外,我們在使用POST文件流的時候恬汁,HttpWebRequest對象的內(nèi)容一定要設(shè)置好伶椿,主要是需要和微信定義的media這個保持一直才可以。如下是HttpHelper 輔助類里面的PostStream的部分代碼氓侧,供參考脊另。



永久素材上傳后的結(jié)果可以在微信公眾號后臺進(jìn)行查看到,具體界面如下所示约巷。



對于永久素材的接口偎痛,我們還可以根據(jù)微信API的要求,完善永久素材的更新独郎、刪除踩麦、獲取素材,以及獲取素材總數(shù)氓癌、獲取圖文素材列表等功能谓谦,由于大多數(shù)操作類似,不需要一一列出贪婉,希望再次拋磚引玉反粥,使得大家能夠更好了解、利用好微信公眾號的素材管理接口,從而實(shí)現(xiàn)我們更加豐富的數(shù)據(jù)管理才顿。
如果對這個《C#開發(fā)微信門戶及應(yīng)用》系列感興趣莫湘,可以關(guān)注我的其他文章
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市郑气,隨后出現(xiàn)的幾起案子幅垮,更是在濱河造成了極大的恐慌,老刑警劉巖尾组,帶你破解...
    沈念sama閱讀 216,919評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件军洼,死亡現(xiàn)場離奇詭異,居然都是意外死亡演怎,警方通過查閱死者的電腦和手機(jī)匕争,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來爷耀,“玉大人甘桑,你說我怎么就攤上這事〈醵#” “怎么了跑杭?”我有些...
    開封第一講書人閱讀 163,316評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長咆耿。 經(jīng)常有香客問我德谅,道長,這世上最難降的妖魔是什么萨螺? 我笑而不...
    開封第一講書人閱讀 58,294評論 1 292
  • 正文 為了忘掉前任窄做,我火速辦了婚禮,結(jié)果婚禮上慰技,老公的妹妹穿的比我還像新娘椭盏。我一直安慰自己,他們只是感情好吻商,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評論 6 390
  • 文/花漫 我一把揭開白布掏颊。 她就那樣靜靜地躺著,像睡著了一般艾帐。 火紅的嫁衣襯著肌膚如雪乌叶。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,245評論 1 299
  • 那天柒爸,我揣著相機(jī)與錄音准浴,去河邊找鬼。 笑死揍鸟,一個胖子當(dāng)著我的面吹牛兄裂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播阳藻,決...
    沈念sama閱讀 40,120評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼晰奖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了腥泥?” 一聲冷哼從身側(cè)響起匾南,我...
    開封第一講書人閱讀 38,964評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蛔外,沒想到半個月后蛆楞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,376評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡夹厌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評論 2 333
  • 正文 我和宋清朗相戀三年豹爹,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片矛纹。...
    茶點(diǎn)故事閱讀 39,764評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡臂聋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出或南,到底是詐尸還是另有隱情孩等,我是刑警寧澤,帶...
    沈念sama閱讀 35,460評論 5 344
  • 正文 年R本政府宣布采够,位于F島的核電站肄方,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蹬癌。R本人自食惡果不足惜权她,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望逝薪。 院中可真熱鬧伴奥,春花似錦、人聲如沸翼闽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽感局。三九已至尼啡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間询微,已是汗流浹背崖瞭。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留撑毛,地道東北人书聚。 一個月前我還...
    沈念sama閱讀 47,819評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親雌续。 傳聞我的和親對象是個殘疾皇子斩个,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評論 2 354

推薦閱讀更多精彩內(nèi)容