微信訂閱號自定義菜單java開發 原

小弟應運營要求要更改公衆號菜單,本以爲是在公衆號官網上進行配置即可,,誰知道 竟然是開發者模式編輯的。無奈,從未接觸過公衆號開發的我。有開始啃開了微信開發的api,原來的做這個得小夥伴,跑路了。但沒有交接。哎~~~

廢話不多說。開啓流程。

1、小弟這個僅僅是【訂閱號】的開發。進入公衆號後左邊菜單找到

這是該公衆號開發時用到的關鍵參數列表,如下:

這裏介紹下幾個開發中用到的重要參數:

1、開發者ID(AppId):就是開發人員在開發該訂閱號  的賬號

2、開發者密碼(AppSecret) : 就是開發人員在開發該訂閱號  的密碼

3、IP白名單:該參數是微信服務器的一個ip白名單的驗證,如果沒有該白名單,微信服務器就不會承認你的地址是安全的。不能獲取access_token參數

4、服務器地址(URL):他是微信回調 你的服務器的地址。記住這個服務器地址是你的。不是微信的。而且這個地址有些硬性條件

      (1)該url必須開通外網映射,不管你是在公司 還是在家。這個地址必須外網能夠訪問到。

      (2)該url端口號必須是80,至於映射到本地應用端口是XXXX都無所謂。配置外網映射 我使用的是Sunny-Ngrok(https://www.ngrok.cc/)內網穿透服務,這個是一個網站提供,裏面有免費的http外網映射。其他的映射服務均失敗(可能是自己太菜)。。格式,外網映射地址+應用驗證接口

5、令牌(Token):驗證使用的一個自定義字符串

6、消息加解密密鑰:這個參數是發送/接收消時加密用的。但如果設置是明文方式,那麼這個參數沒用到。我就沒用到

7、消息加密/解密方式:明文、兼容、安全

以上參數,構成了微信開發的基礎參數。但想要真正開發,還有一些準備要做。

一、驗證:

不能可直接在生產環境開發,大牛這麼做的都很少。所以需要一個測試環境。那麼就是開發者工具中的【公衆號測試賬號】中,就可以創建,目前其他幾項我就是看看沒有仔細研究,後期補發。點擊進入:

用手機微信直接授權登錄即可:

簡單說明一下,測試賬號信息表中的內容是根據登錄的微信生成的。。我試了好幾次都不會變。應該是賬號綁定的。注意,,這時測試賬號的賬號和密碼,,前者的賬號  密碼是生產環境。還有 這個登錄的微信必須是該公衆號管理員授權綁定的微信賬號才行。

在公衆號左側菜單 人員設置中添加人員(創建者忽略),然後開發者工具中的Web開發者工具綁定一個開發者的微信號即可。
 

* 然後說說接口配置信息,第一次測試賬號配置是空的。url 也就是你的服務器地址,必須是80端口或443(也就是http和https默認端口)外網能夠訪問到的地址+你的驗證應用接口地址  和第4 配置套路一模一樣比如  http://xxxx.cn/wx/yanzhengApi,驗證的java demo爲:

@ResponseBody
	@RequestMapping(value = "/WechatCallbackApi", method = RequestMethod.GET)
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 微信加密簽名
		String signature = request.getParameter("signature");
		System.out.println("微信加密簽名=====" + signature);
		// 隨機字符串
		String echostr = request.getParameter("echostr");
		System.out.println("隨機字符串=====" + echostr);
		// 時間戳
		String timestamp = request.getParameter("timestamp");
		System.out.println("時間戳=====" + echostr);
		// 隨機數
		String nonce = request.getParameter("nonce");
		System.out.println("隨機數=====" + echostr);
		String[] str = { TOKEN, timestamp, nonce };
		Arrays.sort(str); // 字典序排序
		String bigStr = str[0] + str[1] + str[2];
		System.out.println("=====================" + bigStr);

		MessageDigestUtils digestutil = new MessageDigestUtils();
		String sha1 = MessageDigestUtils.sha1(bigStr);
		// 確認請求來至微信
		if (sha1.equals(signature)) {
			System.out.println("=====驗證成功============");
			response.getWriter().print(echostr);
		}

	}

