Heim  >  Artikel  >  WeChat-Applet  >  WeChat-Entwicklung zum Empfangen von Textnachrichten

WeChat-Entwicklung zum Empfangen von Textnachrichten

Y2J
Y2JOriginal
2017-05-09 09:43:212467Durchsuche

Die Nachrichtentypen in WeChat sind: Text, Bild, Sprache, Video, geografischer Standort, Link und Ereignisnachricht. Mit Ausnahme der Ereignisnachrichten werden die anderen zusammenfassend als gewöhnliche Nachrichten bezeichnet. Der Push und die Antwort von Nachrichten in WeChat werden in XML-Datenpaketen übertragen. Wenn ein Benutzer eine Nachricht an ein offizielles Konto sendet und der WeChat-Server innerhalb von fünf Sekunden keine Antwort erhält, wird die Verbindung getrennt und die Anfrage erneut gestartet, wobei insgesamt drei Wiederholungsversuche erforderlich sind . Gewöhnliche Nachrichten können mit msgid dedupliziert werden, um die Auswirkungen doppelter Nachrichten auf die Geschäftslogik zu vermeiden.

Wenn der Server nicht garantieren kann, dass er innerhalb von fünf Sekunden verarbeitet und antwortet, können Sie direkt mit einer leeren Zeichenfolge antworten. Der WeChat-Server wird diese Anfrage nicht verarbeiten und keinen erneuten Versuch einleiten. Es ist zu beachten, dass die Antwort auf die hier erwähnte leere Zeichenfolge nicht darin besteht, auf eine leere Textnachricht zu antworten, sondern direkt auf Response.Write("") zu antworten.

Im Folgenden finden Sie eine kurze Erläuterung der einzelnen häufigen Meldungen.

Textnachricht:
<xml>
 <ToUserName><![CDATA[toUser]]></ToUserName>
 <FromUserName><![CDATA[fromUser]]></FromUserName> 
 <CreateTime>1348831860</CreateTime>
 <MsgType><![CDATA[text]]></MsgType>
 <Content><![CDATA[this is a test]]></Content>
 <MsgId>1234567890123456</MsgId>
 </xml>
Bildnachricht:
<xml>
 <ToUserName><![CDATA[toUser]]></ToUserName>
 <FromUserName><![CDATA[fromUser]]></FromUserName>
 <CreateTime>1348831860</CreateTime>
 <MsgType><![CDATA[image]]></MsgType>
 <PicUrl><![CDATA[this is a url]]></PicUrl>
 <MediaId><![CDATA[media_id]]></MediaId>
 <MsgId>1234567890123456</MsgId>
 </xml>
Sprachnachricht:
<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>1357290913</CreateTime><MsgType><![CDATA[voice]]></MsgType><MediaId><![CDATA[media_id]]></MediaId><Format><![CDATA[Format]]></Format><MsgId>1234567890123456</MsgId></xml>
Videonachricht:
<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>1357290913</CreateTime><MsgType><![CDATA[video]]></MsgType><MediaId><![CDATA[media_id]]></MediaId><ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId><MsgId>1234567890123456</MsgId></xml>
Geolocation-Nachricht:
<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>1351776360</CreateTime><MsgType><![CDATA[location]]></MsgType><Location_X>23.134521</Location_X><Location_Y>113.358803</Location_Y><Scale>20</Scale><Label><![CDATA[位置信息]]></Label><MsgId>1234567890123456</MsgId></xml>
Link Nachricht:
<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>1351776360</CreateTime><MsgType><![CDATA[link]]></MsgType><Title><![CDATA[公众平台官网链接]]></Title><Description><![CDATA[公众平台官网链接]]></Description><Url><![CDATA[url]]></Url><MsgId>1234567890123456</MsgId></xml>

Sorgfältige Programmierer sollten entdeckt haben, dass alle Nachrichten (einschließlich Ereignisnachrichten) die folgenden Felder enthalten

