這次我們來一起研究一下“客服訊息”,首先明確一下“客服訊息”的概念。這不同於之前的“被動響應訊息”,也就是說並不是之前“你一言我一語的即時響應”,可能在某種情況下你需要給不同的人主動發送訊息,例如你的餐館推出了新的川菜,那麼你需要給喜歡川菜的人發送訊息,而並不是等著被人發送“有什麼新菜”後,然後反饋給客戶,我推出了什麼什麼的。
說道這裡可能有人會問,那不是群發嗎?不是每天只能發一條嗎?服務號每個月發一條嗎?答案很明確說的是“客服訊息”,也不是群發,它跟群發的區別就在於只要關注了我,那麼我就可以群發給你訊息,而為了不讓使用者感到討厭,作了嚴格的群發條數限制。而“客服訊息”則是只有關注你的人向你發送了訊息,你才能主動推送。就像打電話只有人家問過你問題了,你才能回答,並且繼續跟進回答。再舉一個例子:你通過被人知道了My Phone號,存下來了,你突然給我打電話,我肯定是抵觸的。但是如果我給你打過電話,你通過來電顯示知道了我的號碼,以後再給我打電話,說明我們是認識的,我最少不會抵觸。這就使群發/被動響應/客服訊息的本質區別。
就像我們可以通過收集電話號碼,手機自己的客戶資訊一樣,一旦他們的資訊被我們收錄。那麼我們就可以突破群發條數的限制了,按照的限制群發一個月只能一條(服務號),但是“客服訊息”則可以一天50000條,足夠用了。
下面的問題就是如何手機客戶的“手機號”了,裡面有一個OPENID,這就使手機號了,這個是關注你的使用者的唯一標識,這個標識是不會變的,但是同一個使用者關注不同的號,那麼他在不同號中的ID是不一樣的。如何取得OPENID呢?
網上找了些資料,有的說的的確是錯誤的,有的還說要通過OAuth 2.0授權才可以,這個的確可以,但是太複雜了吧,通過我的測試得出了這樣的結論“只要使用者和你的公用好發生互動”就可以取得他的OPENID了。就如同打電話一樣,只要使用者給你打了電話,你一定知道他的電話了。在裡是這樣的:使用者只要發資訊給你,或者點了某個菜單,發過來的資訊都會有一個“FromUserName”,這個就使OPENID了。我們可以建立一個資料庫來收集這些寶貴的使用者身份資訊,也就是記錄他的“電話號碼”,有了電話號碼,我們就可以以後經常與客戶主動打電話了。我做這樣的一個實驗:
首先記錄使用者的OPENID在OnLoad函數第二行裡面加上一個 WriteLog(wx.FromUserName);把它記錄在一個文字檔中
protected void Page_Load(object sender, EventArgs e) { wxmessage wx = GetWxMessage(); WriteLog(wx.FromUserName); string res = ""; if (!string.IsNullOrEmpty(wx.EventName) && wx.EventName.Trim() == "subscribe") { string content = ""; if (!wx.EventKey.Contains("qrscene_")) { content = "/:rose歡迎北京永傑友信科技有限公司/:rose\n直接回複“你好”"; res = sendTextMessage(wx, content); } else { content = "二維碼參數:\n" + wx.EventKey.Replace("qrscene_", ""); res = sendTextMessage(wx, content); } } else if (!string.IsNullOrEmpty(wx.EventName) && wx.EventName.ToLower() == "scan") { string str = "二維碼參數:\n" + wx.EventKey; res = sendTextMessage(wx, str); } else if (!string.IsNullOrEmpty(wx.EventName) && wx.EventName.Trim() == "CLICK") { if(wx.EventKey=="HELLO") res = sendTextMessage(wx, "你好,歡迎使用北京永傑友信科技有限公司公用平台!"); } else if (!string.IsNullOrEmpty(wx.EventName) && wx.EventName.Trim() == "LOCATION") { res = sendTextMessage(wx, "您的位置是經度:" + wx.Latitude + ",維度是:" + wx.Longitude+",地理經度為:"+wx.Precision); } else { if (wx.MsgType == "text" && wx.Content == "你好") { res = sendTextMessage(wx, "你好,歡迎使用北京永傑友信科技有限公司公用平台!"); } else if (wx.MsgType == "voice") { res = sendTextMessage(wx, wx.Recognition); } else if (wx.MsgType == "location") { res = sendTextMessage(wx, "您發送的位置是:" + wx.Label + ";緯度是:" + wx.Location_X + ";經度是:" + wx.Location_Y + ";縮放比例為:" + wx.Scale); } else { res = sendTextMessage(wx, "你好,未能識別訊息!"); } } Response.Write(res); }WriteLog的方法是這樣的:
/// <summary> /// 寫日誌(用於跟蹤) /// </summary> private void WriteLog(string strMemo) { string filename = Server.MapPath("/logs/log.txt"); if (!Directory.Exists(Server.MapPath("//logs//"))) Directory.CreateDirectory("//logs//"); StreamWriter sr = null; try { if (!File.Exists(filename)) { sr = File.CreateText(filename); } else { sr = File.AppendText(filename); } sr.WriteLine(strMemo); } catch { } finally { if (sr != null) sr.Close(); } } 這樣當客戶發送任何一種資訊給公用號,我們的log.txt檔案中就會記錄這個OPENID,我先開啟Log.txt這個檔案看看OPENID號,我的事這樣的“oV93gjl5slD3p29yS1dOijy-pqZ8”,有了這個OPENID很多事情就都好辦了,以後我們還會介紹如何擷取客戶的資訊。這裡先說“客戶訊息”吧。
下面我們建立一個新的ASPX頁面,在這個頁面裡面我就可以給這些使用者發資訊了。這個頁面(SendMessage.aspx.cs)很簡單就使兩個文字框和一個按鈕:
string MyOpenID; string MyContent; protected void Page_Load(object sender, EventArgs e) { MyOpenID = "oV93gjl5slD3p29yS1dOijy-pqZ8"; MyContent = "這是一個客服訊息"; UserName.Text = MyOpenID; Content.Text = MyContent; } protected void Button1_Click(object sender, EventArgs e) { string res = ""; string Access_Token = IsExistAccess_Token(); string posturl = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" + Access_Token; string postData = "{\"touser\":\"" + UserName.Text + "\",\"msgtype\":\"text\",\"text\":{\"content\":\"" + Content.Text + "\"}}"; res = GetPage(posturl, postData); Response.Write(res); } 中間還用到了之前提到的3個函數:
public string GetPage(string posturl, string postData) { Stream outstream = null; Stream instream = null; StreamReader sr = null; HttpWebResponse response = null; HttpWebRequest request = null; Encoding encoding = Encoding.UTF8; byte[] data = encoding.GetBytes(postData); // 準備請求... try { // 設定參數 request = WebRequest.Create(posturl) as HttpWebRequest; CookieContainer cookieContainer = new CookieContainer(); request.CookieContainer = cookieContainer; request.AllowAutoRedirect = true; request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; request.ContentLength = data.Length; outstream = request.GetRequestStream(); outstream.Write(data, 0, data.Length); outstream.Close(); //發送請求並擷取相應回應資料 response = request.GetResponse() as HttpWebResponse; //直到request.GetResponse()程式才開始向目標網頁發送Post請求 instream = response.GetResponseStream(); sr = new StreamReader(instream, encoding); //返回結果網頁(html)代碼 string content = sr.ReadToEnd(); string err = string.Empty; return content; } catch (Exception ex) { string err = ex.Message; Response.Write(err); return string.Empty; } } /// <summary> /// 根據當前日期 判斷Access_Token 是否超期 如果超期返回新的Access_Token 否則返回之前的Access_Token /// </summary> /// <param name="datetime"></param> /// <returns></returns> public static string IsExistAccess_Token() { string Token = string.Empty; DateTime YouXRQ; // 讀取XML檔案中的資料,並顯示出來 ,注意檔案路徑 string filepath = HttpContext.Current.Server.MapPath("XMLFile.xml"); StreamReader str = new StreamReader(filepath, System.Text.Encoding.UTF8); XmlDocument xml = new XmlDocument(); xml.Load(str); str.Close(); str.Dispose(); Token = xml.SelectSingleNode("xml").SelectSingleNode("Access_Token").InnerText; YouXRQ = Convert.ToDateTime(xml.SelectSingleNode("xml").SelectSingleNode("Access_YouXRQ").InnerText); if (DateTime.Now > YouXRQ) { DateTime _youxrq = DateTime.Now; Access_token mode = GetAccess_token(); xml.SelectSingleNode("xml").SelectSingleNode("Access_Token").InnerText = mode.access_token; _youxrq = _youxrq.AddSeconds(int.Parse(mode.expires_in)); xml.SelectSingleNode("xml").SelectSingleNode("Access_YouXRQ").InnerText = _youxrq.ToString(); xml.Save(filepath); Token = mode.access_token; } return Token; } public static Access_token GetAccess_token() { string appid = "wx043225275885dafd"; string secret = "cb4425b24ab79ef875029cf0bf326ae9"; string strUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret; Access_token mode = new Access_token(); HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(strUrl); req.Method = "GET"; using (WebResponse wr = req.GetResponse()) { HttpWebResponse myResponse = (HttpWebResponse)req.GetResponse(); StreamReader reader = new StreamReader(myResponse.GetResponseStream(), Encoding.UTF8); string content = reader.ReadToEnd(); //Response.Write(content); //在這裡對Access_token 賦值 Access_token token = new Access_token(); token = JsonHelper.ParseFromJson<Access_token>(content); mode.access_token = token.access_token; mode.expires_in = token.expires_in; } return mode; }
這個頁面就是這些了,開啟這個頁面然後發送訊息試試?很不錯吧,這樣在配合上我們的資料庫啦,什麼迴圈了,就可以突破了群發的限制,做到定項的群發訊息推送了!這裡面能發很多種訊息:文本,語音,視頻,圖文,圖片等等。只是Json而已,聰明的你一定可以舉一反三的。