這個demo 方法上面肯定還有一個controller 的mapping,自己寫吧。

* 下面的token 就是上述第5點的token

單機提交,如果沒有問題,會提示配置成功(這裏需要確定你的藉口在接收到請求後的響應時間,太長微信都不認, 多試幾次就可以了),否則就是配置失敗。失敗的原因,其實很簡單。就是你的url配置的問題。一般token不會有問題。上述圖片中是我配置很久才成功的截圖。可以修改。提交驗證是,會請求上述demo。大哥斷點就知道怎麼回事了。而且微信的api文檔對這塊說的還是比較清楚的。就是沒有明說url配置需要80或443 端口(PS:其實api文檔也說明了。但是,是在另一個頁面說明的。。【開始開發】-【接入指南】最下方纔說明,這裏配置url啥都沒說。)

完成以上工作久具備了 訂閱號開發的最基本的配置。

* JS接口安全域名 我沒有用到。這裏不做介紹

使用你的登錄測試賬號的微信掃描一下  【測試號二維碼】就會使當前微信關注這個訂閱號了。點擊關注。進入後,發現啥玩意都沒有。咋辦。新建菜單,這個自定義菜單可以使用微信提供的web頁面創建 也可以使用java寫,java 的demo如下

工具類:

package com.tiancaibao.service.weixin;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.log4j.Logger;
import org.springframework.util.StringUtils;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tiancaibao.weixin.pojo.token.WeixinToken; 

/** 
 * 獲取微信access_token工具類 

 */  
public class WeiXinAccessTokenUtil  
{  
    private static final Logger DEBUG_LOGGER = Logger.getLogger(WeiXinAccessTokenUtil.class);  
      
    /** 
     * 從微信上
     * 獲取微信access_token 
     * 
     */  
    public static WeixinToken getWeiXinAccessToken(String appid,String secret)  
    {  
        if(StringUtils.isEmpty(appid)|| StringUtils.isEmpty(secret))  
        {  
            DEBUG_LOGGER.error("appid or secret is null");  
            return null;  
        }  
        WeixinToken token = new WeixinToken();  
        try  
        {  
          String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appid+"&secret="+secret;  
              HttpClient httpClient = new HttpClient();  
            GetMethod getMethod = new GetMethod(url);  
            int execute = httpClient.executeMethod(getMethod);  
            System.out.println("execute:"+execute);  
            String getResponse = getMethod.getResponseBodyAsString();  
            System.out.println("========return的json========"+getResponse);
            JSONObject json = (JSONObject) JSON.parseObject(getResponse);  
               token.setAccessToken(json.getString("access_token"));
               token.setExpiresIn(new Integer(json.getString("expires_in"))); 
               Date createtime=new Date();;
			token.setCreatetime(createtime);
        }  
        catch (IOException e)  
        {  
            DEBUG_LOGGER.error("getAccessToken failed,desc:::"+e);  
            e.printStackTrace();  
        }  
    
        return token; 
    }  


}  

access_token實體:

package com.tiancaibao.weixin.pojo.token;

import java.io.Serializable;
import java.util.Date;

public class WeixinToken implements Serializable {
    private Integer id;

    private String accessToken;

    private Integer expiresIn;

    private Date createtime;

    protected String fields;

    private static final long serialVersionUID = 1L;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getAccessToken() {
        return accessToken;
    }

    public void setAccessToken(String accessToken) {
        this.accessToken = accessToken == null ? null : accessToken.trim();
    }

    public Integer getExpiresIn() {
        return expiresIn;
    }

    public void setExpiresIn(Integer expiresIn) {
        this.expiresIn = expiresIn;
    }

