打碼指南:由貓眼線下掃碼1分購談起 | 掘金直播小程式專場總結

netwjx曹宇發表於2019-02-19

背景

大家好, 今天給大家分享的是打碼指南, 由貓眼線下掃碼1分購談起.

小程式在釋出之後是沒有入口的, 之後確定是由線下掃二維碼進入, 今天分享的是我們自己嘗試在下線投放二維碼, 進行促銷活動, 中間經歷了一些波折. 這裡給大家介紹一下中間經歷的事情.

先做下自我介紹, 在2015年加入美團之前, 一個是去哪兒, 一個是CSDN, 再之前在西安, 主要是外包專案, 企業資訊管理系統. 之前在做Java, 當時沒有前端工程師的崗位, 但日常工作做前端比較多, 後面大家會看到有時有前端, 有時沒有前端的介紹, 這是因為我個人準全棧的經歷導致. 如果有志向做PM的話, 也建議關注下, 因為一個好的PM, 你應該知道這個東西是怎麼工作起來, 都有哪些人蔘與, 每個人負責什麼東西, 這個也是很有幫助的.

回到主題, 我們今天大概介紹這4個點

  • 小程式碼和二維碼的約束
  • 產出物料後修改需求
  • 優惠券和使用者觸達通知
  • 線上監控發現的問題

第1點和業務無關, 純技術的描述. 因為後面在介紹業務相關的場景的時候, 為了說的更流暢, 所以需要先介紹下小程式碼和二維碼的約束.

小程式碼和二維碼的約束

類似菊花那種, 官方名字叫小程式碼, 我們在日常溝通當中不會在意這個細節, 反正都能掃, 都叫二維碼.

方案A: getWXACode

這是微信文件有這個API, 用於生成這個二維碼, 引數包括

path: `pages/movie/index?arg=foo`
複製程式碼

限制:

  • path引數限制128位元組長度
  • 呼叫總數量限制: 10w個, 如果超過微信會拒絕後續的介面請求, 直接出錯, 提示超量

方案B: getWXACodeUnlimt

仍舊是菊花碼, 引數包括

path: `pages/movie/index`
scene: `arg=foo`
複製程式碼

限制:

  • path 不能加query引數
  • scene 長度限制32個字元

在業務場景中不是很通用, 只能固定落地頁, 但是我們掃碼的目的還是需要有一些線下的特點能夠傳過來, 如果使用scene引數傳遞額外引數的話, 這個限制比上一個更苛刻, 但是它不限數量.

這個是在多數大規模投放二維碼的方案, 小規模的, 比如我們的今天要講的這個案例, 我們投放了大概2000多個影院, 其實這2個方案都可以.

方案C: createWXAQRCode

小程式官方叫小程式二維碼, 看起來和普通二維碼差不多, 由於二維碼本身有一定容錯能力, 所以LOGO放著是沒問題, 引數

path: `pages/movie/index?arg=foo`
複製程式碼

限制:

  • path 128位元組長度
  • 呼叫總數量限制: 10w個, 和方案A公用配額

這個二維碼可以用普通掃碼程式掃描, 掃碼之後可以發現地址是 mp.weixin.qq.com/a/xxxxxxxxxxx, 這是一個有意思的地方, 我們明明給傳的是上面的引數, 但是生成的是下面這個地址, 感覺是做了轉換.

前面介紹幾種形式, 限制和支援的引數, 儲存的資訊, 本質上這些資訊和URL差不多. 我們用二維碼連線線上線下, 二維碼本身儲存的資訊是路徑加引數.

傳統web開發我們需要關注URL上的輸入資訊, 比如query引數, 路徑, 特別是單頁應用的路由框架特別關注URL上的資訊.

可以理解URL也是一種輸入, 類似觸控. 所以二維碼也需要前端的同學關注, 因為我們要去處理二維碼背後的引數, 和我們的期望是否能匹配.

接下來看下實際案例, 和遇到的問題.

領取優惠券後, 期望能點選後退

我們線上下投放的業務, 通過易拉寶的形式, 掃上面的二維碼, 進入活動落地頁, 登入支付1分錢, 領取兩張優惠券, 分別用於支付電影和小吃如爆米花時抵扣. 投放位置是電影院, 我們的主要合作方.

需求第1階段

5塊的優惠券不是憑空出來的, 是得有人承擔的, 一般是平臺和商家互相分攤的. 平臺期望活動越多越好, 但是影院是有限度, 因為影院的規模, 活動成本有要求. 因此我們必須要識別出來是那家電影院, 涉及到財務結算, 不能錯.

