WeChat public platform SDK process details

Source: Internet
Author: User
Tags nested switch
Because I still use NOKIA-C5, never used, the understanding of certainly not you much, but the company has a demand, had to read interface document directly with a hard scalp. It is also interesting to see that, when a user sends a message to a public account, the program can automatically reply to the user according to the user's content, for example, if you send a waybill number to a public account of a logistics company, the other party will automatically reply to the logistics details of this waybill number. it feels cool! Service number description: it provides more powerful business services and user management capabilities for enterprises and organizations, and helps enterprises quickly implement a brand new public number service platform.

. NETSDK: Loogn. WeiXinSDK (net2.0 source code, the following code is only approximate, not correct, please download the source code yourself)

Because I still use NOKIA-C5, never used, the understanding of certainly not you much, but the company has a demand, had to read interface document directly with a hard scalp.

It is also interesting to see that, when a user sends a message to a public account, the program can automatically reply to the user according to the user's content, for example, you can send a waybill number to a public account of a logistics company,

The other party automatically replies to the logistics details of your waybill number. it feels cool! For convenience, the following information is provided:

Now the message process is basically clear. call the SDK to reply to the message as follows:

Using System. Web; using Loogn. WeiXinSDK; using Loogn. WeiXinSDK. Message; namespace WebTest {//////-> Server configuration URL ///Public class WeiXinAPI: IHttpHandler {static string Token = "Token"; // here Token is not Access_Token public void ProcessRequest (HttpContext context) {context. response. contentType = "text/plain"; var signature = context. request ["signature"]; var timestamp = context. request ["timestamp"]; var nonce = context. request ["nonce"]; if (WeiXin. checkSignature (signature, timestamp, nonce, Token) // verify that the message is sent to you {// according to the note Reply to the message and event handler in the volume. // if a message or event is not registered, ReplyEmptyMsg is returned. instance, that is, GetXML () is string. empty, compliant with the requirements var replyMsg = WeiXin. replyMsg (); var xml = replyMsg. getXML (); // WriteLog (xml); // You can view the returned XML message context. response. write (xml);} else {context. response. write ("fuck you! ") ;}} Static WeiXinAPI () {WeiXin. configGlobalCredential ("appid", "appSecret"); // register a message processing program. when the user sends "ABC", you reply "You say: ABC"; WeiXin. registerMsgHandler
 
  
(Msg) => {return new ReplyTextMsg {Content = "You said:" + msg. Content // FromUserName = msg. ToUserName. this is the default setting and does not need to be set! // ToUserName = msg. FromUserName, which is the default value and does not need to be set! // CreateTime = DateTime. Now. Ticks is set by default! } ;}); // Register an event handler that the user follows. when the user follows your public account, you reply "Hello !" WeiXin. RegisterEventHandler
  
   
(Msg) => {return new ReplyTextMsg {Content = "Hello! "};}); // You can continue to register the messages and event handlers you are interested in.} public bool IsReusable {get {return false ;}}}}
  
 

The SDK contains the encapsulation of all interfaces except (OAuth2.0 webpage authorization). the class name and method name are obvious. here we will not demonstrate them one by one. if you are interested, you can download the dll and test it on your own, this is a paid authentication interface diagram:

Next, let's talk about the implementation details:

I. credential (access_token) expired

"Access_token is the globally unique ticket of the public account. access_token is required when the public account calls each interface. Under normal circumstancesAccess_token is valid for 7200 seconds, Duplicate access will invalidate the last access_token. The public account can use AppID and AppSecret to call this interface to obtain the access_token. AppID and AppSecret can be obtained in the development mode (you need to become a developer and the account is not abnormal )."

According to the document, we can think of using the cache (it is impossible to use it every time !), The cache code is very simple, mainly inIn this case, you can thinkCache:IncompleteCode:

        access_token { ;                     expires_in { ;  Dictionary<, Credential> creds =  Dictionary<, Credential>  TokenUrl =   Credential GetCredential( appId, =  (creds.TryGetValue(appId,  (cred.add_time.AddSeconds(cred.expires_in - ) <=  json = Util.HttpGet2(= Util.JsonTo
 

II. Error code information

The code for obtaining creden is incomplete because it does not process the error code that may be returned. the error code is returned in json format, for example:

{"errcode":40013,"errmsg":"invalid appid"}

Most of the interfaces we call proactively may return error codes. the error code format is completely different from the data format normally returned. in the SDK, I handle the error code in this way. First, define the model class of the error code, here I am calling ReturnCode because the error code also contains a successful request of {"errcode": 0, "errmsg": "OK:

       errcode { ;   errmsg { ;     + errcode +  + errmsg +

When defining a response message class with an error code, we can include a ReturnCode type attribute, such as creating a QR code interface:

    public class QRCodeTicket    {        public string ticket { get; set; }        public int expire_seconds { get; set; }        public ReturnCode error { get; set; }    }

The code from the returned json to the QRCodeTicket object is like this (others are similar ):

            var json = Util.HttpPost2(url, data);            if (json.IndexOf("ticket") > 0)            {                return Util.JsonTo
 
  (json);            }            else            {                QRCodeTicket tk = new QRCodeTicket();                tk.error = Util.JsonTo
  
   (json);                return tk;            }
  
 

Therefore, after using the SDK to call the interface, the obtained object can be easily determined:

Var qrcode = WeiXin. createQRCode (true, 23); if (qrcode. error = null) {// error returned. you can use qrcode. error view error message} else {// The Returned result is correct. you can operate on qrcode. ticket}

III. deserialization

The json returned by the interface is sometimes not directly mapped to the object (the json format is too flexible !), For example, json returned after a group is created:

{    "group": {        "id": 107,         "name": "test"    }}

If you want to get the object through deserialization using json directly, the class definition of this object may be as follows:

    public class GroupInfo    {        public Group group { get; set; }        public class Group        {            public int id { get; set; }            public string name { get; set; }        }    }

The access will also be gp. group. name, so I am not very direct. the class we want must be defined as the previous subclass:

    public class GroupInfo    {            public int id { get; set; }            public string name { get; set; }    }

If the interface returns the following:

    {        "id": 107,         "name": "test"    }

It would be better, but we cannot modify the code. we only have to find a solution.

1. do you want to define a simple class, 2 do not manually analyze json (such as regular expressions), and 3. do you want to define another class? do you think of a good method? If yes, you can reply to me, and I choose to use the dictionary for intermediate conversion.

BecauseBasically all json formats can be deserialized into dictionaries.(Nested dictionary, nested dictionary set, etc.). For example, the json returned above can be represented by the following types:

Dictionary
 
  >
 

Json ---> dict ---> GroupInfo

var dict = Util.JsonTo
 
  >>(json);var gi = new GroupInfo();var gpdict = dict["group"];gi.id = Convert.ToInt32(gpdict["id"]);gi.name = gpdict["name"].ToString();
 

IV. Optimization of message processing

"Everything is simple and beautiful", I am a very simple programmer. Remember the first message (the event is a message, which is collectively referred to as a message). I think it is very simple. Register the processing program for the message that needs to be processed. However, this is not the case at the beginning. you must manually determine the message type at the beginning, just like:

Using System. Web; using Loogn. WeiXinSDK; using Loogn. WeiXinSDK. Message; namespace WebTest {//////-> Server configuration URL ///Public class WeiXinAPI: IHttpHandler {static string Token = "Token"; // here Token is not Access_Token public void ProcessRequest (HttpContext context) {context. response. contentType = "text/plain"; var signature = context. request ["signature"]; var timestamp = context. request ["timestamp"]; var nonce = context. request ["nonce"]; if (WeiXin. checkSignature (signature, timestamp, nonce, Token) // verify that the message is sent to you {var r EplyMsg = WeiXin. replyMsg (recEvtMsg) => {switch (recEvtMsg. msgType) {case MsgType. text: {var msg = recEvtMsg as RecTextMsg; // here the transformation is required. Please return new ReplyTextMsg {Content = "You said:" + msg. content };} case MsgType. event: {var evtMsg = recEvtMsg as EventBaseMsg; // The basic Event message to be transformed here, so switch (evtMsg. myEventType) {case MyEventType. attend: var msg = evtMsg as EventAttendMsg; // In this example, this line of code is not required, but other code to be converted to message content is still required. Annoying return new ReplyTextMsg {Content = "Hello! "}; Default: break;} return ReplyEmptyMsg. instance; // nested switch, and each case has several, which is not elegant}); var xml = replyMsg. getXML (); // WriteLog (xml); // You can view the returned XML message context. response. write (xml);} else {context. response. write ("fuck you! ") ;}} Public bool IsReusable {get {return false ;}}}}

When optimizing, first try to see if you can post on MsgType and MyEventType. for example, when registering, input the MsgType and the processing program (lamba) parameters:

public static void RegisterMsgHandler(MsgType type, Func
 
   handler){    //add handler}
 

This is indeed feasible, but you still need to manually convert the type when calling the SDK registration:

 WeiXin.RegisterMsgHandler(MsgType.text, (recEvtMsg) => msg = recEvtMsg   ReplyTextMsg { Content =  +

Can I write one for each subtype?

    public static void RegisterMsgHandler(MsgType type, Func
 
   handler)    {        //add handler    }    public static void RegisterMsgHandler(MsgType type, Func
  
    handler)    {        //add handler    }    //.............
  
 

The definition is acceptable. let's take a look at the call:

// RegisterMsgHandler (MsgType. text, new Func
 
  
(Msg) =>{ return new ReplyTextMsg {Content = "You said:" + msg. Content };}); // RegisterMsgHandler (MsgType. text, new Func
  
   
(Msg) => {return new ReplyTextMsg {Content = "your image:" + msg. picUrl };})); // Yes. Note that the msg smart prompt is RecTextMsg type RegisterMsgHandler (MsgType. text, (msg) => {return new ReplyTextMsg {Content = "You said:" + msg. content };}); // Yes. Note that the msg smart prompt is still the RecTextMsg type, but the type inference is used. the RecImageMsg type can be determined during running, so RegisterMsgHandler (MsgType. text, (msg) =>{ return new ReplyTextMsg {Content = "your image:" + msg. picUrl };}); // No. Note that the msg smart prompt is still of the RecTextMsg type, but the attributes of the specific subclass of msg are not used in the lamba body, and the type cannot be inferred, so the call to RegisterMsgHandler (MsgType. text, (msg) =>{ return new ReplyTextMsg {Content = "You sent a message "};});
  
 

From the above call, we can see that if you want to call this method, you cannot use lamba expressions at will! Finally, the generic model is used.

public static void RegisterMsgHandler
 
  (Func
  
    handler) where TMsg : RecBaseMsg        {            var type = typeof(TMsg);            var key = string.Empty;            if (type == typeof(RecTextMsg))            {                key = MsgType.text.ToString();            }            else if (type == typeof(RecImageMsg))            {                key = MsgType.image.ToString();            }            else if (type == typeof(RecLinkMsg))            {                key = MsgType.link.ToString();            }            else if (type == typeof(RecLocationMsg))            {                key = MsgType.location.ToString();            }            else if (type == typeof(RecVideoMsg))            {                key = MsgType.video.ToString();            }            else if (type == typeof(RecVoiceMsg))            {                key = MsgType.voice.ToString();            }            else            {                return;            }            m_msgHandlers[key] = (Func
   
    )handler;        }
   
  
 

After this transformation, we can register with simple lamba expressions as we started.

The above is a detailed explanation of the public platform SDK process. For more information, see other related articles on php Chinese network!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.