    public Date getCreatetime() {
        return createtime;
    }

    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }

    public void setFields(String fields) {
        this.fields = fields;
    }

    public String getFields() {
        return fields;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append(" [");
        sb.append("Hash = ").append(hashCode());
        sb.append(", id=").append(id);
        sb.append(", accessToken=").append(accessToken);
        sb.append(", expiresIn=").append(expiresIn);
        sb.append(", createtime=").append(createtime);
        sb.append(", fields=").append(fields);
        sb.append(", serialVersionUID=").append(serialVersionUID);
        sb.append("]");
        return sb.toString();
    }
}

請求創建工具:

package com.tiancaibao.weixin.menu;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Date;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tiancaibao.service.weixin.MyX509TrustManager; 



/**
* 

* 開發人員: liming  </br>

 */
public class WeixinUtil {
    
    private static Logger log = LoggerFactory.getLogger(WeixinUtil.class);
    

    // 菜單創建(POST) 限100(次/天)
    public static String menu_create_url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";
/***
 * 自定義菜單創建接口:
http請求方式:POST(請使用https協議) https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN
自定義菜單查詢接口:
http請求方式:GET https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN
自定義菜單刪除接口:
http請求方式:GET https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN
 * 
 */
    /**
     * 創建菜單
     * 
     * @param menu 菜單實例
     * @param accessToken 有效的access_token
     * @return 0表示成功,其他值表示失敗
     */
    public static int createMenu(Menu menu, String accessToken) {
        int result = 0;
        // 拼裝創建菜單的url
        String url = menu_create_url.replace("ACCESS_TOKEN", accessToken);
        // 將菜單對象轉換成json字符串
        String jsonMenu = JSONObject.toJSONString(menu);
        // 調用接口創建菜單
        JSONObject jsonObject = httpRequest(url, "POST", jsonMenu);
        if (null != jsonObject) {
            if (0 != jsonObject.getInteger("errcode")) {
                result = jsonObject.getInteger("errcode");
                log.error("創建菜單失敗 errcode:{} errmsg:{}", jsonObject.getInteger("errcode"), jsonObject.getString("errmsg"));
            }
        }

        return result;
    }
    

    
    
    /**
     * 描述:  發起https請求並獲取結果
     * @param requestUrl 請求地址
     * @param requestMethod 請求方式(GET、POST)
     * @param outputStr 提交的數據
     * @return JSONObject(通過JSONObject.get(key)的方式獲取json對象的屬性值)
     */
    public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
        JSONObject jsonObject = null;
        StringBuffer buffer = new StringBuffer();
        try {
            // 創建SSLContext對象,並使用我們指定的信任管理器初始化
            TrustManager[] tm = { new MyX509TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 從上述SSLContext對象中得到SSLSocketFactory對象
            SSLSocketFactory ssf = sslContext.getSocketFactory();

            URL url = new URL(requestUrl);
            HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
            httpUrlConn.setSSLSocketFactory(ssf);

            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);
            
            // 設置請求方式(GET/POST)
            httpUrlConn.setRequestMethod(requestMethod);

            if ("GET".equalsIgnoreCase(requestMethod))
                httpUrlConn.connect();

            // 當有數據需要提交時
            if (null != outputStr) {
                OutputStream outputStream = httpUrlConn.getOutputStream();
                // 注意編碼格式,防止中文亂碼
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }

            // 將返回的輸入流轉換成字符串
            InputStream inputStream = httpUrlConn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            // 釋放資源
            inputStream.close();
            inputStream = null;
            httpUrlConn.disconnect();
            jsonObject = JSONObject.parseObject(buffer.toString());
        } catch (ConnectException ce) {
            log.error("Weixin server connection timed out.");
        } catch (Exception e) {
            log.error("https request error:{}", e);
        }
        return jsonObject;
    }
    /**
     * 發送圖片消息
     * @param accesstoken
     * {
    "touser":"OPENID",
    "msgtype":"image",
    "image":
    {
      "media_id":"MEDIA_ID"
    }
}
     * @param openid
     */
    public static int SendCustomerMessage(String accesstoken ){
    	      String url="https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token="+accesstoken;
    	      ImageMsg image =new ImageMsg();
    	      Image ima= new Image();
    	      ima.setMedia_id("FsM7Uo7Nk1YDdSZr8zYu7p079vyXhsvdbW3ArYpwqcM");
    	      image.setImage(ima);
    	      image.setTouser("ovlNE1A7Zlufu0wfMYiweE6igo-c");
    	      image.setMsgtype("image");// 圖片類型消息

    	      
    	      String jsonMenu = JSONObject.toJSONString(image);
    	      System.out.println(jsonMenu);
    	        // 調用接口創建菜單
  	        JSONObject jsonObject = httpRequest(url, "POST", jsonMenu);
    	      int  result = 0;
				if (null != jsonObject) {
    	            if (0 != jsonObject.getInteger("errcode")) {
    	                result = jsonObject.getInteger("errcode");
    	                log.error("創建菜單失敗 errcode:{} errmsg:{}", jsonObject.getInteger("errcode"), jsonObject.getString("errmsg"));
    	            }
    	        }

    	        return result;
      	
    }
    
 public static void main(String[] args) {
	}
}