参数 描述
ToUserName 接收方微信号
FromUserName 发送方微信号,若为普通用户,则是一个OpenID
CreateTime 消息创建时间
MsgType 消息类型

Und die Nachricht Die Typen wurden am erwähnt Am Anfang des Artikels sind dies: Text, Bild, Sprache, Video, Standort, Link, Ereignis

Um die Verwaltung und das Schreiben von Code zu erleichtern, können wir eine Aufzählung für diese Nachrichtentypen schreiben. Wie folgt:

/// <summary>
    /// 消息类型枚举    /// </summary>
    public enum MsgType
    {        /// <summary>
        ///文本类型        /// </summary>        TEXT,        /// <summary>
        /// 图片类型        /// </summary>        IMAGE,        /// <summary>
        /// 语音类型        /// </summary>        VOICE,        /// <summary>
        /// 视频类型        /// </summary>        VIDEO,        /// <summary>
        /// 地理位置类型        /// </summary>        LOCATION,        /// <summary>
        /// 链接类型        /// </summary>        LINK,        /// <summary>
        /// 事件类型        /// </summary>        EVENT
    }

Lassen Sie mich hier erklären, dass „event“ ein Schlüsselwort in C# ist, sodass „event“ nicht in Aufzählungen verwendet werden kann. Aus Gründen der Einheitlichkeit verwende ich hier für die Aufzählungen ausschließlich Großbuchstaben.

Da alle Nachrichtentexte über die oben genannten Felder verfügen, können Sie eine Basisklasse schreiben und dann verschiedene Nachrichtenentitäten diese Basisklasse erben . (Ich habe mit einem Problem zu kämpfen. Früher habe ich alle Felder im Nachrichtentext in eine Klasse geschrieben, was sehr bequem aufzurufen ist. Es gibt jedoch immer mehr Felder in der Klasse, was mir unangenehm ist. Darüber hinaus Ich habe wenig Talent und Wissen und bin nicht in der Lage, objektorientiert

zu verwenden. Deshalb liste ich beim direkten Aufruf von var ss = WeiXinRequest immer alle Felder in einer Klasse auf

. RequestHelper(token, EncodingAESKey, appid ; Die Lesbarkeit wurde verbessert, aber der Aufruf ist nicht mehr so ​​bequem wie zuvor. Freunde, bitte geben Sie mir einige Vorschläge

)

Das Folgende sind die Basisklassen jeder Nachrichtenentität:

Die Basisklasse definiert die öffentlichen Felder des Nachrichtentexts und die virtuellen Methoden, die zum Antworten auf Benutzeranfragen verwendet werden (die Antwortnachricht steht nicht im Mittelpunkt dieses Artikels). Daher wird der Methodenkörper nicht veröffentlicht. Bitte beachten Sie den Folgeartikel.

Einer der Parameter der Methode in der Basisklasse ist vom Typ EnterParam. Diese Klasse ist der Parameter, der verwendet werden muss, wenn der Benutzer auf die Nachricht zugreift und deren Authentizität überprüft, einschließlich Token, Verschlüsselungsschlüssel. appid usw. Die Definition lautet wie folgt:

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)
        {            
        }        /// <summary>
        /// 回复消息(音乐)        /// </summary>
        public  void ResMusic(EnterParam param, Music mu)
        {
        }        public  void ResVideo(EnterParam param, Video v)
        {        }        /// <summary>
        /// 回复消息(图片)        /// </summary>
        public  void ResPicture(EnterParam param, Picture pic, string domain)
        {
}        /// <summary>
        /// 回复消息(图文列表)        /// </summary>
        /// <param name="param"></param>
        /// <param name="art"></param>
        public  void ResArticles(EnterParam param, List<Articles> art)
        {        }        /// <summary>
        /// 多客服转发        /// </summary>
        /// <param name="param"></param>
        public  void ResDKF(EnterParam param)
        {
}        /// <summary>
        /// 多客服转发如果指定的客服没有接入能力(不在线、没有开启自动接入或者自动接入已满),该用户会一直等待指定客服有接入能力后才会被接入,而不会被其他客服接待。建议在指定客服时,先查询客服的接入能力指定到有能力接入的客服,保证客户能够及时得到服务。        /// </summary>
        /// <param name="param">用户发送的消息体</param>
        /// <param name="KfAccount">多客服账号</param>
        public  void ResDKF(EnterParam param, string KfAccount)
        {        }        private  void Response(EnterParam param, string data)
        {            
        }
    }
