小弟應運營要求要更改公衆號菜單,本以爲是在公衆號官網上進行配置即可,,誰知道 竟然是開發者模式編輯的。無奈,從未接觸過公衆號開發的我。有開始啃開了微信開發的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);
}
}