自定義菜單創建main:

package com.tiancaibao.weixin.menu;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.tiancaibao.service.weixin.WeiXinAccessTokenUtil;
import com.tiancaibao.weixin.pojo.token.WeixinToken;


/**
* 類名: MenuManager </br>
* 
* 描述:菜單管理器類 </br>

 */
public class MenuManager {
    private static Logger log = LoggerFactory.getLogger(MenuManager.class);

    public static void main(String[] args) {
      // 第三方用戶唯一憑證  測試
     String appId = "wxxxxxxx";
        // 第三方用戶唯一憑證密鑰
        String appSecret = "xxxxxxxxxxxx";
    	    
        WeixinToken weiXinAccessToken = WeiXinAccessTokenUtil.getWeiXinAccessToken(appId, appSecret);
        
       if (null != weiXinAccessToken) {
        	String asstoken=weiXinAccessToken.getAccessToken();
        			// 調用接口創建菜單
            int result = WeixinUtil.createMenu(getMenu(), asstoken);

            // 判斷菜單創建結果
            if (0 == result)
                log.info("菜單創建成功!");
            else
                log.info("菜單創建失敗,錯誤碼:" + result);
       }
    }

    /**
     * 組裝菜單數據
     * 
     * @return
     */
    private static Menu getMenu() {


        //新菜單自定義

        CommonButton mainBtn1New = new CommonButton();
        mainBtn1New.setName("呀!活動");
        mainBtn1New.setType("view");
        mainBtn1New.setKey("http://weixin.xxxx");

        CommonButton btn2_1 = new CommonButton();
        btn2_1.setName("歷史文章");
        btn2_1.setType("view");
        btn2_1.setUrl("xxxx");

        CommonButton btn2_2 = new CommonButton();
        btn2_2.setName("積分商城");
        btn2_2.setType("view");
        btn2_2.setUrl("http://xxxx");

        CommonButton btn2_3 = new CommonButton();
        btn2_3.setName("客服熱線");
        btn2_3.setType("click");
        btn2_3.setKey("我們的服務熱線xx,工作時間 9:00-20:00,歡迎有問題撥打熱線哦~");

        CommonButton btn3_1 = new CommonButton();
        btn3_1.setName("我的資產");
        btn3_1.setType("view");
        btn3_1.setKey("http://xxxx");

        CommonButton btn3_2 = new CommonButton();
        btn3_2.setName("登錄註冊");
        btn3_2.setType("view");
        btn3_2.setKey("http://xxx");

        CommonButton btn3_3 = new CommonButton();
        btn3_3.setName("我要出借");
        btn3_3.setType("view");
        btn3_3.setKey("http://xxx");

        CommonButton btn3_4 = new CommonButton();
        btn3_4.setName("下載APP");
        btn3_4.setType("view");
        btn3_4.setKey("https://xxx");
        
        /**
         * 微信:  mainBtn1,mainBtn2,mainBtn3底部的三個一級菜單。 執行前觀察appSecret參數是否需要重置。記得的話就不需要。。不急的。估計懸了。。要重置,
         * 但重置後會不會對全有的菜單有影響呢?~~
         */
        
//        ComplexButton mainBtn1 = new ComplexButton();
//        mainBtn1.setName("呀!活動");
//        //一級下有4個子菜單
//        mainBtn1.setSub_button(new CommonButton[] {btn8,btn9});

        
        ComplexButton mainBtn2 = new ComplexButton();
        mainBtn2.setName("呀!姿勢");
        mainBtn2.setSub_button(new CommonButton[] { btn2_1,btn2_2, btn2_3 });

        
        ComplexButton mainBtn3 = new ComplexButton();
        mainBtn3.setName("呀!我的");
        mainBtn3.setSub_button(new CommonButton[] { btn3_1,btn3_2,btn3_3, btn3_4 });

        
        /**
         * 封裝整個菜單
         */
        Menu menu = new Menu();
        menu.setButton(new Button[] { mainBtn1New, mainBtn2, mainBtn3 });

        return menu;
    }
}