Textentität:

Bildentität:

/// <summary>
    /// 微信接入参数    /// </summary>
    public class EnterParam
    {        /// <summary>
        /// 是否加密        /// </summary>
        public bool IsAes { get; set; }        /// <summary>
        /// 接入token        /// </summary>
        public string token { get; set; }        /// <summary>
        ///微信appid        /// </summary>
        public string appid { get; set; }        /// <summary>
        /// 加密密钥        /// </summary>
        public string EncodingAESKey { get; set; }
    }

Sprachentität:

public class TextMessage:BaseMessage
    {       /// <summary>
       /// 消息内容       /// </summary>
        public string Content { get; set; }       /// <summary>
        /// 消息id,64位整型       /// </summary>
        public string MsgId { get; set; }

    
    }

Video-Entität:

public class ImgMessage : BaseMessage
    {       /// <summary>
       /// 图片路径       /// </summary>
        public string PicUrl { get; set; }       /// <summary>
        /// 消息id,64位整型       /// </summary>
        public string MsgId { get; set; }        /// <summary>
        /// 媒体ID        /// </summary>
        public string MediaId { get; set; }

     
    }

Link-Entität:

public class VoiceMessage : BaseMessage
    {       /// <summary>
       /// 缩略图ID       /// </summary>
        public string MsgId { get; set; }       /// <summary>
        /// 格式       /// </summary>
        public string Format { get; set; }        /// <summary>
        /// 媒体ID        /// </summary>
        public string MediaId { get; set; }        /// <summary>
        /// 语音识别结果        /// </summary>
        public string Recognition { get; set; }

    
    }

Nachdem die Nachrichtenentität definiert wurde, besteht der nächste Schritt darin, den vom WeChat-Server übertragenen Nachrichtentext in die entsprechende Entität zu analysieren . Ich hatte geplant, die mit C# gelieferte XML-Serialisierung zu verwenden, um serialisierte Komponenten zu senden, aber als ich es ausprobiert habe, habe ich immer einen XML-Fehler gemeldet, also habe ich einfach eine Verarbeitungsmethode mit Reflektion geschrieben:

public class VideoMessage : BaseMessage
    {       /// <summary>
       /// 缩略图ID       /// </summary>
        public string ThumbMediaId { get; set; }       /// <summary>
        /// 消息id,64位整型       /// </summary>
        public string MsgId { get; set; }        /// <summary>
        /// 媒体ID        /// </summary>
        public string MediaId { get; set; }

    
    }

Methode für XML verarbeiten Nach der Definition geht es im Folgenden um das Parsen der entsprechenden Entitäten nach verschiedenen Nachrichtentypen:

public class LinkMessage : BaseMessage
    {       /// <summary>
       /// 缩略图ID       /// </summary>
        public string MsgId { get; set; }       /// <summary>
        /// 标题       /// </summary>
        public string Title { get; set; }        /// <summary>
        /// 描述        /// </summary>
        public string Description { get; set; }        /// <summary>
        /// 链接地址        /// </summary>
        public string Url { get; set; }

     
    }

Die CreateMessage-Methode übergibt das Datenpaket (wenn es verschlüsselt ist, muss es entschlüsselt und übergeben werden). in Form einer Basisklasse Gibt die entsprechende Entität zurück.