我們的方案:

  • 活動頁每家電影院帶上影院引數, 每家影院生成不一樣的二維碼
  • 我們還需要列印出來

問題來了, 我們有2000家影院, 每家比如需要2份物料, 那麼我們需要列印4000份, 有2000種不一樣的二維碼.

物料一般是總部生產, 因為多數公司比較在意自己的品牌, 不會允許地下城市自己隨便生產涉及品牌形象的物料. 總部製作好之後還需要郵寄到各個城市, 把它放到具體的影院中.

正確的列印和郵寄, 人工不出錯才見鬼了. 快遞還可以直接看單子, 二維碼人不能直接識別, 列印錯了也難以發現.

所以直接按照這個方案走是很容易出錯的. 1%的出錯比例影響也比較大, 出錯的影院會直接找上門, 那就會是很大的麻煩.

為了避免出錯, 調整之後的方案, 我們印刷一個模板, 不包含二維碼, 因為物料只有二維碼部分是變的, 別的都不變, 這樣就可以批量的印刷, 批量的郵寄的問題. 如果郵寄出錯了, 我們可以把電子版素材發過去, 在當地印刷出來也來得及, 也允許電影院自行印刷更合適的介質.

二維碼通過影院後臺推送, 影院自行貼上, 這也是大家看一些大型活動二維碼和背後的物料是分離的原因.

看起來沒啥問題, 實際落地效果基本符合預期. 但接著就進入到一些更具體的業務場景

需求第2階段

進入活動落地頁, 完成簡單任務或直接領取優惠券, 領取優惠券之後期望支援後退, 如果我們什麼額外的都不做, 左上角什麼都沒有, 沒有後退, 只能點右上角關閉, 再進來又是活動頁.

使用者就會疑問, 我領了優惠券到哪裡去花呢?

所以需求肯定會要求支援回退, 跳轉到能消費優惠券的地方. 之前在掘金小程式開發者大會當中有講師也提到過, 左上角的後退按鈕對使用者體驗和資料的提升很重要的, 前端就需要考慮怎麼實現這個需求.

最笨的辦法: 先到首頁, 首頁再做一次重定向到活動頁, 一般我們期望後退到首頁.

另一個方案是自定義導航, 相當於頁面是全屏的, 只是在右上角浮出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整體協商合作.

接下來看看服務端我們期望它有什麼功能

  • 建立短網址 API: 因為我們會批量建立
  • 批量查詢和修改 API: 因為是批量建立的, 我們又有產出物料後改需求的常態
  • 短網址的額外資訊
    • 類別: 同一活動屬於同一類別
    • 附加資訊: Map結構, 比如包含 影院ID, 後退的頁面地址, 埋點資訊等, 為了通用性

最終我們生成的二維碼包含的 path 資訊是: pages/jump?id=3a5fc8, 我們只需要到短網址服務後臺修改就可以控制它的行為.

更多

這個方案需求是解決了, 但由於多了箇中間頁, 可能介面是白的, 最多加個loading態, 改善下體驗, 但時間上可能會有點問題, 比原來要慢些.

一般的解決辦法, 首次進入快取, 第2次進入直接使用快取資料, 但仍舊發一個請求出去, 響應了再更新快取, 這樣無論快取過期還是別的狀況, 請求都不會阻塞.

更進一步, 我們可以生成一個http的地址, 其它的程式也能掃碼成功, 不限於微信.

http://m.maoyan.com/jump?id=3a5fc8
複製程式碼

比如我們期望使用一個二維碼, 任何終端掃碼都能進入活動. 我們期望微信掃碼開啟小程式, 這樣體驗更好, 其它程式掃碼開啟h5頁面.

微信掃普通二維碼能開啟小程式, 這個能力來自小程式管理後臺, 叫”掃普通連結二維碼開啟小程式”, 只需要配置一個URL模式, 模式限制數量10個.

有些公司可能小程式公眾號參與者許可權互相有隔離, 所以實施這個會有一些溝通工作.

小結

  • 需求是多變的: 基礎需求, 後退, 埋點等訴求, 這是一種常態
  • 物料產出後難以修改: 隨著需求變更而重新生產物料是不現實的
  • 短網址服務: 最終的方案

我們現在已經能讓使用者掃碼, 進入活動頁, 領取優惠券, 後退回到首頁, 完成購票流程.

但不是所有使用者都會走購票流程, 比如使用者現在想去吃飯, 就會關閉小程式走了, 這種情況我們
就只能等使用者來購票.

顯然我們不能等使用者來購票, 這樣在體驗上還是差點, 使用者領取了優惠券, 但是沒有消費是我們不願意看到的.

優惠券和使用者觸達通知

