WeChat development passive reply and upload and download files

Y2J
Release: 2017-05-09 09:58:53
Original
2328 people have browsed it

Chapter 5 has already talked about how to handle messages sent by users. This chapter will talk about how to respond to user requests. Novices must be confused when they see this title. Don’t be confused. The interface of WeChat is just like this. When replying to pictures, music, voice, etc., we need to upload our media files to the WeChat server before we can use it. I don’t know what the considerations are for this approach, and the message body formats sent by the customer service interface and the group sending interface are actually different when replying to messages to users. It is estimated that these interfaces were not written by the same person, and the code was not unified. We loser developers can only complain.

Before talking about the upload and download interface, we need to first talk about the access_token acquisition method. In the process of WeChat interface development, access_token is crucial. It is the globally unique ticket of the official account. The official account needs to use access_token when calling each interface. Developers need to store it properly. At least 512 characters of space must be reserved for access_token storage. The validity period of access_token is currently 2 hours and needs to be refreshed regularly. Repeated acquisition will cause the last access_token to become invalid. It should be noted that there is only one valid access_token for an official account at the same time, and developers need to refresh the access_token before the access_token expires. During the refresh process, the public platform backend will ensure that both the old and new access_tokens are available within a short time of refresh, which ensures a smooth transition of third-party services.

The public account can use AppID and AppSecret to call this interface to obtain access_token. AppID and AppSecret can be obtained from the official website of WeChat Public Platform - Developer Center page (you need to have become a developer, and the account has no abnormal status). As shown below:

WeChat development passive reply and upload and download files

The interface address for obtaining access_token is:

https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
Copy after login
将appid和secret替换成你自己的。
Copy after login

Send a get request to this address, and the returned data is as follows:

{"access_token":"eEd6dhp0s24JfWwDyGBbrvJxnhqHTSYZ8MKdQ7MuCGBKxAjHv-tEIwhFZzn102lGvIWxnjZZreT6C1NCT9fpS7NREOkEX42yojVnqKVaicg","expires_in":7200}
Copy after login
我们只需解析这个json,即可获取到我们所需的access_token.代码如下:
Copy after login
AccessToken实体类:
Copy after login
public class AccessToken
    {        public string token { get; set; }        public DateTime expirestime { get; set; }
    }
Copy after login

Get 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;
            }

        }
Copy after login

After successfully obtaining the access_token, let’s upload and download multimedia files. The official said that when the official account uses the interface, operations such as obtaining and calling multimedia files and multimedia messages are performed through media_id (I don’t know much about reading, so I don’t understand why the URL cannot be used, but it is unnecessary to upload it to the server before sending. ). Through this interface, public accounts can upload or download multimedia files. But please note that each multimedia file (media_id) will be automatically deleted 3 days after it is uploaded and sent to the WeChat server by the user to save server resources.

The interface address for uploading multimedia is:

file.api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE
Copy after login

where access_token is the calling interface certificate, type is the media file type, including WeChat development passive reply and upload and download files, voice, VIDEO (video) and THUMBNAIL (thumb)

NOTES :

Uploaded multimedia files have format and size restrictions , as follows:

  • Picture (WeChat development passive reply and upload and download files): 1M, supports JPG format

  • Voice (voice): 2M, playback length does not exceed 60s, Support AMR\MP3 format

  • Video (video): 10MB, support MP4 format

  • Thumbnail (thumb): 64KB, support JPG format

#Media files are saved in the background for 3 days, that is, the media_id will expire after 3 days.

In order to facilitate calling, define the type of media file as an enumeration, the code is as follows:

public enum MediaType
    {        /// <summary>
        /// 图片(WeChat development passive reply and upload and download files): 1M,支持JPG格式        /// </summary>        WeChat development passive reply and upload and download files,        /// <summary>
        /// 语音(voice):2M,播放长度不超过60s,支持AMR\MP3格式        /// </summary>        voice,        /// <summary>
        /// 视频(video):10MB,支持MP4格式        /// </summary>        video,        /// <summary>
        /// 缩略图(thumb):64KB,支持JPG格式        /// </summary>        thumb
    }
Copy after login

Then define the type of the return value:

public class UpLoadInfo
    {        /// <summary>
        /// 媒体文件类型,分别有图片(WeChat development passive reply and upload and download files)、语音(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; }
    }
Copy after login

Finally use WebClient class to upload files and read out the return value. The code is as follows:

/// <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;
                }
            }
        }
Copy after login

At this point, before talking about replying to the message, two basic support interfaces have been inserted. Since your ability to organize and summarize is so bad, please read it. Please bear with me. If you have any questions, please leave a message and communicate with me. Let’s officially start talking about replying to messages. When reading the following content, please read it in conjunction with Chapters 4 and 5.

The previous two chapters talked about receiving and processing messages sent by users, and talked about a message base class BaseMessage. No matter what type of message we receive, we need to be able to call methods to respond to user requests, so , the method for users to reply to user requests needs to be encapsulated into a base class. Let’s take a brief look at the types of messages that public accounts can reply to, as well as the message formats.

Note:

Once the following situation occurs, WeChat will issue a system prompt to the user in the public account session "This public account is temporarily unavailable. Service, please try again later":

1、开发者在5秒内未回复任何内容
2、开发者回复了异常数据,比如JSON数据等
Copy after login
回复文本消息
<xml><ToUserName><![CDATA[接收方帐号(收到的OpenID)]]></ToUserName><FromUserName><![CDATA[开发者微信号]]></FromUserName><CreateTime>消息创建时间 (整型)</CreateTime><MsgType><![CDATA[WeChat development passive reply and upload and download files]]></MsgType><Content><![CDATA[回复的消息内容(换行:在content中能够换行,微信客户端就支持换行显示)]]></Content></xml>
Copy after login
回复图片消息
<xml><ToUserName><![CDATA[接收方帐号(收到的OpenID)]]></ToUserName><FromUserName><![CDATA[开发者微信号]]></FromUserName><CreateTime>消息创建时间 (整型)</CreateTime><MsgType><![CDATA[WeChat development passive reply and upload and download files]]></MsgType><Image><MediaId><![CDATA[通过上传多媒体文件,得到的id。]]></MediaId></Image></xml>
Copy after login
回复语音消息
<xml><ToUserName><![CDATA[接收方帐号(收到的OpenID)]]></ToUserName><FromUserName><![CDATA[开发者微信号]]></FromUserName><CreateTime>消息创建时间 (整型)</CreateTime><MsgType><![CDATA[voice]]></MsgType><Voice><MediaId><![CDATA[通过上传多媒体文件,得到的id。]]></MediaId></Voice></xml>
Copy after login
回复视频消息
<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>
Copy after login
回复音乐消息
<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>
Copy after login
回复图文消息
<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>
Copy after login

回复图文中,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[WeChat development passive reply and upload and download files]]></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);

        }
    }
Copy after login

上面的代码中,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
    }
Copy after login

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; }
    }
Copy after login

public void ResArticles(EnterParam param, List art)中的Articles定义如下:

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
    }
Copy after login

【相关推荐】

1.微信公众号平台源码下载

2.微信投票源码

The above is the detailed content of WeChat development passive reply and upload and download files. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template