First, overview:
If only the input box, it may be too simple to feel like a command line. Custom menus provide us with a lot of flexibility and more in line with the user's operating habits. In a small micro-letter Dialogue page, you can achieve more functionality. Menu intuitive, not only to provide event response, but also support URL jump, if the need for more complex functions, we can use the URL jump, jump to our web page can be.
Note: Custom menus, only service numbers are available for this function
Then we'll explain how to implement a custom menu?
Second, detailed steps:
1. Get Access_token First
Access_token is the public number's globally unique ticket, the public number calls each interface to use the Access_token. Under normal circumstances Access_token is valid for 7,200 seconds, and repeated acquisition will cause the last acquired access_token to fail.
The public number can use AppID and Appsecret to invoke this interface to obtain the Access_token. AppID and Appsecret can be obtained in development mode (need to be a developer and account is not in an abnormal state). Note The HTTPS protocol is required to invoke all micro-interfaces.
Interface Call Request Description
HTTP request mode: Get
Https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
Parameter description
Parameters |
whether you must |
Description |
Grant_type |
Is |
Get Access_token Fill client_credential |
AppID |
Is |
Unique credentials for third party users |
Secret |
Is |
Third-party user unique voucher key, both Appsecret |
Return description
Normally, the micro-letter will return the following JSON packet to the public number:
{"Access_token": "Access_token", "expires_in": 7200}
Parameters |
Description |
Access_token |
The voucher that was obtained |
Expires_in |
Voucher valid time, in units: seconds |
Return description
Normally, the micro-letter will return the following JSON packet to the public number:
{"Access_token": "Access_token", "expires_in": 7200}
Parameters |
Description |
Access_token |
The voucher that was obtained |
Expires_in |
Voucher valid time, in units: seconds |
In the case of an error, the micro-letter returns information such as the error code, and the JSON packet example is as follows (the example is an AppID invalid error):
2. Create a custom menu
Custom menus Help the public number to enrich the interface, allowing users to better and faster understand the function of the public number. When you open a custom menu, the public number screen looks like this:
Currently, custom menus include up to 3 levels of menus, and each level menu contains up to 5 levels of two menus. The first level menu up to 4 characters, two level menu up to 7 characters, the more out of the part will be "..." instead. Note that when you create a custom menu, a 24-hour micro-credit client is required to be displayed due to the micro-client cache. When it is recommended that you try to cancel the attention of the public account after the test, you can see the effect after the creation.
The current custom menu interface can implement two types of buttons, as follows:
Click:
After the user clicks the Click Type button, the micro-trust server will push the message type to the developer (Reference Message Interface Guide) via the message interface, and with the key value that the developer fills in the button, the developer can interact with the user through the custom key value.
View
The user clicks the View Type button, the micro-letter client will open the developer to fill in the button the URL value (namely the webpage link), achieves opens the webpage the goal, proposed with the webpage authorization obtains the user basic information interface union, obtains the user the login personal information.
Interface Call Request Description
HTTP request mode: POST (please use HTTPS protocol) Https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN
Request sample
{"
button": [
{
"type": "Click",
"name": "Today's song",
"key": "V1001_today_music"
},
{
" Type ': ' Click ',
' name ': ' Profile of singer ',
' key ': ' V1001_today_singer '
},
{
' name ': ' Menu ',
' sub_ Button ': [
{
' type ': ' View ',
' name ': ' Search ',
' url ': ' http://www.soso.com/'
},
{
' Type ': ' View ',
' name ': ' Video ',
' url ': ' http://v.qq.com/'
},
{
' type ': ' Click ',
' name ': "Praise Us",
"key": "V1001_good"}]}
]
}
Parameter description
Parameters |
whether you must |
Description |
button |
Is |
The first level menu array, the number should be 1~3 |
Sub_button |
Whether |
Two-level menu array, the number should be 1~5 |
Type |
Is |
Menu response action type, currently has click, view two types of |
Name |
Is |
Menu title, no more than 16 bytes, submenu no more than 40 bytes |
Key |
The Click Type must |
Menu key value, for message interface push, no more than 128 bytes |
Url |
The view type must be |
Web links, users click on the menu to open the link, no more than 256 bytes |
return results
The correct return of the JSON packet is as follows:
{"Errcode": 0, "errmsg": "OK"}
Error returns the JSON packet as follows (example is invalid menu name length):
{"Errcode": 40018, "errmsg": "Invalid button name size"}
3. Query Menu
With interfaces to create custom menus, developers can also use interfaces to query the structure of custom menus.
Request Description
HTTP request mode: Get
Https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN
Return description
Corresponding to the Create interface, the correct JSON returns the result:
{"Menu": {"button": [{"Type": "click", "Name": "Today's Song", "Key": "V1001_today_music", "Sub_button": []},{"Type": "Click", " Name ": Singer Profile", "Key": "V1001_today_singer", "Sub_button": []},{"Name": "Menu", "Sub_button": [{"Type": "View", "name": "Search" , "url": "http://www.soso.com/", "Sub_button": []},{"type": "View", "Name": "Video", "url": "http://v.qq.com/", "Sub_button ": []},{" Type ":" click "," Name ":" Praise Us "," Key ":" V1001_good "," Sub_button ": []}]}
4, delete the menu
After creating a custom menu using an interface, developers can also use the interface to remove the currently used custom menu.
Request Description
HTTP request mode: Get
Https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN
Return description
corresponding to the Create interface, the correct JSON returns the result:
{"Errcode": 0, "errmsg": "OK"}
5. Event handling
When the user clicks on the custom menu, if the menu button is set to click Type, the micro-letter pushes the Click event to the developer, noting that the menu click of the view type (jump to URL) is not reported.
Push XML Packet Sample:
<xml>
<tousername><![ Cdata[touser]]></tousername>
<fromusername><![ cdata[fromuser]]></fromusername>
<CreateTime>123456789</CreateTime>
<msgtype ><! [cdata[event]]></msgtype>
<event><![ Cdata[click]]></event>
<eventkey><![ Cdata[eventkey]]></eventkey>
</xml>
Parameter description:
Parameters |
Description |
Tousername |
developer Micro-signal |
Fromusername |
Sender account (an OpenID) |
Createtime |
Message creation time (integer) |
Msgtype |
Message type, Event |
Event |
Event Type, CLICK |
Eventkey |
Event key value, corresponding to key value in custom menu interface
|
Third, the example explanation
And then in an article about. Micro-Credit Public Account development Tutorial (iii) Introduction to the example: Robot (with source code)
We will add the custom menu functionality based on the previous article.
1. Get Access_token
First you need to get AppID and Appsecret.
When you become a developer, you can naturally see these two values in the developer mode, and you can reset them.
The call is then followed by the action shown in two. 1.
Note: The Access_token has an expiration date and will need to be retrieved if it expires.
The code is as follows:
private static DateTime Getaccesstoken_time;
<summary>///Expiration Time is 7,200 seconds///</summary> private static int expires_period = 7200;
<summary>//////</summary> private static string Maccesstoken; <summary>//////</summary> public static string Accesstoken {get {//if empty, or expired, need to regain Takes the if (string. IsNullOrEmpty (Maccesstoken) | |
Hasexpired ()) {//Get Maccesstoken = Getaccesstoken (AppID, Appsecret);
return maccesstoken; }///<summary>//////</summary>///<param name= "appId" ></param>///<param N Ame= "Appsecret" ></param>///<returns></returns> private static string Getaccesstoken (String app Id, String appsecret) {string url = string. Format ("Https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}",
AppId, Appsecret);
string result = Httputility.getdata (URL); XDocument doc = Xmlutility.parsejson (result, "root"); XElement root = Doc.
Root; if (root!= null) {XElement Access_token = root.
Element ("Access_token");
if (Access_token!= null) {getaccesstoken_time = DateTime.Now; if (root. Element ("expires_in")!=null) {expires_period = Int. Parse (Root. Element ("expires_in").
Value); Return Access_token.
Value;
else {getaccesstoken_time = Datetime.minvalue;
} return null; ///<summary>///To determine if Access_token is expired///</summary>///<returns>bool</returns> privat e static bool Hasexpired () {if (getaccesstoken_time!= null) {//Expiration time, allow a certain error, one minute. Gets the time consumption if (DateTime.Now > Getaccesstoken_time.addseconds (expires_period).
AddSeconds ( -60)) {return true;
return false;
}
2. Set Menu
The menu needs to be set according to the actual requirements.
Here we provide weather query function, will be used to list the city, click can be queried.
Then also provides the link, here provides the view type menu, can jump directly to the URL page, for the jump to do a good demo.
The specific menu is as follows:
{'
button ': [
{
' name ': ' Link ',
' Sub_button ': [
{
' type ': ' View ',
' name ': ' Search ',
' url ' : "http://www.baidu.com/"
},
{
"type": "View",
"name": "Video",
"url": "http://v.qq.com/"
},
{
"type": "Click",
"name": "Praise Us",
"key": "Btn_good"
}
]
},
{
"name": "Query Weather",
"Sub_button": [
{
"type": "Click",
"name": "Wuhan",
"key": "Btn_tq_ WUHAN "
},
{
" type ":" Click ",
" name ":" Shanghai ",
" key ":" Btn_tq_shanghai "
},
{
' Type ': ' Click ', '
name ': ' Beijing ',
' key ': ' Btn_tq_beijing '
}
]
},
{
' type ': ' Click ' ,
"name": "Help",
"key": "Btn_help"
}
]
}
3, Management menu
Because the menu changes are not so frequent, the TXT file is used to set the menu and manage the menu through the admin interface.
The main management functions:
1 loading menu from file
2) Create a menu. Notify the micro-service side of the menu and update to the micro-credit client
3) Query menu. Gets the menu for the current system.
4) Delete the menu. Delete a menu from a micro-trust server, or delete it and then create it.
The implementation code is as follows:
public class Menumanager {///<summary>///menu file path///</summary> private static readonly string Me
Nu_data_path = System.AppDomain.CurrentDomain.BaseDirectory + "/data/menu.txt"; <summary>///Get menu///</summary> public static string GetMenu () {string url = string.
Format ("https://api.weixin.qq.com/cgi-bin/menu/get?access_token={0}", Context.accesstoken);
return Httputility.getdata (URL); ///<summary>///Create menu///</summary> public static void CreateMenu (String menu) {String url = String.
Format ("https://api.weixin.qq.com/cgi-bin/menu/create?access_token={0}", Context.accesstoken);
String menu = Fileutility.read (Menu_data_path);
Httputility.sendhttprequest (URL, menu); ///<summary>///Delete menu///</summary> public static void DeleteMenu () {string url = string.
Format ("https://api.weixin.qq.com/cgi-bin/menu/delete?access_token={0}", Context.accesstoken); HttpUtility.
GetData (URL); ///<summary>///Load menu///</summary>///<returns></returns> public static string Loa
Dmenu () {return fileutility.read (Menu_data_path);
}
}
4. Basic methods
The above code, in fact, we have a number of public functions to do the encapsulation. such as GET request, post submission, etc., read files, etc.
Here we provide the method case code for Get, post submission, if used, recommend optimization.
Using System;
Using System.IO;
Using System.Net;
Using System.Text;
Using System.Web; namespace Yank.WeiXin.Robot.Utility {///<summary>///HTTP Help class///</summary> class HttpUtility {/// <summary>///Send request///</summary>///<param name= "url" >url address </param>///<param name= " Data > </param> public static string sendhttprequest (string URL, string data) {return sendposthttpreques
T (URL, "application/x-www-form-urlencoded", data); ///<summary>//////</summary>///<param name= "url" ></param>///<returns>&l t;/returns> public static string GetData (string url) {return sendgethttprequest (URL, "Application/x-www-form-url
Encoded "); ///<summary>///Send request///</summary>///<param name= "url" >url address </param>///<par Am Name= "Method" > Methods (Post or get) </param>///<param name= "approach" > Data type </param>///<param Name= "RequestData" > Data </param> public static string Sendposthttprequest (String url,string contenttype,string
RequestData) {WebRequest request = (WebRequest) httpwebrequest.create (URL); Request.
method = "POST";
byte[] postbytes = null; Request.
ContentType = ContentType;
Postbytes = Encoding.UTF8.GetBytes (RequestData); Request.
ContentLength = Postbytes.length; using (Stream OutStream = Request. GetRequestStream ()) {OutStream.
Write (postbytes, 0, postbytes.length); string result = String.
Empty; using (WebResponse response = Request. GetResponse ()) {if (response!= null) {using (Stream stream = response. GetResponseStream ()) {using (StreamReader reader = new StreamReader (stream, Encoding.UTF8)) {res Ult = reader.
ReadToEnd ();
}}} return result; ///<summary>///Send request///</summary>///<param name= "url" >url address </param>///<pAram Name= "Method" > Methods (Post or get) </param>///<param name= ' method ' > Data type </param>///<param name = "RequestData" > Data </param> public static string sendgethttprequest (string url, string contentType) {Webreq
Uest request = (WebRequest) httpwebrequest.create (URL); Request.
method = ' Get '; Request.
ContentType = ContentType; string result = String.
Empty; using (WebResponse response = Request. GetResponse ()) {if (response!= null) {using (Stream stream = response. GetResponseStream ()) {using (StreamReader reader = new StreamReader (stream, Encoding.UTF8)) {res Ult = reader.
ReadToEnd ();
}}} return result;
}
}
}
Using System;
Using System.Xml.Linq;
Using Newtonsoft.json;
Namespace Yank.WeiXin.Robot.Utility
{
class xmlutility
{
///<summary>
///
///</ summary>
///<param name= "JSON" ></param>
///<param name= "Rootname" ></param>
///<returns></returns> public
static XDocument Parsejson (String json,string rootname)
{ Return
Jsonconvert.deserializexnode (JSON, rootname);}}
5. Event handling
The menu is set, and the event needs to be handled. As we have previously designed aspx or WinForm, we have to bind the events of the button. This only passes the request through an XML message.
By "2, set menu" in the specific menu content, we already know what needs to be done to deal with. For a view of the button type, it will automatically jump to the specified URL without processing.
Click events that need to be handled:
1) Praise
2 Check the weather of a city, Beijing, Shanghai, Wuhan
3) Help
This also uses the event handler EventHandler in the previous chapter to extend the processing.
The specific implementation code bar:
Using System;
Using System.Collections.Generic;
Using System.Linq;
Using System.Text;
Using Yank.WeiXin.Robot.Messages; XML///for namespace Yank.WeiXin.Robot.Handlers {class Eventhandler:ihandler {///<summary>///requests
Mary> private string RequestXML {get; set;} <summary>///Constructor///</summary>///<param name= "RequestXML" ></param> public Eventha Ndler (String requestxml) {this.
RequestXML = RequestXML; ///<summary>///processing request///</summary>///<returns></returns> public string handlerequ EST () {string response = string.
Empty;
Eventmessage em = eventmessage.loadfromxml (RequestXML); if (em!= null) {switch (EM).
Event.tolower ()) {case ("subscribe"): Response = Subscribeeventhandler (EM);
Break
Case "click": Response = ClickEventHandler (EM);
Break
} return response; ///<summary>///concerns///≪/summary>///<param name= "em" ></param>///<returns></returns> private String Subscrib
Eeventhandler (eventmessage em) {//Reply welcome Message TextMessage TM = new TextMessage (); Tm. Tousername = em.
Fromusername; Tm. Fromusername = em.
Tousername; Tm.
Createtime = Common.getnowtime (); Tm. Content = "Welcome your attention * * * *, I am a mobile phone, something asked me, hehe!"
\ n '; Return TM.
Generatecontent (); ///<summary>///Processing Click events///</summary>///<param name= "em" ></param>///<returns& Gt;</returns> private String ClickEventHandler (Eventmessage em) {string result = string.
Empty; if (em!= null && em. Eventkey!= null) {switch (em.
Eventkey.toupper ()) {case ' btn_good ': result = Btngoodclick (EM);
Break
Case "btn_tq_beijing": result = Searchweather ("BEIJING", EM);
Break
Case "Btn_tq_shanghai": result = Searchweather ("Shanghai", EM);
Break
Case "Btn_tq_wuhan": result = Searchweather ("Wuhai", EM);
Break
Case "Btn_help": result = Btnhelpclick (EM);
Break
} return result; ///<summary>///Praise///</summary>///<param name= "em" ></param>///<returns>
</returns> private String Btngoodclick (Eventmessage em) {//Reply welcome Message TextMessage TM = new TextMessage (); Tm. Tousername = em.
Fromusername; Tm. Fromusername = em.
Tousername; Tm.
Createtime = Common.getnowtime (); Tm. Content = @ "Thank you for your support!"
"; Return TM.
Generatecontent (); ///<summary>///help///</summary>///<param name= "em" ></param>///<returns>&
Lt;/returns> private String Btnhelpclick (Eventmessage em) {//Reply welcome Message TextMessage TM = new TextMessage (); Tm. Tousername = em.
Fromusername; Tm. Fromusername = em.
Tousername; Tm.
Createtime = Common.getnowtime (); Tm.
Content = @ "Query weather, enter TQ city name pinyin \ First letter"; Return TM.
Generatecontent ();
}<summary>///Weather///</summary>///<param name= "CityName" ></param>///<param na Me= "em" ></param>///<returns></returns> private String Searchweather (string cityname, eventmess
Age em) {TextMessage TM = new TextMessage (); Tm.
Content = Weatherhelper.getweather (CityName); Convert TM to Sender and receiver. Tousername = em.
Fromusername; Tm. Fromusername = em.
Tousername; Tm.
Createtime = Common.getnowtime (); Return TM.
Generatecontent ();
}
}
}
6. Effect Drawing
Finally workpiece, finally look at the effect of the picture bar
The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.