This article shares the experience summary of developing custom menus for WeChat public accounts
开发公司的微信公众账号,在没人指导没有人商量的情况下没少查资料、逛论坛。其中有多少酸甜苦辣,相信能进来看见我的帖子的能体会的到。一年多来为了应付公司的各种需求没时间整理,今天我就把详细的流程写下来供同样遇到问题的参考。微信公众账号几种分类相信大家都有了解。 订阅号我表示无能为力。除非你能认证通过。废话少说开撸。 自定义菜单操作流程其实很简单 ,就是执行一段Java程序 将你公众账号的appid和封装的菜单发送到腾讯服务器,腾讯服务器会根据你请求参数appid和封装的菜单添加到对应的公众账号,一定要罗嗦一句, 在Java 程序中执行一次 main 方法就可以,下次修改重新执行,不过会有缓存,取消重新关注就可以了。 1 新建按钮基类 public class Button { //按钮名称 private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } 2,根据业务需求新建不同的按钮类 /** * view类型的按钮 点击跳转链接 * */ public class ViewButton extends Button { private String type; private String url; public String getType() { return type; } public void setType(String type) { this.type = type; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } }
/**
* Click type button is similar to input type = 'button'. Specify the key to process the corresponding business based on the captured key.
*
*/
public class ClickButton extends Button {
private String type;
private String key;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
}
3 Create a button that matches the type. To put it bluntly, it means creating a main menu container
/**
* Compound type button
*
*/
public class ComplexButton extends Button {
private Button[] sub_button ;
public Button[] getSub_button() {
return sub_button;
}
public void setSub_button(Button[] sub_button) {
this.sub_button = sub_button;
}
}
4 Create a menu class to hold three main menus
/* *
* menu
*/
public class Menu {
private Button[] button;
public Button[] getButton() {
return button ;
}
public void setButton(Button[] button) {
this.button = button;
}
}
5 Create the calling credential class Token to prepare for executing the main method to call the Tencent interface
/**
* Voucher
*
*/
public class Token {
// Interface access credentials
private String accessToken;
// Credential validity period, unit: seconds
private int expiresIn;
public String getAccessToken( ) {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public int getExpiresIn() {
return expiresIn;
}
public void setExpiresIn(int expiresIn) {
this .expiresIn = expiresIn;
}
}
In the following code, I only describe the class. See comments for specific code functions.
6 Prepare for calling Tencent interface
(1) Create a common tool class
/**
* General tool class
*
*/
public class CommonUtil {
private static Logger log = LoggerFactory.getLogger(CommonUtil.class);
/**
* Obtain interface access credentials
*
* @param appid credentials
* @param appsecret key
* @return
*/
public static Token getToken(String appid, String appsecret ) {
// Credential acquisition (GET)
String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET ";
Token token = null;
String requestUrl = token_url.replace("APPID", appid).replace("APPSECRET", appsecret);
// Initiate a GET request to obtain credentials
JSONObject jsonObject = httpsRequest(requestUrl, "GET", null);
if (null != jsonObject) {
try {
token = new Token();
token.setAccessToken(jsonObject.getString("access_token"));
token.setExpiresIn(jsonObject.getInt("expires_in"));
} catch (JSONException e) {
// Failed to obtain token
token = null;
}
}
return token;
}
/**
* Send https request
*
* @param requestUrl request address
* @param requestMethod request method (GET, POST)
* @param outputStr submitted data
* @return JSONObject (obtain the attribute value of the json object through JSONObject.get(key))
*/
public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {
JSONObject jsonObject = null;
try {
// Create an SSLContext object and initialize it with the trust manager we specified
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom( ));
// Get the SSLSocketFactory object from the above SSLContext object
SSLSocketFactory ssf = sslContext.getSocketFactory();
URL url = new URL(requestUrl);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(ssf);
conn.setDoOutput(true);
conn.setDoInput (true);
conn.setUseCaches(false);
//Set the request method (GET/POST)
conn.setRequestMethod(requestMethod);
// Write data to the output stream when outputStr is not null
if (null != outputStr) {
OutputStream outputStream = conn.getOutputStream();
// Pay attention to the encoding format
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
// Read the returned content from the input stream
InputStream inputStream = conn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
StringBuffer buffer = new StringBuffer();
while ((str = bufferedReader. readLine()) != null) {
buffer.append(str);
}
// Release resources
bufferedReader.close() ;
inputStreamReader.close();
inputStream.close();
inputStream = null;
conn.disconnect();
jsonObject = JSONObject.fromObject(buffer.toString());
} catch (ConnectException ce) {
log.error("Connection timeout: {}", ce);
} catch (Exception e) {
log.error("https request exception: {}", e);
}
return jsonObject ;
}
}
(2) Create trust manager
package com.test.util;
import java. security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
/**
* Trust Manager
*
*/
public class MyX509TrustManager implements X509TrustManager {
// Check client certificate
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
// Check the server-side certificate
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
// Returns an array of trusted X509 certificates
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
7 After completing the above work, you can create a custom menu. Create a custom menu management class. Assign appId and appSecret and run the main method, done.
package com.test.menu;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.sf. json.JSONObject;
import com.test.bean.Button;
import com.test.bean.ComplexButton;
import com.test.bean.Menu;
import com.test.bean.Token;
import com.test.bean.ViewButton;
import com.test.util.CommonUtil;
/**
* Menu manager class
*
*/
public class MenuManager {
private static Logger log = LoggerFactory.getLogger(MenuManager.class);
/**
* Define menu structure
* @return
*/
private static Menu getMenu() {
//Define submenu
ViewButton btn1 = new ViewButton();
btn1.setName( "Submenu 1");
btn1.setType("view");
btn1.setUrl("http://www.baidu.com");
ViewButton btn2 = new ViewButton();
btn2.setName("Submenu 2");
btn2.setType("view");
btn2.setUrl ("http://www.baidu.com");
ViewButton btn3 = new ViewButton();
btn3.setName("Submenu 3");
btn3.setType("view");
btn3.setUrl("http://www.baidu.com");
ViewButton btn4 = new ViewButton();
btn4.setName("Submenu 4");
btn4.setType("view");
btn4.setUrl("http://www.baidu.com" );
ComplexButton mainBtn1 = new ComplexButton();
mainBtn1.setName("Main Menu 1");
mainBtn1.setSub_button(new Button[] { btn1, btn2});//WeChat stipulates a maximum of five submenus
ComplexButton mainBtn2 = new ComplexButton();
mainBtn2.setName("Main Menu 2");
mainBtn2 .setSub_button(new Button[] { btn3});
ComplexButton mainBtn3 = new ComplexButton();
mainBtn3.setName("Main Menu 3");
mainBtn3 .setSub_button(new Button[] {btn4});
Menu menu = new Menu();
menu.setButton(new Button[] { mainBtn1, mainBtn2, mainBtn3 });
return menu;
}
public static void main(String[] args) {
// The only credential for the public account
1
String appId = "";
//Public account unique credential key
String appSecret = "";
// Call the interface to obtain the credentials
Token token = CommonUtil.getToken(appId, appSecret);
if (null != token) {
// Create a menu
boolean result = createMenu(getMenu(), token.getAccessToken());
// Determine the menu creation result
if (result )
log.info("Menu creation successful!");
else
log.info("Menu creation failed!");
}
}
/**
* Create menu
*
* @param menu menu instance
* @param accessToken credential
* @return true success false failed
*/
public static boolean createMenu(Menu menu, String accessToken) {
boolean result = false ;
String menu_create_url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";
String url = menu_create_url.replace(" ACCESS_TOKEN", accessToken);
// Convert the menu object into a json string
String jsonMenu = JSONObject.fromObject(menu).toString();
// Initiate a POST request to create a menu
JSONObject jsonObject = CommonUtil.httpsRequest(url, "POST", jsonMenu);
if (null != jsonObject) {
int errorCode = jsonObject.getInt("errcode");
String errorMsg = jsonObject.getString("errmsg");
if (0 == errorCode) {
result = true ;
} else {
result = false;
log.error("Failed to create menu errcode:{} errmsg:{}", errorCode, errorMsg);
}
}
return result;
}
}
The above is the detailed content of Summary of experience in developing custom menus for WeChat public accounts. For more information, please follow other related articles on the PHP Chinese website!