本期分享背景:微信小程式在釋出初期是沒有什麼入口的,之後的一段時間,才確定了由線下掃二維碼進入。今天的分享內容由貓眼前端技術團隊-小程式業務組提供。團隊在一次線下投放二維碼進行促銷活動的過程中,經歷了一些波折,這裡總結並與大家分享一下!
本期主講大咖:曹宇,2015年加入美團,之後隨貓眼獨⽴。⽬前負責貓眼電影選座交易業務的Web前端和小程式業務。屬於準全棧工程師,習慣多角度思考業務和需求,關注工程質量、工程效率相關工具和理論的推⼴。
本期分享主要介紹一下4點:
- ⼩程式碼和二維碼的約束(純技術分享)
- 產出物料後改需求
- 優惠券和使用者觸達通知
- 線上監控發現的問題
⼩程式碼和二維碼的約束
小程式碼生成:
方案A:getWXACode
引數:path: 'pages/movie/index?arg=foo'
限制:長度128位元組,數量10w個
方案A是,呼叫微信文件中的 getWXACode API 生成小程式碼,引數path可以傳入帶query引數的路徑,整個path的長度限制為128位元組,生成小程式碼的數量限制是10w個,超過10w後,微信會絕句介面請求,提示超量。使用時要注意場景是否適用。
小程式碼生成:
方案B:getWXACodeUnlimit
引數:path: 'pages/movie/index' 和 scene: 'arg=foo'
限制:path不能加引數,scene引數32個字元,不限數量
方案B是,呼叫微信文件中的 getWXACodeUnlimit API 生成小程式碼,這個二維碼生成數量沒有限制,但是path部分不能帶引數,這就限制了很多業務場景,這個限制導致它只能在一個固定的落地頁。不帶引數,我們無從知道使用者是從哪裡掃過來的,也就無從定製特定使用場景的特色。在大規模投放場景下,只能使用這個方法
(小程式)二維碼生成:
方案C:createWXAQRCode
引數:path: 'pages/movie/index?arg=foo'
限制:長度128位元組,數量10w個
方案C是,呼叫微信文件中的 createWXAQRCode API 生成(小程式)二維碼,引數及限制和方案A基本一樣,但是這個二維碼可以用微信以外的一般掃碼程式來掃,你會發現它的地址是https://mp.weixin.qq.com/a/~xxxxxxxxxxx~這種,這裡應該是微信內部對path做了一個轉換,有興趣的可以查閱相關資料,這裡就不做擴充了。
上面介紹了一些⼩程式碼和二維碼的形式以及它們支援的一些東西,它們本身儲存了一些資訊,本質上和url差不多,url本身也可以理解為一種輸入,所以這些也需要我們前端去控制,去處理⼩程式碼和二維碼背後的那個字串,綜上總結功能如下:
作為連線線上和線下的入口
頁面路徑 + 引數 ~= url
⼩程式的⼀種輸入形式,類似點選 觸控...
線下掃碼1分購
業務流程
電影院掃碼(通過易拉寶展示二維碼)
支付1分錢領5元選座券 + 5元賣品券
線上⽀付,購買電影票、爆米花、甜品、飲料時使用
需求階段1
單價約束: 優惠劵成本是和影院分攤的
總價約束: 每家影院可領取的數量有限
需求階段1 —— 初步解決方案
活動落地頁增加影院引數
⽣成二維碼加上相關引數
每家影院二維碼不同
例如:path: 'pages/onecent/index?cinema=15280'
需求階段1 —— 遇到的問題
2000家影院的地推物料如何正確生產出來
並如期正確的送達
解析:此次活動,貓眼有2000家影院參與,預計至少列印4000份二維碼,因為每家影院可能投放多個易拉寶。這種物料一般是由總部統一製作,多數公司很在意自己的品牌,不會允許各個影院自己隨便處理。總部製作好,需要郵寄到各個城市,所以必須保證正確的列印與正確的郵寄,而這種人工集中處理的方式,出錯是必然的,因為二維碼必須掃過之後,才能知道是哪家影院的二維碼,很容易出錯,假使出問題的概率按1%計算,也有20多家會出問題,所以整體印刷出來後在郵寄的方案肯定是行不通的
需求階段1 —— 新的解決方案
批量生產物料模板,寄送多份
二維碼獨立推送
影院自行印刷並貼上二維碼
提供設計素材,定製物料
解析:貓眼會統一印刷一些沒有二維碼的模板,因為整體物料除了二維碼部分,其他部分是一樣的,然後在批量郵寄二維碼,如果某家影院的二維碼出現問題,總部可以把設計素材的電子版發給影院,影院的後臺可以推送二維碼,並可以自己列印二維碼,貼上上即可,基本沒有什麼差異。
實際效果:
需求階段2
領取優惠券後, 期望能點選後退
解析:一般二維碼掃進來後,之後一個活動頁,使用者領取了優惠券後,返回就直接退出了,再次掃進來還是活動頁,這就導致了使用者領取了優惠券,但是不知道去哪裡消費。所以希望載使用者點選後退的時候,能去到一個可以消費優惠券的場景。
需求如圖所示,需要在左上角出現一個返回按鍵:
需求階段2 —— 初步解決方案
掃碼後,先跳轉到首⻚,再重定向到活動頁
例子:path: 'pages/movie/index?go=pages/onecent/ index?cinema=15280'
或自定義導航欄
解析:第一種方案中'pages/movie/index'為首頁,後面部分為跳轉目標,這種方案導致二維碼又變了,而且引數變長了,會有一些麻煩和風險。第二種方法是完全自定義導航欄,相當於頁面變成了全屏的,只是右上角浮出來小程式的關閉與選單按鈕,這是就可以自己控制螢幕左上角的操作佈局了。這個方案有一些限制,比如使用了自定義導航欄,那整個小程式所有的頁面,就都是自定義的了。最後貓眼採用了第一種方案。
需求階段2 —— 遇到的問題
已經列印的二維碼物料都沒用了
需要重新生成⼆維碼
重新讓影院印刷二維碼並貼上
解析:因為路徑改變了,所以二維碼也變了,相當於之前所有電子版和列印版的二維碼全部失效,這種走步一看一步的方式肯定會出問題的。
需求階段2 —— 問題的分析
期望能控制後退
期望可以後退到非⾸頁的地址
⼀家影院在不同⼊口放置的二維碼效果如何
引數越來越多,長度超限怎麼辦
解析:產出物料後改需求是常態。
如果想後退到非首頁,路徑變更,又會導致二維碼的更改;如果是同一家影院放在不同的地方,想知道具體效果如何,還是要在二維碼上繼續增加引數;這種需求越多,引數就會越多,最後可能就會達到引數長度的限制。頻繁的變更二維碼不僅麻煩,最終還可能觸及方案A的10w個數量限制。
需求階段2 —— 新的解決方案
使用短網址服務,客戶端:
⼊口 path: 'pages/jump?id=3a5fc8'
前端請求 wx.request()
後端響應結果 { path: 'pages/movie/index?go=pages/onecent/ index?cinema=15280&utm_source=foo' }
前端重定向 wx.redirectTo()
使用短網址服務,管理端:
建立短網址 API (響應給前端)
批量查詢 修改 API(滿足頻繁更改二維碼需求)
類別(對不同活動進行區分)
附加資訊 :Map 結構(比如影院id,後退頁面地址,埋點等)
解析:貓眼提供了一個jump頁面,這個頁面提供了所有二維碼的入口,並提供一個唯一id標識,此方案需要前端,後端及PM一起協商,後端去儲存所有短網址的資訊,前端使用id去後端請求返回一個長的path,這個path是不受二維碼長度限制的,因為它不是二維碼本身。拿到path後,前端就可以重定向到指定頁面了,這樣也解決了後退多樣化的需求,埋點的需求可以通過,比如上面的 &utm_source=foo 引數,來進行控制。
綜上即實現了掃描同一個二維碼,返回不同的路徑(後端控制)。
使用短網址服務,更多:
體驗問題
掃普通連結二維碼開啟小程式
連結http://m.maoyan.com/jump?id=3a5fc8
pages/jump?id=3a5fc8
解析:最終我們生成的二維碼短網址,後面的id是不變的,我們只需要在後臺更改對應id下的小程式行為,最終來控制小程式的行為。這個方案解決了需求,但是也產生了一個問題,它多了一箇中間層jump頁面,一般jump頁面是空白的,最多加一個loading改善一下體驗,中間層jump頁面多了一次請求,可能會多消耗一點時間,進入頁面相應的會慢一點。一般的解決辦法是:首次進入就是這麼慢,然後將響應資料儲存起來,第二次掃進來就會更快一些,快取方面的技巧這裡不做擴充套件。此方案的一個進階場景是生成普通的二維碼,連結如http://m.maoyan.com/jump?id=3a5fc8,這個傳統二維碼使用任何掃碼工具都可以掃描,小程式管理後臺提供一個功能,支援掃普通連結開啟小程式,只需要經過一些配置即可。
達成掃碼,⼩結:
需求是多變的
物料產出後難以修改
短網址服務方案
優惠券和使用者觸達通知
使用者掃碼領取了優惠券後,不一定會立刻使用,我們不會等使用者來購票,我們期望可以通知領取了優惠券的使用者。
微信支付及預充值代金券
首先,介紹一下微信支付的優惠券體系
曝光⼊口:訊息列表 "微信支付" 服務號
時機:領取通知 和 到期通知(設定提前通知的時間很重要)
優惠形式:滿減,
商品限制
,預算限制提供服務:防刷,對賬,下載消耗記錄
解析:我們想投放微信支付的優惠券時,首先需要充值,比如5元的優惠券投放100個,至少需要充值500元,這對公司的現金會有要求,pm考慮到這一點。前端需要注意的主要是商品限制這一塊,在調微信支付的時候,需要將商品的標記或分類傳過去,否則不能使用優惠券。
⾃建優惠券系統
在使用微信的優惠券時,需要先墊付資金,可能會對公司的現金流產生影響,所以有的公司會考慮自建一套優惠券系統。貓眼使用的是微信提供的優惠券,但是也對自建優惠券系統做了調研分析如下
曝光⼊口:訊息列表 "服務通知"
時機:⾃由,提前收集formId/prepayId,7天內通知
問題:客訴,合規性問題
優惠形式,防刷,對賬,消耗記錄
解析:通知入口可以使用微信的訊息列表"服務通知",這個通知一般是隨時可以傳送,但是使用時也有一些約束,我們每發一個服務通知,必須要有一個憑證。這個憑證可以是使用者點選一個按鈕,提交一個表單產生的formId作為憑證,這個憑證只能使用1次;或者是使用者支付成功,返回一個prepayId作為憑證,這個憑證可以使用3次。這兩個憑證的有效期都是7天,這是前端需要特別注意的。前端需要刻意的在一些地方去收集formId,否則可能遇到想通知使用者領取優惠券,但是發不出去通知的場景。一般要儘量多收集一些,因為需求比較多變,可能由之前的傳送2個通知,到傳送3個,4個,還有別的通知等等。當我們傳送多個通知的時候,可能會遇到客戶的投訴,這就會導致訊息傳送不成功,如果一起工作的pm不瞭解這些,一定要即時告知有這個風險,如果業務流程特別依賴服務通知,那麼一定不要做任何可能違規的事情。自己做優惠券,那麼優惠形式,防刷,對賬,消耗記錄都需要自己做,這對後端來說,工作量是很大的。自建優惠券系統,要做的事情是比較多的,如果是初創公司,不想在這方面有額外的投入的話,最好是直接用微信支付提供的優惠券服務,這會省很多事。
線上監控發現的問題
無法完成登入
貓眼優惠券專案上線後,一直在觀察服務本身是否有意外情況。貓眼對多數的非同步呼叫都做了監控,發現了一個無法完成登入的問題,比如 wx.getUserInfo() 校驗 signature 不一致時,微信認為可能存在通訊問題,這次呼叫是失敗的。實際的情況是,在某種場景下,校驗永遠是失敗的,比如:微信 + android 5.x以下,使用者暱稱中含emoji時。這是這種場景下微信本身存在的一個問題,目前沒有什麼解決方案,只能等android 5.x版本消失就沒問題了。當前的處理辦法是,發現符合上述特徵時,暫時忽略略簽名檢查,使用者暱稱的大概還是能獲取到的,作為展示沒有太大問題。
所有微信介面呼叫可能失敗
通過node呼叫微信的所有介面時,有時可能會超時,比如獲取使用者的暱稱,頭像這些東西,使用者點選授權,⼩程式端可能會出現卡頓,等了好久後,提示網路錯誤。這種情況是偶發的,約 0.5%,貓眼的日活基本在百萬以上,最高在300w左右或更高,這種場景下,0.5%就牽涉到了很多使用者了,一般使用者遇到卡頓,可能會認為小程式有問題,導致這個使用者可能就會流失了。經過調研,確定為網路線路穩定性問題,因為貓眼的機房在北京,小程式的機房在上海。目前有一個解決方案是,在使用api.weixin.qq.com這個域名出現問題時,可以使用api2.weixin.qq.com在試一試,即做一個容災方案。具體到貓眼本身是,做了一個延遲重試策略,這個功能上線後,使用成功率的變化為 99.5% => 99.99% 的提升。
監控工具推薦
Central Application Tracking
貓眼使用的是自己的監控工具,名為 cat。這個工具是在和大眾點評合併之後,大眾點評技術團隊分享的一套監控系統,為開源專案。之前在使用其他監控系統時,遇到的問題是,我們期望在遇到異常是,一定要對異常進行一個分類,需要知道異常的規模是什麼樣的,其他的監控系統,要麼是在大規模報警的時候就崩潰了,要麼就是隻做日誌,不做分類,導致了我們"只見樹木,不見森林"。使用 cat,可以精確的控制分類,吞吐量特別大,滿足了我們前端和node端的監控需要,有興趣的可以去github上了解一下。
以上,由貓眼線下掃碼1分購談起,分享了靠譜的線下掃碼活動需要技術團隊提供哪些⽀支撐,這就是這次活動的內容。