一、前言
由於微信小程序的規則限制,在小程序內部是無法直接識別二維碼的,這樣對於想通過微信小程序給微信公衆號引流的想法大抵都被扼殺了,偶然間發現微信官方小程序“微保”竟然做到了,而且他們竟是通過小程序客服消息這種曲線救國的方式實現的,於是好好研究了一番總算也把功能實現了,遂整理思緒記錄一下實現過程和方法,爲有想通過微信小程序給公衆號引流想法的開發者提供借鑑(相信有此想法的還是大有人在的 哈哈~)。
二、如何實現二維碼識別?
“微保”小程序的實現步驟如下:
1、用戶在小程序中點擊去關注的按鈕跳轉到客服消息聊天頁面。
2、輸入“666” 自動回覆微信公衆號關注的鏈接,點擊鏈接進入微信公衆號二維碼頁面(嗯 這騷操作還是挺6的)。
3、用戶長按識別二維碼直接跳轉公衆號關注頁面,直接關注即可。
雖然規則限制不允許小程序給公衆號引流,並做了很多技術手段上的規避,但通過這種方式能夠實現也算是開了一扇小窗。
三、代碼實現
1、小程序端代碼實現
<button class="pay-button" open-type='contact' show-message-card='true' send-message-img='/images/icon_input.png' >
微信付款
</button>
呀呀呀~ 不是說小程序給公衆號引流麼?怎麼扯到了微信付款,額..... 我這裏做的正是在小程序中識別微信收款碼的功能,不過原理都是一樣的,只要實現了在小程序內識別二維碼的功能,你將這個微信收款碼換成公衆號二維碼不就成了麼!! 好,言歸正傳,繼續上代碼。
代碼釋義:
open-type='contact' 指定按鈕類型爲喚起客服消息的按鈕。
show-message-card 是否顯示會話內消息卡片,設置此參數爲 true,用戶進入客服會話會在右下角顯示"可能要發送的小程序"提示,用戶點擊後可以快速發送小程序消息。
send-message-title 官方文檔解釋爲會話內消息卡片標題,我試過了並沒有用,還有一點“微保”小程序點擊按鈕可自動輸入併發送“666”,研究了半天我這邊並不能如願實現此功能,如有知道如何實現的還請告知一二,萬分感謝~。
send-message-img 指定會話內消息卡片圖片即會話窗口右下角自動展示的圖片。如下圖:
2、後端代碼實現
我這裏後端代碼使用C#實現的,如有需要其他語言的實現代碼還請自行百度。
1)、接口認證
對接微信客服消息前需要在微信公衆平臺配置消息推送Token以及我們自己的API地址並驗證成功才行,這一步操作頗費了些功夫。
認證代碼如下:
/// <summary>
/// 微信消息推送配置認證
/// </summary>
/// <param name="echostr">隨機字符串</param>
/// <param name="signature">微信簽名</param>
/// <param name="timestamp">時間戳</param>
/// <param name="nonce">隨機數</param>
/// <returns></returns>
[HttpGet]
public HttpResponseMessage weixinchat(string echostr, string signature, string timestamp, string nonce)
{
try
{
string token = "xxxxx"; //寫自己配置的token
if (!CheckSignature(token, signature, timestamp, nonce))
echostr = "驗證不正確";
HttpResponseMessage responseMessage = new HttpResponseMessage { Content = new StringContent(echostr, Encoding.GetEncoding("UTF-8"), "text/plain") };
return responseMessage;
}
catch (Exception ex)
{
throw ex;
}
}
2)、接收消息內容並回復
當用戶在客服會話發送消息、或由某些特定的用戶操作引發事件推送時,微信服務器會將消息或事件的數據包發送到開發者填寫的 URL,各消息類型的推送JSON、XML數據包結構如下:
文本消息
用戶在客服會話中發送文本消息時將產生如下數據包:
JSON 格式
{
"ToUserName": "toUser",
"FromUserName": "fromUser",
"CreateTime": 1482048670,
"MsgType": "text",
"Content": "this is a test",
"MsgId": 1234567890123456
}
XML 格式
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1482048670</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[this is a test]]></Content>
<MsgId>1234567890123456</MsgId>
</xml>
圖片消息
用戶在客服會話中發送圖片消息時將產生如下數據包:
JSON 格式
{
"ToUserName": "toUser",
"FromUserName": "fromUser",
"CreateTime": 1482048670,
"MsgType": "image",
"PicUrl": "this is a url",
"MediaId": "media_id",
"MsgId": 1234567890123456
}
XML 格式
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1482048670</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
<PicUrl><![CDATA[this is a url]]></PicUrl>
<MediaId><![CDATA[media_id]]></MediaId>
<MsgId>1234567890123456</MsgId>
</xml>
還有小程序卡片消息、進入會話事件 等這裏就不一一列舉了,大家自己看官方文檔 接收消息和事件 。
消息回覆代碼實現
/// <summary>
/// 接收用戶消息並處理
/// </summary>
/// <returns></returns>
[HttpPost]
public HttpResponseMessage weixinchat()
{
var content = Request.Content.ReadAsStringAsync().Result;
wxMessageModel msgModel = JsonConvert.DeserializeObject<wxMessageModel>(content);
LogUtil.WriteLog("接收的客服消息:" + msgModel.Content);
if (IsNumber(msgModel.Content))
{
TradeOrderModel tmodel = new TradeOrderBLL().getModelByOrderNo(msgModel.Content);
string receivecode = "";
string username = "";
if (tmodel.retype == 1)
{
username = tmodel.reusername;
receivecode = new UserBLL().GetModel(tmodel.reuserid).receivecode;
}
else
{
username = tmodel.orderusername;
receivecode = new UserBLL().GetModel(tmodel.orderuserid).receivecode;
}
string payImage = "https://xxxx.com/" + receivecode; WxMessageUtil.SendMessage(msgModel.FromUserName, payImage, tmodel.totalmoney, username);
}
HttpResponseMessage responseMessage = new HttpResponseMessage();
return responseMessage;
}
/// <summary>
/// 接收到的消息模型
/// </summary>
public class wxMessageModel
{
public string FromUserName { get; set; }
public string MsgType { get; set; }
public string Content { get; set; }
}
/// <summary>
/// WxMessageUtil 發送消息
/// </summary>
/// <param name="touser"></param>
public static bool SendMessage(string touser, string payimg, decimal money,string reciveuser)
{
try
{
string accessToken = WeixinUtil.GetAccessToken();
string SendMessageApi = ConfigurationManager.AppSettings["SendMessageApi"];
string postUrl = SendMessageApi +
"?access_token=" + accessToken;
JObject data = new JObject();
data.Add("touser", touser);
data.Add("msgtype", "link");
data.Add("link", JObject.FromObject(new
{
title = "微信支付",
description = "點擊鏈接進入掃碼付款\r\n金額:¥" + money + "\r\n收款人:" + reciveuser,
url = payimg,
thumb_url = payimg
}));
LogUtil.WriteLog("客服消息發送用戶:" + touser + "內容:" + payimg);
string postData = data.ToString();
var res = WeixinUtil.PostResponse(postUrl, postData);
RetMessage ret = JsonConvert.DeserializeObject<RetMessage>(res);
LogUtil.WriteLog("客服消息發送結果:" + ret.errmsg);
return ret.errmsg == "ok";
}
catch (Exception ex)
{
throw ex;
}
}
代碼中涉及的兩個Util類WeixinUtil,WxMessageUtil 鏈接:https://pan.baidu.com/s/1cJ-s48LGIrDvufCJXr38rw 密碼:7pyc 取用自便。
最終實現效果如下:
參考資料:
小程序官方文檔
微信小程序-消息推送服務器認證 C#