>  기사  >  위챗 애플릿  >  WeChat 개발 수동 응답 및 파일 업로드 및 다운로드

WeChat 개발 수동 응답 및 파일 업로드 및 다운로드

Y2J
Y2J원래의
2017-05-09 09:58:532304검색

이미 5장에서 사용자가 보낸 메시지를 처리하는 방법에 대해 설명했습니다. 이번 장에서는 사용자 요청에 응답하는 방법에 대해 설명합니다. 초보자들은 이 제목을 보고 혼란스러울 것입니다. WeChat의 인터페이스는 이와 같습니다. 사진, 음악, 음성 등에 응답하려면 먼저 미디어 파일을 WeChat 서버에 업로드해야 합니다. 그것을 사용할 수 있습니다. 이 접근 방식에는 어떤 고려 사항이 있는지 잘 모르겠고, 사용자에게 메시지를 회신할 때 고객 서비스 인터페이스와 그룹 전송 인터페이스에서 보내는 메시지 본문 형식이 실제로 다릅니다. 이러한 인터페이스는 같은 사람이 작성한 것이 아니며 코드가 통합되지 않은 것으로 추정됩니다.

업로드 및 다운로드 인터페이스에 대해 이야기하기 전에 먼저 access_token 획득 방법에 대해 이야기해야 합니다. WeChat 인터페이스 개발 과정에서 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은 위챗 퍼블릭 플랫폼 공식 홈페이지 - 개발자 센터 페이지에서 받으실 수 있습니다. (개발자 자격이 있어야 하며, 계정에 비정상적인 상태가 없어야 합니다.) 아래와 같이

WeChat 개발 수동 응답 및 파일 업로드 및 다운로드

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

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

        }

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은 이미지, 음성 및 비디오를 포함한 미디어 파일 형식입니다. (동영상) 및 썸네일 (썸)

참고 :

업로드되는 멀티미디어 파일에는 다음과 같은 형식 및 크기 제한이 있습니다. :

  • 사진(이미지): 1M, JPG 형식 지원

  • 음성(음성): 2M, 재생 길이는 60초 이내, 지원 AMRMP3 형식

  • 동영상(동영상): 10MB, MP4 형식 지원

  • 썸네일(thumb): 64KB, JPG 형식 지원

미디어 파일은 3일 동안 백그라운드에 저장됩니다. 즉, media_id는 3일 후에 만료됩니다.

호출의 편의를 위해 미디어 파일의 유형을 열거형으로 정의합니다. 코드는 다음과 같습니다.

public enum MediaType
    {        /// <summary>
        /// 图片(WeChat 개발 수동 응답 및 파일 업로드 및 다운로드): 1M,支持JPG格式        /// </summary>        WeChat 개발 수동 응답 및 파일 업로드 및 다운로드,        /// <summary>
        /// 语音(voice):2M,播放长度不超过60s,支持AMR\MP3格式        /// </summary>        voice,        /// <summary>
        /// 视频(video):10MB,支持MP4格式        /// </summary>        video,        /// <summary>
        /// 缩略图(thumb):64KB,支持JPG格式        /// </summary>        thumb
    }

그런 다음 반환 값의 유형을 정의합니다.

public class UpLoadInfo
    {        /// <summary>
        /// 媒体文件类型,分别有图片(WeChat 개발 수동 응답 및 파일 업로드 및 다운로드)、语音(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;
                }
            }
        }

이 시점에서 응답 메시지에 대해 이야기하기 전에 두 가지 기본 지원 인터페이스가 삽입되었습니다. 정리력, 요약력이 너무 형편없으니 꼭 읽어주세요. 궁금한 점이 있으면 메시지를 남겨서 소통해주세요. 메시지 답장에 대해 공식적으로 이야기를 시작하겠습니다. 다음 내용을 읽으실 때에는 4장, 5장과 연계하여 읽어주시기 바랍니다.

처음 두 장에서는 사용자가 보낸 메시지를 수신하고 처리하는 방법에 대해 설명했고, 메시지 기본 클래스인 BaseMessage에 대해 설명했습니다. 수신하는 메시지 유형에 관계없이 사용자에게 응답하는 메서드를 호출할 수 있어야 합니다. 요청이므로 사용자가 사용자 요청에 응답하는 방법은 기본 클래스로 캡슐화되어야 합니다. 공개 계정이 응답할 수 있는 메시지 유형과 메시지 형식을 간략하게 살펴보겠습니다.

참고:

다음 상황이 발생하면 WeChat은 공식 계정 세션에서 사용자에게 "이 공식 계정을 일시적으로 사용할 수 없습니다"라는 시스템 메시지를 표시합니다. " 서비스를 이용하세요. 나중에 다시 시도해 주세요.":

1、开发者在5秒内未回复任何内容
2、开发者回复了异常数据,比如JSON数据等
回复文本消息
<xml><ToUserName><![CDATA[接收方帐号(收到的OpenID)]]></ToUserName><FromUserName><![CDATA[开发者微信号]]></FromUserName><CreateTime>消息创建时间 (整型)</CreateTime><MsgType><![CDATA[WeChat 개발 수동 응답 및 파일 업로드 및 다운로드]]></MsgType><Content><![CDATA[回复的消息内容(换行:在content中能够换行,微信客户端就支持换行显示)]]></Content></xml>
回复图片消息
<xml><ToUserName><![CDATA[接收方帐号(收到的OpenID)]]></ToUserName><FromUserName><![CDATA[开发者微信号]]></FromUserName><CreateTime>消息创建时间 (整型)</CreateTime><MsgType><![CDATA[WeChat 개발 수동 응답 및 파일 업로드 및 다운로드]]></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[WeChat 개발 수동 응답 및 파일 업로드 및 다운로드]]></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 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
    }

【相关推荐】

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

2.微信投票源码

위 내용은 WeChat 개발 수동 응답 및 파일 업로드 및 다운로드의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.