public static T ConvertObj<T>(string xmlstr)
        {
            XElement xdoc = XElement.Parse(xmlstr);            var type = typeof(T);            var t = Activator.CreateInstance<T>();            foreach (XElement element in xdoc.Elements())
            {                var pr = type.GetProperty(element.Name.ToString());                if (element.HasElements)
                {//这里主要是兼容微信新添加的菜单类型。nnd,竟然有子属性,所以这里就做了个子属性的处理                    foreach (var ele in element.Elements())
                    {
                        pr = type.GetProperty(ele.Name.ToString());
                        pr.SetValue(t, Convert.ChangeType(ele.Value, pr.PropertyType), null);
                    }                    continue;
                }                if (pr.PropertyType.Name == "MsgType")//获取消息模型
                {
                    pr.SetValue(t, (MsgType)Enum.Parse(typeof(MsgType), element.Value.ToUpper()), null);                    continue;
                }                if (pr.PropertyType.Name == "Event")//获取事件类型。
                {
                    pr.SetValue(t, (Event)Enum.Parse(typeof(Event), element.Value.ToUpper()), null);                    continue;
                }
                pr.SetValue(t, Convert.ChangeType(element.Value, pr.PropertyType), null);
            }            return t;
        }
Wir sind hier fast fertig mit der Diskussion über den Empfang gewöhnlicher Nachrichten. In Kombination mit dem vorherigen Blog-Beitrag wird der geänderte Zugangscode nun wie folgt veröffentlicht:

public class MessageFactory
    {        public static BaseMessage CreateMessage(string xml)
        {
            XElement xdoc = XElement.Parse(xml);            var msgtype = xdoc.Element("MsgType").Value.ToUpper();
            MsgType type = (MsgType)Enum.Parse(typeof(MsgType), msgtype);            switch (type)
            {                case MsgType.TEXT: return Utils.ConvertObj<TextMessage>(xml);                case MsgType.IMAGE: return Utils.ConvertObj<ImgMessage>(xml);                case MsgType.VIDEO: return Utils.ConvertObj<VideoMessage>(xml);                case MsgType.VOICE: return Utils.ConvertObj<VoiceMessage>(xml);                case MsgType.LINK:                    return Utils.ConvertObj<LinkMessage>(xml);                case MsgType.LOCATION:                    return Utils.ConvertObj<LocationMessage>(xml);                case MsgType.EVENT://事件类型                {
                    
                } break;                default:                    return Utils.ConvertObj<BaseMessage>(xml);
            }
        }
    }
[Verwandte Empfehlungen]

1.

Quellcode der WeChat-Plattform für öffentliche Konten herunterladen

public class WxRequest
    {       public static BaseMessage Load(EnterParam param, bool bug = true)
       {           string postStr = "";
           Stream s = VqiRequest.GetInputStream();//此方法是对System.Web.HttpContext.Current.Request.InputStream的封装,可直接代码
           byte[] b = new byte[s.Length];
           s.Read(b, 0, (int)s.Length);
           postStr = Encoding.UTF8.GetString(b);//获取微信服务器推送过来的字符串
           var timestamp = VqiRequest.GetQueryString("timestamp");           var nonce = VqiRequest.GetQueryString("nonce");           var msg_signature = VqiRequest.GetQueryString("msg_signature");           var encrypt_type = VqiRequest.GetQueryString("encrypt_type");           string data = "";           if (encrypt_type=="aes")//加密模式处理           {
               param.IsAes = true;               var ret = new MsgCrypt(param.token, param.EncodingAESKey, param.appid);               int r = ret.DecryptMsg(msg_signature, timestamp, nonce, postStr, ref data);               if (r != 0)
               {
                   WxApi.Base.WriteBug("消息解密失败");                   return null;

               }
           }           else
           {
               param.IsAes = false;
               data = postStr;
           }           if (bug)
           {
               Utils.WriteTxt(data);
           }           return MessageFactory.CreateMessage(data);
       }
    }

2.

WeChat Lala Takeout 2.2.4 entschlüsselte Open-Source-Version des WeChat Rubik's Cube-Quellcodes

Das obige ist der detaillierte Inhalt vonWeChat-Entwicklung zum Empfangen von Textnachrichten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn