你們好, 今天給你們分享的是打碼指南, 由貓眼線下掃碼1分購談起.前端
小程序在發佈以後是沒有入口的, 以後肯定是由線下掃二維碼進入, 今天分享的是咱們本身嘗試在下線投放二維碼, 進行促銷活動, 中間經歷了一些波折. 這裏給你們介紹一下中間經歷的事情.java
先作下自我介紹, 在2015年加入美團以前, 一個是去哪兒, 一個是CSDN, 再以前在西安, 主要是外包項目, 企業信息管理系統. 以前在作Java, 當時沒有前端工程師的崗位, 但平常工做作前端比較多, 後面你們會看到有時有前端, 有時沒有前端的介紹, 這是由於我我的準全棧的經歷致使. 若是有志向作PM的話, 也建議關注下, 由於一個好的PM, 你應該知道這個東西是怎麼工做起來, 都有哪些人蔘與, 每一個人負責什麼東西, 這個也是頗有幫助的.android
回到主題, 咱們今天大概介紹這4個點git
第1點和業務無關, 純技術的描述. 由於後面在介紹業務相關的場景的時候, 爲了說的更流暢, 因此須要先介紹下小程序碼和二維碼的約束.github
相似菊花那種, 官方名字叫小程序碼, 咱們在平常溝通當中不會在乎這個細節, 反正都能掃, 都叫二維碼.web
這是微信文檔有這個API, 用於生成這個二維碼, 參數包括小程序
path: 'pages/movie/index?arg=foo'
複製代碼
限制:後端
仍舊是菊花碼, 參數包括api
path: 'pages/movie/index'
scene: 'arg=foo'
複製代碼
限制:緩存
在業務場景中不是很通用, 只能固定落地頁, 可是咱們掃碼的目的仍是須要有一些線下的特色可以傳過來, 若是使用scene參數傳遞額外參數的話, 這個限制比上一個更苛刻, 可是它不限數量.
這個是在多數大規模投放二維碼的方案, 小規模的, 好比咱們的今天要講的這個案例, 咱們投放了大概2000多個影院, 其實這2個方案均可以.
小程序官方叫小程序二維碼, 看起來和普通二維碼差很少, 因爲二維碼自己有必定容錯能力, 因此LOGO放着是沒問題, 參數
path: 'pages/movie/index?arg=foo'
複製代碼
限制:
這個二維碼能夠用普通掃碼程序掃描, 掃碼以後能夠發現地址是 mp.weixin.qq.com/a/xxxxxxxxxxx, 這是一個有意思的地方, 咱們明明給傳的是上面的參數, 可是生成的是下面這個地址, 感受是作了轉換.
前面介紹幾種形式, 限制和支持的參數, 存儲的信息, 本質上這些信息和URL差很少. 咱們用二維碼鏈接線上線下, 二維碼自己存儲的信息是路徑加參數.
傳統web開發咱們須要關注URL上的輸入信息, 好比query參數, 路徑, 特別是單頁應用的路由框架特別關注URL上的信息.
能夠理解URL也是一種輸入, 相似觸控. 因此二維碼也須要前端的同窗關注, 由於咱們要去處理二維碼背後的參數, 和咱們的指望是否能匹配.
接下來看下實際案例, 和遇到的問題.
咱們在線下投放的業務, 經過易拉寶的形式, 掃上面的二維碼, 進入活動落地頁, 登陸支付1分錢, 領取兩張優惠券, 分別用於支付電影和小吃如爆米花時抵扣. 投放位置是電影院, 咱們的主要合做方.
5塊的優惠券不是憑空出來的, 是得有人承擔的, 通常是平臺和商家互相分攤的. 平臺指望活動越多越好, 可是影院是有限度, 由於影院的規模, 活動成本有要求. 所以咱們必需要識別出來是那家電影院, 涉及到財務結算, 不能錯.
咱們的方案:
問題來了, 咱們有2000家影院, 每家好比須要2份物料, 那麼咱們須要打印4000份, 有2000種不同的二維碼.
物料通常是總部生產, 由於多數公司比較在乎本身的品牌, 不會容許地下城市本身隨便生產涉及品牌形象的物料. 總部製做好以後還須要郵寄到各個城市, 把它放到具體的影院中.
正確的打印和郵寄, 人工不出錯才見鬼了. 快遞還能夠直接看單子, 二維碼人不能直接識別, 打印錯了也難以發現.
因此直接按照這個方案走是很容易出錯的. 1%的出錯比例影響也比較大, 出錯的影院會直接找上門, 那就會是很大的麻煩.
爲了不出錯, 調整以後的方案, 咱們印刷一個模板, 不包含二維碼, 由於物料只有二維碼部分是變的, 別的都不變, 這樣就能夠批量的印刷, 批量的郵寄的問題. 若是郵寄出錯了, 咱們能夠把電子版素材發過去, 在當地印刷出來也來得及, 也容許電影院自行印刷更合適的介質.
二維碼經過影院後臺推送, 影院自行粘貼, 這也是你們看一些大型活動二維碼和背後的物料是分離的緣由.
看起來沒啥問題, 實際落地效果基本符合預期. 但接着就進入到一些更具體的業務場景
進入活動落地頁, 完成簡單任務或直接領取優惠券, 領取優惠券以後指望支持後退, 若是咱們什麼額外的都不作, 左上角什麼都沒有, 沒有後退, 只能點右上角關閉, 再進來又是活動頁.
用戶就會疑問, 我領了優惠券到哪裏去花呢?
因此需求確定會要求支持回退, 跳轉到能消費優惠券的地方. 以前在掘金小程序開發者大會當中有講師也提到過, 左上角的後退按鈕對用戶體驗和數據的提高很重要的, 前端就須要考慮怎麼實現這個需求.
最笨的辦法: 先到首頁, 首頁再作一次重定向到活動頁, 通常咱們指望後退到首頁.
另外一個方案是自定義導航, 至關於頁面是全屏的, 只是在右上角浮出2個小程序自身的按鈕, 關閉和菜單按鈕. 但這個方案有一些限制, 咱們最後沒有用這個方案.
使用第一個方案的話, 二維碼變了, 雖然沒超過128字節, 但已經印刷的二維碼就不能用了, 這就麻煩了, 還得從新生成二維碼, 從新印刷, 並粘貼上去.
若是真的是這樣走一步看一步, 走到這確定出問題, 確定會吐槽.
實際不只僅如此
相似的需求越多, 參數就會越多. 若是是方案B的二維碼, 參數限制只有32位, 若是是方案A, 總長度128能稍好一些, 但反覆生成二維碼頗有可能超過10w個數量限制.
最終會發現產出物料後改需求是一個常態, 咱們如何才能支持這個常態.
這時就回到了咱們提到的那個有意思的方案C, 咱們提交的參數是一個地址, 但它生成的二維碼實際存儲的是另一個地址, 很像短網址服務有沒有. 咱們是否是也能夠作一個這樣的服務, 客戶端的方案以下
path: 'pages/jump?id=3a5fc8'
, id參數表示一個短網址的id, 這個用於生成二維碼pages/jump
頁面
wx.request({ url: 'xxxx', data: '3a5fc8' })
{ path: 'pages/movie/index?go=pages/onecent/index?cinema=15280&utm_source=foo' }
wx.redirectTo({ url: path })
這個 path
就沒什麼長度限制, 這樣就能夠完美的控制後退導航行爲, 以及增長相似 utm_source
的埋點參數, 用於跟蹤放在影院的不一樣入口掃碼意願的差別.
作這些須要前端 後端 PM總體協商合做.
接下來看看服務端咱們指望它有什麼功能
最終咱們生成的二維碼包含的 path 信息是: pages/jump?id=3a5fc8
, 咱們只須要到短網址服務後臺修改就能夠控制它的行爲.
這個方案需求是解決了, 但因爲多了箇中間頁, 可能界面是白的, 最多加個loading態, 改善下體驗, 但時間上可能會有點問題, 比原來要慢些.
通常的解決辦法, 首次進入緩存, 第2次進入直接使用緩存數據, 但仍舊發一個請求出去, 響應了再更新緩存, 這樣不管緩存過時仍是別的情況, 請求都不會阻塞.
更進一步, 咱們能夠生成一個http的地址, 其它的程序也能掃碼成功, 不限於微信.
http://m.maoyan.com/jump?id=3a5fc8
複製代碼
好比咱們指望使用一個二維碼, 任何終端掃碼都能進入活動. 咱們指望微信掃碼打開小程序, 這樣體驗更好, 其它程序掃碼打開h5頁面.
微信掃普通二維碼能打開小程序, 這個能力來自小程序管理後臺, 叫"掃普通連接二維碼打開小程序", 只須要配置一個URL模式, 模式限制數量10個.
有些公司可能小程序公衆號參與者權限互相有隔離, 因此實施這個會有一些溝通工做.
咱們如今已經能讓用戶掃碼, 進入活動頁, 領取優惠券, 後退回到首頁, 完成購票流程.
但不是全部用戶都會走購票流程, 好比用戶如今想去吃飯, 就會關閉小程序走了, 這種狀況咱們 就只能等用戶來購票.
顯然咱們不能等用戶來購票, 這樣在體驗上仍是差點, 用戶領取了優惠券, 可是沒有消費是咱們不肯意看到的.
咱們指望用戶領了優惠券以後能通知用戶, 方案有兩種
微信支付 預充值代金券
須要先充值, 會佔用一些現金, 有作PM的同窗須要注意這點
前端須要注意商品限制, 有這種限制的時候, 須要前端把商品標記傳給微信支付API
有些公司可能不太願意提早墊付資金, 這樣對現金流有要求, 那麼就可能須要自建優惠券.
若是要作到相似微信支付優惠券的體驗, 咱們須要作
限制
自建優惠劵須要作的工做不少, 初創公司建議直接使用微信支付優惠券, 特別是合規 防刷 對帳
自建優惠券, 前端須要注意多收集憑證, 經過 form + button
至此, 咱們的活動上線, 用戶領了優惠券後, 既能現場買票, 也能夠過一段時間收到通知, 得知還有優惠券能夠去買票.
上線後還須要觀察服務自己有什麼意外, 因爲咱們對於多數的異步調用都作了監控, 因此...
wx.getUserInfo() 的返回中包含 signature: 簽名參數, 正常流程是返回了用戶暱稱 頭像信息後須要進行數字簽名並比對是否一致, 不一致就表示有問題, 通常是認爲獲取用戶信息失敗.
但實際中發現Android 5.x系統下的微信客戶端, 若是用戶暱稱中若是包含 emoji 字符, 那麼 signature 確定不一致. 此時用戶暱稱中的 emoji 字符實際ASCII值爲 0xFEFE 這樣的字符, 通常看起來是亂碼.
解決方案: 除了等android 5.x基本消失, 就是如何符合上述條件, 能夠忽略這個數字簽名比對, 暱稱只能獲取到個大概, 基本夠看.
咱們調用了不少微信的接口, 好比 wx.login 相關, 生成二維碼. 有時會超時, 小程序端上的表現是卡頓, 隔了好久提示網絡錯誤, 偶發, 很難復現, 大概0.5%.
對於百萬以上日活用戶的app來講, 這個問題仍是挺嚴重的, 有些用戶若是點擊後發現沒響應, 就停在這了, 用戶會認爲你的小程序有問題, 直接關閉退出了.
調研的結論是網絡問題, 微信這邊給的方案是嘗試用 api2.weixin.qq.com, 也就是咱們須要實現一個容災 重試策略.
咱們最終實現了一個延遲重試的策略, 上線後調用微信接口的可用性從 99.5% 上升到 99.99%+.
咱們用過的一些異常收集系統, 或者在系統出問題的時候, 收集系統也掛掉了, 或者不夠實時, 或者沒有合適的分類, 只見樹不見林, 沒法知道整個問題的狀況, 不容易抓住重點.
咱們發現上述問題主要依賴一個叫cat的系統
基於java, 吞吐量 負載能力超強, 分類聚合知足需求
回顧下標題, 打碼指南: 由貓眼線下掃碼1分購談起, 靠譜的線下掃碼活動須要技術團隊提供那些支撐.
咱們討論了須要開發什麼樣的系統, 關注什麼流程, 那些約束條件須要周知給各方. 由於前端全部的工做都是在一個宿主環境下, 都有不少的限制, 咱們須要在各類限制的條件下完成各類需求.
自定義導航欄, navigationStyle: custom 1.9.5 開始支持, 但須要 整個小程序 全部頁面都自定義導航欄才行, 這對於咱們的場景不太適用, 只能做爲長遠打算
根據咱們的監控統計, 請求微信的接口95%的都會在650ms內響應, 大於這個時間最終請求超時的機率就很大了, 因此最終策略是
一旦請求在650ms內未完成, 當即發出後備請求, 直到任意一個得到響應, 而且是正確的響應內容
這個策略咱們開發成了一個superagent插件, 後續會考慮開源出來
咱們最初還考慮過另外一種方案, 能夠經過定位, 讓用戶選擇附近商家, 會在體驗 運營自由度上有折扣, 但能夠規避各類二維碼物料的問題.
不過最後仍是沒有用這個方案, 若是可接受體驗上的折扣, 仍是能夠用這種方案的.
其次就是把上文提到的二維碼相關功能作成服務開放出來, 我也有關注提供這方面支持的互聯網產品, 目前看未有發現.
上面的文字版的總結,也推薦你們若有時間的話觀看原版視頻分享,如今已經上傳到了 Bilibili,連接爲:www.bilibili.com/video/av348… ,歡迎你們觀看學習和收藏~