CommonButton:

package com.tiancaibao.weixin.menu;

/**
* 類名: CommonButton </br>
* 包名: com.souvc.weixin.menu
* 描述: 子菜單項 :沒有子菜單的菜單項,有可能是二級菜單項,也有可能是不含二級菜單的一級菜單。 </br>

 */
public class CommonButton extends Button {
    
    private String type;
    private String key;
    private String  url;

    public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

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

complexButton:

package com.tiancaibao.weixin.menu;

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

Button:

package com.tiancaibao.weixin.menu;


/**
* 類名: Button </br>
* 包名: com.souvc.weixin.menu
* 描述: 菜單項的基類  </br>
 */
public class Button {
    
    private String name;//所有一級菜單、二級菜單都共有一個相同的屬性,那就是name

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Menu:

package com.tiancaibao.weixin.menu;

/**
* 類名: Menu </br>
* 包名: com.souvc.weixin.menu
* 描述: 整個菜單對象的封裝 </br>

 */
public class Menu {
    private Button[] button;

    public Button[] getButton() {
        return button;
    }

    public void setButton(Button[] button) {
        this.button = button;
    }
}

以上就是 自定菜單的創建源碼及過程。一級菜單和二級菜單的編輯 使用了java 的多態特性。api文檔中也給出了具體的demo 可以參考。至於相關的事件和特性也請參看api文檔,寫的很詳細了,不做贅述。

附加,接收微信回調處理方法:

/*
	 * 特別注意,req.getInputStream()只能獲取一次,並且只能讀取一次。如果想要多次讀取,需要另外想辦法。爲了簡單起見,
	 */
	@ResponseBody
	@RequestMapping(value = "/WechatCallbackApi", method = RequestMethod.POST)
	public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 設置編碼
		req.setCharacterEncoding("utf-8");
		resp.setContentType("html/text;charset=utf-8");
		resp.setCharacterEncoding("utf-8");
		/*
		 * 該部分我們獲取用戶發送的信息,並且解析成<K,V>的形式進行顯示
		 */
		// 解析用戶發送過來的信息
		InputStream is = req.getInputStream();// 拿取請求流
		// 將解析結果存儲在HashMap中
		Map<String, String> map = new HashMap<String, String>();
		// 解析xml,將獲取到的返回結果xml進行解析成我們習慣的文字信息
		SAXReader reader = new SAXReader();//
		Document document = null;
		try {
			document = reader.read(is);// 讀取流中的內容
		} catch (DocumentException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		// 得到xml根元素
		Element root = document.getRootElement();
		// 得到根元素的所有子節點
		List<Element> elementList = root.elements();
		// 遍歷所有子節點,將所有的節點存放到map中,讀取的時候方便
		for (Element e : elementList)
			map.put(e.getName(), e.getText());

		Set<String> keySet = map.keySet();
		// 輸出解析後用戶發過來的信息
		System.out.println("===解析用戶發送過來的信息開始");
		String FromUserName = "";// 用戶的openid
		String event = "";// 事件類型
		boolean ismessage = false;
		String messsgeContent = "";
		String shopid = "";
		String EventKey = "";
		for (String key : keySet) {
			System.out.println(key + ":" + map.get(key));
			if ("FromUserName".equals(key)) {
				FromUserName = map.get(key);
			}
			if ("Event".equals(key)) {
				event = map.get(key);
			}
			// 關鍵詞報文開頭
			if ("MsgId".equals(key)) {
				ismessage = true;
			}
			if ("Content".equals(key)) {
				messsgeContent = map.get(key);
			}
			if ("EventKey".equals(key)) {
				EventKey = map.get(key);
			}
		}

		System.out.println("==========是否發送message==============" + ismessage);
		System.out.println(":解析用戶發送過來的信息結束");

		/*
		 * 該部分我們嘗試按照文檔的要求格式給用戶回覆文本信息、圖文消息。重點:按照文檔要求構造需要的參數。特別注意:參數區分大小寫。
		 */
		// 發送普通文本消息,請查看文檔關於“回覆文本消息”的xml格式

		// 第一步:按照回覆文本信息構造需要的參數
		TextMsg textMsg = new TextMsg();
		textMsg.setToUserName(map.get("FromUserName"));// 發送和接收信息“User”剛好相反
		textMsg.setFromUserName(map.get("ToUserName"));
		textMsg.setCreateTime(new Date().getTime());// 消息創建時間 (整型)
		textMsg.setMsgType("text");// 文本類型消息
		Date subscribedate = new Date();
		// 自定義菜單爲 CLICK,關注爲subscribe
		if (event.equals("CLICK")) {
			textMsg.setContent("我們的服務熱線xxxx,工作時間 9:00-20:00,歡迎有問題撥打熱線哦~\ue415");
		} else if (event.equals("subscribe")) {
			// 查詢是否有關注記錄
			Weixinshopsubscriberecord selectInfoByOpenId = wexinSubscibeservice.selectInfoByOpenId(FromUserName);
			System.out.println("=============查詢是否有關注記錄==========" + selectInfoByOpenId);
			if (EventKey != "" || EventKey != null || !"".equals(EventKey)) {
				System.out.println("===========================EventKey===============" + EventKey.toString());
				String[] Str = EventKey.split("_");
				// 此判斷是爲了防止二維碼參數爲空的情況
				if (Str.length > 1) {
					shopid = Str[1];
				}
			}
			// 未關注
			if (selectInfoByOpenId == null) {
				// 初次關注
				String FirstSubscribe = "終於等到你還好我沒放棄,右下角快去開啓你的財富之旅吧!" ;
				if(!"".equals(shopid)){

					FirstSubscribe+="   來源編號:"+ shopid;

				}
				
				
				textMsg.setContent(FirstSubscribe);
				Weixinshopsubscriberecord weixinshop = new Weixinshopsubscriberecord();
				weixinshop.setOpenid(FromUserName);
				weixinshop.setShopid(shopid);
				weixinshop.setState("1");
				weixinshop.setSubscribedate(subscribedate);
				weixinshop.setSubscribetime(subscribedate);
				// 保存openid
				wexinSubscibeservice.SubscribeSave(weixinshop);

			} else {
				// 取消後再次關注
				selectInfoByOpenId.setState("2");
				selectInfoByOpenId.setSubscribedate(subscribedate);
				selectInfoByOpenId.setSubscribetime(subscribedate);
				selectInfoByOpenId.setOpenid(FromUserName);
				selectInfoByOpenId.setShopid(shopid);
				wexinSubscibeservice.UpdateSubscribe(selectInfoByOpenId);// 更改記錄
				
				String SecondSubscribe = "歡迎回到財富之路,等你啓程!" ;
				if(!"".equals(shopid)){
					SecondSubscribe+="  來源編號:"+ shopid;
				}
				
				
				
				
				textMsg.setContent(SecondSubscribe);

			}
		} else if (event.equals("unsubscribe")) {
			Weixinshopsubscriberecord weixinshop = new Weixinshopsubscriberecord();
			weixinshop.setState("0");// 取消關注爲0
			weixinshop.setSubscribedate(subscribedate);
			weixinshop.setSubscribetime(subscribedate);
			weixinshop.setOpenid(FromUserName);
			weixinshop.setShopid(shopid);
			wexinSubscibeservice.UpdateSubscribe(weixinshop);

		}
		// 是否發送客服消息
		Boolean issend = false;

		/**
		 * 回覆圖片消息
		 */
		ImageMsg imagemsg = new ImageMsg();
		imagemsg.setToUserName(map.get("FromUserName"));// 發送和接收信息“User”剛好相反
		imagemsg.setFromUserName(map.get("ToUserName"));
		imagemsg.setCreateTime(new Date().getTime());// 消息創建時間 (整型)
		imagemsg.setMsgType("image");// 文本類型消息
		Image Image = new Image();
		// Image.setMediaId("FsM7Uo7Nk1YDdSZr8zYu7p079vyXhsvdbW3ArYpwqcM");//圖片ID,不固定

		Image.setMediaId("6GTGDx7tGKMgnHv2Qzd9-orxsSaNBr4TdLN_n2zdw14");// 圖片ID,不固定

		imagemsg.setImage(Image);
		// 消息內容
		if (ismessage) {
			if (messsgeContent.indexOf("建軍節快樂") != -1) {
				textMsg.setContent("活動已結束,歡迎下次來參加哦\ue409");
			}else if(messsgeContent.indexOf("中秋") != -1){
			   textMsg.setContent("http://4xxx/index.jsp?aid=fe66eb90a5ea40e3a956ecaf2926f1c9&activityid=110312&wuid=457767&keyversion=0&isFromApiFilter=1");
		     }else if (messsgeContent.indexOf("客服 聯繫 電話") != -1) {
				textMsg.setContent("我們的客服熱線:xxx,快去撥打吧,美麗的客服妹子在等你~");
			} else if (messsgeContent.indexOf("你好") != -1 || messsgeContent.indexOf("在麼") != -1
					|| messsgeContent.indexOf("在") != -1 || messsgeContent.indexOf("在?") != -1
					|| messsgeContent.indexOf("你好?") != -1 || messsgeContent.indexOf("您好?") != -1
					|| messsgeContent.indexOf("你好?") != -1 || messsgeContent.indexOf("你好啊?") != -1
					|| messsgeContent.indexOf("hi") != -1 || messsgeContent.indexOf("hello") != -1) {
				textMsg.setContent("Hi~~~想我了嗎?有任何問題,請電話騷擾我們的客服哦,客服電話:xxx \ue032");
			} else if (messsgeContent.indexOf("好買酒") != -1 || messsgeContent.indexOf("好賣酒") != -1
					|| messsgeContent.indexOf("酒") != -1) {
				// textMsg.setContent("呀呀,你是“好買酒”過來的吧?路途遙遠,辛苦啦\ue056
				// \n即日起,掃描上方二維碼實名註冊xxx,即可享受5000元體驗金\ue106+80元現金紅包\ue106+20%加息券\ue106“三重好禮”大禮包,機不可失,失不再來,快去完成註冊吧\ue056");

				XStream xStream = new XStream();
				xStream.alias("xml", imagemsg.getClass());
				String imagemsgXml = xStream.toXML(imagemsg);
				System.out.println("回覆圖片的xml====" + imagemsgXml);
				PrintWriter printWriter = resp.getWriter();
				printWriter.print(imagemsgXml);
				issend = true;
			} else {
				textMsg.setContent(
						"憋~着~急~哈~\ue415你的消息,小編我已收到,容我慢慢回覆哈~\ue056有問題最好還是找我們的客服妹子哈,xxx,人家可比我這個整天只知道碼字送積分的小編專業滴多哈~~~\ue409");
			}
		}

		XStream xStream = new XStream();
		xStream.alias("xml", textMsg.getClass());
		String textMsg2Xml = xStream.toXML(textMsg);
		System.out.println("返回給微信服務器,讓其發送用戶消息的報文====" + textMsg2Xml);

		// 第三步,發送xml的格式信息給微信服務器,服務器轉發給用戶
		// 除了這個,已關注再掃描的事件
		if (!event.equals("SCAN")) {
			PrintWriter printWriter = resp.getWriter();
			printWriter.print(textMsg2Xml);
			System.out.println("======文本發送了============");

		}

		if (issend) {
			/**
			 * 發送客服文本消息
			 */
			// 第一步 獲取accesstoken
			String accesstoken = "";
			Date date1 = new Date();
			Date date2 = new Date();
			Weixincommoninfo selectaccesstoken = weixincommoInfoservice.selectInfo();
			// 查看是否有accesstoken
			if (selectaccesstoken == null) {

				selectaccesstoken = new Weixincommoninfo();
				WeixinToken weiXinAccessToken = WeiXinAccessTokenUtil.getWeiXinAccessToken();
				accesstoken = weiXinAccessToken.getAccessToken();
				selectaccesstoken.setSavefiled("accesstoken");
				selectaccesstoken.setSaveinfo(accesstoken);
				selectaccesstoken.setExpiresIn(weiXinAccessToken.getExpiresIn());
				selectaccesstoken.setCreatetime(date1);
				date2.setHours(date1.getHours() + 1);// 此處將accesstoken的有效期,設置爲1小時
				selectaccesstoken.setEffectivetime(date2);
				weixincommoInfoservice.Saveinfo(selectaccesstoken);

			} else {
				Date date = new Date();
				// 判斷當前時間是否在accesstoken 的有效期內,
				Date effectivetime = selectaccesstoken.getEffectivetime();
				if (effectivetime.getTime() > date.getTime()) {
					accesstoken = selectaccesstoken.getSaveinfo();
					System.out.println("數據庫中的accesstoken能用");
				} else {
					WeixinToken weiXinAccessToken = WeiXinAccessTokenUtil.getWeiXinAccessToken();
					selectaccesstoken = new Weixincommoninfo();
					accesstoken = weiXinAccessToken.getAccessToken();
					selectaccesstoken.setSavefiled("accesstoken");
					selectaccesstoken.setSaveinfo(accesstoken);
					selectaccesstoken.setExpiresIn(weiXinAccessToken.getExpiresIn());
					selectaccesstoken.setCreatetime(date1);
					date2.setHours(date1.getHours() + 1);
					selectaccesstoken.setEffectivetime(date2);
					weixincommoInfoservice.upadateInfo(selectaccesstoken);
					System.out.println("數據庫中的accesstoken不呢能用,重新獲取更新");
				}
			}

			// 第二步發送消息
			System.out.println("發送客服消息=======================");
			String mescont = "呀呀,你是“好買酒”過來的吧?路途遙遠,辛苦啦\ue056 \n即日起,掃描下方二維碼實名註冊xxx,即可享受5000元體驗金\ue106+80元現金紅包\ue106+20%加息券\ue106“三重好禮”大禮包,機不可失,失不再來,快去完成註冊吧\ue056";
			WeixinUtil.SendCustomerTextMessage(accesstoken, FromUserName, mescont);
		}

	}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章