我們期望使用者領了優惠券之後能通知使用者, 方案有兩種

  • 微信支付優惠券
  • 自建優惠券

微信支付優惠券

微信支付 預充值代金券

  • 入口: 訊息列表 “微信支付” 服務號
  • 時機: 領取時, 即將到期時
  • 滿減 商品限制 預算限制
  • 防刷 對賬 消耗記錄

需要先充值, 會佔用一些現金, 有做PM的同學需要注意這點

前端需要注意商品限制, 有這種限制的時候, 需要前端把商品標記傳給微信支付API

自建優惠券

有些公司可能不太願意提前墊付資金, 這樣對現金流有要求, 那麼就可能需要自建優惠券.

如果要做到類似微信支付優惠券的體驗, 我們需要做

  • 入口: 訊息列表 “服務通知”
  • 時機: 自由
  • 滿減 限制商品 預算限制
  • 防刷 對賬 消耗記錄

限制

  • 要使用服務通知, 所有訊息都需要憑證, 憑證通過表單 form 標籤 和支付能收集到, 也就是使用者必須有點選行為, 7天有效期
  • 前端需要刻意在小程式上儘量收集這些憑證, 因為需求是多變的, 可能一開始說發2次就行, 後續又說需要發4次
  • 客訴, 使用者覺得騷擾, 會給微信投訴, 微信會直接刪除訊息模板, 訊息就發不出去, 投訴再多就可能觸犯了小程式的規定, 有封號可能
    • 一定要告知給PM, 特別是業務流程需要這個通知, 一定不要做違規的試探行為
  • 防刷 對賬對於後端來說工作量還是很大的

小結

自建優惠劵需要做的工作很多, 初創公司建議直接使用微信支付優惠券, 特別是合規 防刷 對賬

自建優惠券, 前端需要注意多收集憑證, 通過 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監控系統

我們用過的一些異常收集系統, 或者在系統出問題的時候, 收集系統也掛掉了, 或者不夠實時, 或者沒有合適的分類, 只見樹不見林, 無法知道整個問題的情況, 不容易抓住重點.

我們發現上述問題主要依賴一個叫cat的系統

github.com/dianping/ca…

基於java, 吞吐量 負載能力超強, 分類聚合滿足需求

總結

  • 我們介紹了小程式二維碼的約束
  • 需求變化導致我們需要支援產出物料後改需求, 我們通過短網址服務來支援這個業務
  • 我們期望促銷活動能產生使用者消費, 需要通知使用者使用優惠券, 介紹了兩種方案的利弊, 成熟的公司可能兩種方案都要支援
  • 上線的非同步呼叫 遠端呼叫監控, 發現的2個問題及其解決方案.

回顧下標題, 打碼指南: 由貓眼線下掃碼1分購談起, 靠譜的線下掃碼活動需要技術團隊提供那些支撐.

我們討論了需要開發什麼樣的系統, 關注什麼流程, 那些約束條件需要周知給各方. 因為前端所有的工作都是在一個宿主環境下, 都有很多的限制, 我們需要在各種限制的條件下完成各種需求.

Q&A

  1. 為什麼沒有使用自定義導航欄的方案

自定義導航欄, navigationStyle: custom 1.9.5 開始支援, 但需要 整個小程式 所有頁面都自定義導航欄才行, 這對於我們的場景不太適用, 只能作為長遠打算

  1. 能講下延遲重試策略麼?

根據我們的監控統計, 請求微信的介面95%的都會在650ms內響應, 大於這個時間最終請求超時的概率就很大了, 所以最終策略是

一旦請求在650ms內未完成, 立即發出後備請求, 直到任意一個獲得響應, 並且是正確的響應內容

這個策略我們開發成了一個superagent外掛, 後續會考慮開源出來

  1. 這麼看做線下掃碼活動成本 門檻還是有點高, 有什麼別的方法能減少這方面成本?

我們最初還考慮過另一種方案, 可以通過定位, 讓使用者選擇附近商家, 會在體驗 運營自由度上有折扣, 但可以規避各種二維碼物料的問題.

不過最後還是沒有用這個方案, 如果可接受體驗上的折扣, 還是可以用這種方案的.

其次就是把上文提到的二維碼相關功能做成服務開放出來, 我也有關注提供這方面支援的網際網路產品, 目前看未有發現.

打碼指南:由貓眼線下掃碼1分購談起 | 掘金直播小程式專場總結

上面的文字版的總結,也推薦大家如有時間的話觀看原版視訊分享,現在已經上傳到了 Bilibili,連結為:www.bilibili.com/video/av348… ,歡迎大家觀看學習和收藏~

相關文章