微信開發之被動回覆與上傳下載文件
第五章已經講了怎麼處理用戶發送的訊息,本章就來講講怎麼回應用戶的請求。想必新手看到這個標題也就懵了,千萬別懵,微信的介面就這樣,在回覆圖片、音樂、語音等都需要將我們的媒體檔案上傳到微信的伺服器才能使用。不知道這樣的做法是出於什麼考慮的,而且同是給用戶回覆訊息,客服介面和群發介面發送的訊息體格式竟然是不同的。估計是這幾處介面不是同一個人寫的,沒有做好程式碼的統一,咱們屌絲開發者只能無力吐槽了。
在講上傳下載介面前,需要先將下先來講講access_token取得方法。在微信介面開發的過程access_token是至關重要的,是公眾號的全域唯一票據,公眾號呼叫各介面時都需使用access_token。開發者需要進行妥善保存。 access_token的儲存至少要保留512個字元空間。 access_token的有效期限目前為2小時,需定時刷新,重複取得將導致上次取得的access_token失效。需要注意的時,一個公眾號同時只存在一個有效的access_token,開發者需要在access_token過期前,刷新access_token。在刷新的過程中,公眾平台後台會保證在刷新短時間內,新舊access_token都可用,這保證了第三方業務的平滑過渡。
公眾號可以使用AppID和AppSecret呼叫本介面來取得access_token。 AppID和AppSecret可在微信公眾平台官網-開發者中心頁中取得(需要已成為開發者,且帳號沒有異常狀態)。如下圖:
取得access_token的介面位址是:
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
将appid和secret替换成你自己的。
發送get請求到這個位址,傳回的資料如下:
{"access_token":"eEd6dhp0s24JfWwDyGBbrvJxnhqHTSYZ8MKdQ7MuCGBKxAjHv-tEIwhFZzn102lGvIWxnjZZreT6C1NCT9fpS7NREOkEX42yojVnqKVaicg","expires_in":7200}
我们只需解析这个json,即可获取到我们所需的access_token.代码如下:
AccessToken实体类:
public class AccessToken { public string token { get; set; } public DateTime expirestime { get; set; } }
取得access token
/// <summary> /// 获取access token /// </summary> /// <param name="appid">第三方用户唯一凭证</param> /// <param name="secret">第三方用户唯一凭证密钥,即appsecret</param> /// <returns>AccessToken对象,expirestime是过期时间</returns> public static AccessToken GetAccessToken(string appid, string secret) { try { string url = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", appid, secret); string retdata = Utils.HttpGet(url); if (retdata.Contains("access_token")) { JObject obj = (JObject)JsonConvert.DeserializeObject(retdata); string token = obj.Value<string>("access_token"); int expirestime = obj.Value<int>("expires_in"); return new AccessToken { token = token, expirestime = DateTime.Now.AddSeconds(expirestime) }; } else { WriteBug(retdata);//写错误日志 } return null; } catch (Exception e) { WriteBug(e.ToString());//写错误日志 return null; } }
access_token取得成功後,先來講上傳下載多媒體檔案吧。官方說,公眾號在使用介面時,對多媒體檔案、多媒體訊息的取得和呼叫等操作,是透過media_id來進行的(咱讀書少,不明白為什麼不能使用url,而要多此一舉先上傳到伺服器在發送)。透過本接口,公眾號可以上傳或下載多媒體檔案。但請注意,每個多媒體檔案(media_id)會在上傳、使用者傳送到微信伺服器3天後自動刪除,以節省伺服器資源。
上傳多媒體的介面位址是:
file.api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE
其中access_token為呼叫介面憑證,type是媒體檔案類型,分別有圖片(微信開發之被動回覆與上傳下載文件)、語音(voice)、影片(video)和縮圖(thumb)
上傳的多媒體檔案有格式和大小限制,如下:
圖片(微信開發之被動回覆與上傳下載文件): 1M,支援JPG格式
語音(voice):2M,播放長度不超過60s,支援AMR\MP3格式
影片(video):10MB,支援MP4格式
縮圖(thumb):64KB,支援JPG格式
媒體檔案在後台保存時間為3天,即3天後media_id失效。
為了方便調用,將媒體檔案的型別定義為枚舉,程式碼如下:
public enum MediaType { /// <summary> /// 图片(微信開發之被動回覆與上傳下載文件): 1M,支持JPG格式 /// </summary> 微信開發之被動回覆與上傳下載文件, /// <summary> /// 语音(voice):2M,播放长度不超过60s,支持AMR\MP3格式 /// </summary> voice, /// <summary> /// 视频(video):10MB,支持MP4格式 /// </summary> video, /// <summary> /// 缩略图(thumb):64KB,支持JPG格式 /// </summary> thumb }
然後定義傳回值的型別:
public class UpLoadInfo { /// <summary> /// 媒体文件类型,分别有图片(微信開發之被動回覆與上傳下載文件)、语音(voice)、视频(video)和缩略图(thumb,主要用于视频与音乐格式的缩略图) /// </summary> public string type { get; set; } /// <summary> /// 媒体文件上传后,获取时的唯一标识 /// </summary> public string media_id { get; set; } /// <summary> /// 媒体文件上传时间戳 /// </summary> public string created_at { get; set; } }
最後使用WebClient類別來上傳文件,並讀出返回值,程式碼如下:
/// <summary> /// 微信上传多媒体文件 /// </summary> /// <param name="filepath">文件绝对路径</param> public static ReceiveModel.UpLoadInfo WxUpLoad(string filepath, string token, MediaType mt) { using (WebClient client = new WebClient()) { byte[] b = client.UploadFile(string.Format("http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token={0}&type={1}", token, mt.ToString()), filepath);//调用接口上传文件 string retdata = Encoding.Default.GetString(b);//获取返回值 if (retdata.Contains("media_id"))//判断返回值是否包含media_id,包含则说明上传成功,然后将返回的json字符串转换成json { return JsonConvert.DeserializeObject<UpLoadInfo>(retdata); } else {//否则,写错误日志 WriteBug(retdata);//写错误日志 return null; } } }
至此,在講回覆訊息之前,插入了兩個基礎支援接口,由於各位整理歸納能力太爛了,各位看官請多包涵,如有問題就留言和我交流。 下面正式開始講回覆訊息。在看下面內容的時候,請大家結合第四,第五章來閱讀。
前面兩章講述了接收並處理用戶發送的訊息,講到了一個訊息基類BaseMessage,而不管我們接收到什麼類型的消息,都需要可以調用方法,進行響應用戶的請求,所以,用戶回覆用戶請求的方法需要封裝到基底類別中。以下先簡單了解下公眾號可以回覆的訊息類型,以及訊息格式。
注意:
一旦遇到以下情況,微信都會在公眾號會話中,向使用者下發系統提示「該公眾號暫時無法提供服務,請稍後再試」:
#1、开发者在5秒内未回复任何内容 2、开发者回复了异常数据,比如JSON数据等
回复文本消息
<xml><ToUserName><![CDATA[接收方帐号(收到的OpenID)]]></ToUserName><FromUserName><![CDATA[开发者微信号]]></FromUserName><CreateTime>消息创建时间 (整型)</CreateTime><MsgType><![CDATA[微信開發之被動回覆與上傳下載文件]]></MsgType><Content><![CDATA[回复的消息内容(换行:在content中能够换行,微信客户端就支持换行显示)]]></Content></xml>
回复图片消息
<xml><ToUserName><![CDATA[接收方帐号(收到的OpenID)]]></ToUserName><FromUserName><![CDATA[开发者微信号]]></FromUserName><CreateTime>消息创建时间 (整型)</CreateTime><MsgType><![CDATA[微信開發之被動回覆與上傳下載文件]]></MsgType><Image><MediaId><![CDATA[通过上传多媒体文件,得到的id。]]></MediaId></Image></xml>
回复语音消息
<xml><ToUserName><![CDATA[接收方帐号(收到的OpenID)]]></ToUserName><FromUserName><![CDATA[开发者微信号]]></FromUserName><CreateTime>消息创建时间 (整型)</CreateTime><MsgType><![CDATA[voice]]></MsgType><Voice><MediaId><![CDATA[通过上传多媒体文件,得到的id。]]></MediaId></Voice></xml>
回复视频消息
<xml><ToUserName><![CDATA[接收方帐号(收到的OpenID)]]></ToUserName><FromUserName><![CDATA[开发者微信号]]></FromUserName><CreateTime>消息创建时间 (整型)</CreateTime><MsgType><![CDATA[video]]></MsgType><Video><MediaId><![CDATA[通过上传多媒体文件,得到的id。]]></MediaId><Title><![CDATA[视频消息的标题]]></Title> <Description><![CDATA[视频消息的描述]]></Description> </Video></xml>
回复音乐消息
<xml><ToUserName><![CDATA[接收方帐号(收到的OpenID)]]></ToUserName><FromUserName><![CDATA[开发者微信号]]></FromUserName><CreateTime>消息创建时间 (整型)</CreateTime><MsgType><![CDATA[music]]></MsgType><Music><ThumbMediaId><![CDATA[缩略图的媒体id,通过上传多媒体文件,得到的id。]]></ThumbMediaId><Title><![CDATA[视频消息的标题]]></Title> <Description><![CDATA[视频消息的描述]]></Description> <MusicURL><![CDATA[音乐链接]]></MusicURL> <HQMusicUrl><![CDATA[高质量音乐链接,WIFI环境优先使用该链接播放音乐]]></HQMusicUrl> </Music></xml>
回复图文消息
<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>
回复图文中,item是一个项,一个item代码一个图文。在响应的时候,我们只需根据数据格式,替换掉对应的属性,然后Response.Write(s)即可。结合前两章的讲解,BaseMessage的最终代码如下:
/// <summary> /// 消息体基类 /// </summary> public abstract class BaseMessage { /// <summary> /// 开发者微信号 /// </summary> public string ToUserName { get; set; } /// <summary> /// 发送方帐号(一个OpenID) /// </summary> public string FromUserName { get; set; } /// <summary> /// 消息创建时间 (整型) /// </summary> public string CreateTime { get; set; } /// <summary> /// 消息类型 /// </summary> public MsgType MsgType { get; set; } public virtual void ResponseNull() { Utils.ResponseWrite(""); } public virtual void ResText(EnterParam param, string content) { StringBuilder resxml = new StringBuilder(string.Format("<xml><ToUserName><![CDATA[{0}]]></ToUserName><FromUserName><![CDATA[{1}]]></FromUserName><CreateTime>{2}</CreateTime>", FromUserName, ToUserName, Utils.ConvertDateTimeInt(DateTime.Now))); resxml.AppendFormat("<MsgType><![CDATA[text]]></MsgType><Content><![CDATA[{0}]]></Content><FuncFlag>0</FuncFlag></xml>", content); Response(param, resxml.ToString()); } /// <summary> /// 回复消息(音乐) /// </summary> public void ResMusic(EnterParam param, Music mu) { StringBuilder resxml = new StringBuilder(string.Format("<xml><ToUserName><![CDATA[{0}]]></ToUserName><FromUserName><![CDATA[{1}]]></FromUserName><CreateTime>{2}</CreateTime>",FromUserName,ToUserName, Utils.ConvertDateTimeInt(DateTime.Now))); resxml.Append(" <MsgType><![CDATA[music]]></MsgType>"); resxml.AppendFormat("<Music><Title><![CDATA[{0}]]></Title><Description><![CDATA[{1}]]></Description>", mu.Title, mu.Description); resxml.AppendFormat("<MusicUrl><![CDATA[http://{0}{1}]]></MusicUrl><HQMusicUrl><![CDATA[http://{2}{3}]]></HQMusicUrl></Music><FuncFlag>0</FuncFlag></xml>", VqiRequest.GetCurrentFullHost(), mu.MusicUrl, VqiRequest.GetCurrentFullHost(), mu.HQMusicUrl); Response(param, resxml.ToString()); } public void ResVideo(EnterParam param, Video v) { StringBuilder resxml = new StringBuilder(string.Format("<xml><ToUserName><![CDATA[{0}]]></ToUserName><FromUserName><![CDATA[{1}]]></FromUserName><CreateTime>{2}</CreateTime>",FromUserName,ToUserName, Utils.ConvertDateTimeInt(DateTime.Now))); resxml.Append(" <MsgType><![CDATA[video]]></MsgType>"); resxml.AppendFormat("<Video><MediaId><![CDATA[{0}]]></MediaId>", v.media_id); resxml.AppendFormat("<Title><![CDATA[{0}]]></Title>", v.title); resxml.AppendFormat("<Description><![CDATA[{0}]]></Description></Video></xml>", v.description); Response(param, resxml.ToString()); } /// <summary> /// 回复消息(图片) /// </summary> public void ResPicture(EnterParam param, Picture pic, string domain) { StringBuilder resxml = new StringBuilder(string.Format("<xml><ToUserName><![CDATA[{0}]]></ToUserName><FromUserName><![CDATA[{1}]]></FromUserName><CreateTime>{2}</CreateTime>",FromUserName,ToUserName, Utils.ConvertDateTimeInt(DateTime.Now))); resxml.Append(" <MsgType><![CDATA[微信開發之被動回覆與上傳下載文件]]></MsgType>"); resxml.AppendFormat("<PicUrl><![CDATA[{0}]]></PicUrl></xml>", domain + pic.PictureUrl); Response(param, resxml.ToString()); } /// <summary> /// 回复消息(图文列表) /// </summary> /// <param name="param"></param> /// <param name="art"></param> public void ResArticles(EnterParam param, List<Articles> art) { StringBuilder resxml = new StringBuilder(string.Format("<xml><ToUserName><![CDATA[{0}]]></ToUserName><FromUserName><![CDATA[{1}]]></FromUserName><CreateTime>{2}</CreateTime>",FromUserName,ToUserName, Utils.ConvertDateTimeInt(DateTime.Now))); resxml.AppendFormat("<MsgType><![CDATA[news]]></MsgType><ArticleCount>{0}</ArticleCount><Articles>", art.Count); for (int i = 0; i < art.Count; i++) { resxml.AppendFormat("<item><Title><![CDATA[{0}]]></Title> <Description><![CDATA[{1}]]></Description>", art[i].Title, art[i].Description); resxml.AppendFormat("<PicUrl><![CDATA[{0}]]></PicUrl><Url><![CDATA[{1}]]></Url></item>", art[i].PicUrl.Contains("http://") ? art[i].PicUrl : "http://" + VqiRequest.GetCurrentFullHost() + art[i].PicUrl, art[i].Url.Contains("http://") ? art[i].Url : "http://" + VqiRequest.GetCurrentFullHost() + art[i].Url); } resxml.Append("</Articles><FuncFlag>0</FuncFlag></xml>"); Response(param, resxml.ToString()); } /// <summary> /// 多客服转发 /// </summary> /// <param name="param"></param> public void ResDKF(EnterParam param) { StringBuilder resxml = new StringBuilder(); resxml.AppendFormat("<xml><ToUserName><![CDATA[{0}]]></ToUserName>",FromUserName); resxml.AppendFormat("<FromUserName><![CDATA[{0}]]></FromUserName><CreateTime>{1}</CreateTime>",ToUserName,CreateTime); resxml.AppendFormat("<MsgType><![CDATA[transfer_customer_service]]></MsgType></xml>"); Response(param, resxml.ToString()); } /// <summary> /// 多客服转发如果指定的客服没有接入能力(不在线、没有开启自动接入或者自动接入已满),该用户会一直等待指定客服有接入能力后才会被接入,而不会被其他客服接待。建议在指定客服时,先查询客服的接入能力指定到有能力接入的客服,保证客户能够及时得到服务。 /// </summary> /// <param name="param">用户发送的消息体</param> /// <param name="KfAccount">多客服账号</param> public void ResDKF(EnterParam param, string KfAccount) { StringBuilder resxml = new StringBuilder(); resxml.AppendFormat("<xml><ToUserName><![CDATA[{0}]]></ToUserName>",FromUserName); resxml.AppendFormat("<FromUserName><![CDATA[{0}]]></FromUserName><CreateTime>{1}</CreateTime>",ToUserName,CreateTime); resxml.AppendFormat("<MsgType><![CDATA[transfer_customer_service]]></MsgType><TransInfo><KfAccount>{0}</KfAccount></TransInfo></xml>", KfAccount); Response(param, resxml.ToString()); } private void Response(EnterParam param, string data) { if (param.IsAes) { var wxcpt = new MsgCrypt(param.token, param.EncodingAESKey, param.appid); wxcpt.EncryptMsg(data, Utils.ConvertDateTimeInt(DateTime.Now).ToString(), Utils.GetRamCode(), ref data); } Utils.ResponseWrite(data); } }
上面的代码中,public void ResDKF(EnterParam param),public void ResDKF(EnterParam param, string KfAccount)两个方法时多客服中,用户转发用户发送的消息的,多客服将在后期的博文中进行更新,敬请期待。
public void ResMusic(EnterParam param, Music mu)方法中的Music类的定义如下:
public class Music { #region 属性 /// <summary> /// 音乐链接 /// </summary> public string MusicUrl { get; set; } /// <summary> /// 高质量音乐链接,WIFI环境优先使用该链接播放音乐 /// </summary> public string HQMusicUrl { get; set; } /// <summary> /// 标题 /// </summary> public string Title { get; set; } /// <summary> /// 描述 /// </summary> public string Description { get; set; } #endregion }
public void ResVideo(EnterParam param, Video v)方法中的Video类的定义如下:
public class Video { public string title { get; set; } public string media_id { get; set; } public string description { get; set; } }
public void ResArticles(EnterParam param, List
public class Articles { #region 属性 /// <summary> /// 图文消息标题 /// </summary> public string Title { get; set; } /// <summary> /// 图文消息描述 /// </summary> public string Description { get; set; } /// <summary> /// 图片链接,支持JPG、PNG格式,较好的效果为大图640*320,小图80*80。 /// </summary> public string PicUrl { get; set; } /// <summary> /// 点击图文消息跳转链接 /// </summary> public string Url { get; set; } #endregion }
【相关推荐】
2.微信投票源码
以上是微信開發之被動回覆與上傳下載文件的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

PHP是一種開源的腳本語言,廣泛應用於網頁開發和伺服器端編程,尤其在微信開發中得到了廣泛的應用。如今,越來越多的企業和開發者開始使用PHP進行微信開發,因為它成為了真正的易學易用的開發語言。在微信開發中,訊息的加密和解密是一個非常重要的問題,因為它們涉及資料的安全性。對於沒有加密和解密方式的消息,駭客可以輕鬆取得其中的數據,對用戶造成威脅

隨著微信的普及,越來越多的企業開始將其作為行銷工具。而微信群發功能,則是企業進行微信行銷的重要手段之一。但是,如果只依靠手動發送,對於行銷人員來說是一件極為費時費力的工作。所以,開發一款微信群發工具就顯得格外重要。本文將介紹如何使用PHP開發微信群發工具。一、準備工作開發微信群發工具,我們需要掌握以下幾個技術點:PHP基礎知識微信公眾平台開發開發工具:Sub

在微信公眾號開發中,使用者標籤管理是一個非常重要的功能,可以讓開發者更了解和管理自己的使用者。本篇文章將介紹如何使用PHP實作微信使用者標籤管理功能。一、取得微信用戶openid在使用微信用戶標籤管理功能之前,我們首先需要取得用戶的openid。在微信公眾號開發中,透過使用者授權的方式取得openid是比較常見的做法。在使用者授權完成後,我們可以透過以下程式碼取得用

隨著微信成為了人們生活中越來越重要的通訊工具,其敏捷的訊息傳遞功能迅速受到廣大企業和個人的青睞。對企業而言,將微信發展為一個行銷平台已經成為趨勢,而微信開發的重要性也逐漸凸顯。在其中,群發功能更是被廣泛使用,那麼,作為PHP程式設計師,如何實現群發訊息發送記錄呢?以下將為大家簡單介紹一下。 1.了解微信公眾號相關開發知識在了解如何實現群發訊息發送記錄之前,我

在微信公眾號開發中,投票功能經常被運用。投票功能是讓使用者快速參與互動的好方式,也是舉辦活動和調查意見的重要工具。本文將為您介紹如何使用PHP實作微信投票功能。在取得微信公眾號授權首先,你需要取得微信公眾號的授權。在微信公眾平台上,你需要設定微信公眾號碼的api地址、官方帳號和公眾號碼對應的token。在我們使用PHP語言開發的過程中,我們需要使用微信官方提供的PH

如何使用PHP實現微信公眾號開發微信公眾號已經成為了許多企業推廣和互動的重要管道,而PHP作為常用的Web語言,也可以用來進行微信公眾號的開發。本文將介紹使用PHP實現微信公眾號開發的具體步驟。第一步:取得微信公眾號的開發者帳號在開始微信公眾號開發之前,需要先去申請一個微信公眾號的開發者帳號。具體的註冊流程可參考微信公眾平台的官方網

微信是目前全球用戶規模最大的社群平台之一,隨著行動網路的普及,越來越多的企業開始意識到微信行銷的重要性。在進行微信行銷時,客服服務是至關重要的一環。為了更好地管理客服聊天窗口,我們可以藉助PHP語言進行微信開發。一、PHP微信開發簡介PHP是一種開源的伺服器端腳本語言,廣泛用於Web開發領域。結合微信公眾平台提供的開發接口,我們可以使用PHP語言進行微信

隨著網路和行動智慧型裝置的發展,微信成為了社交和行銷領域不可或缺的一部分。在這個越來越數位化的時代,如何使用PHP進行微信開發已經成為了許多開發者的關注點。本文主要介紹如何使用PHP進行微信發展的相關知識點,以及其中的一些技巧和注意事項。一、開發環境準備在進行微信開發之前,首先需要準備好對應的開發環境。具體來說,需要安裝PHP的運作環境,以及微信公眾平台提
