大部分的棄購挽回靠電子郵件。電話的做法不一樣,因為電話是唯一需要拿捏判斷的 一步。寫封信給已經買了的人,無傷大雅;打電話給這個人,對雙方都是尷尬的 一分鐘。
所以這篇指南的大部分內容不是講怎麼播號,而是講在此之前必須成立的每一件事: 確實存在一筆結帳、對方確實沒買、現在不是對方的深夜、對方從未要求你別再打來、 而且你對名字的掌握足夠用來開場。
預留半小時。大部分時間花在 Shopify 上,不在這裡。
簡短版
- 建立一個 Shopify 應用程式,勾選四個權限,並安裝它
- 從 Shopify 複製兩個不同的金鑰
- 把兩個都儲存成 Omni Octo 的連線
- 請 Octo 搭建流程
- 複製 webhook 網址,貼到 Shopify,貼兩次
- 用一分鐘的等待時間做測試
卡住人的是第 1 步和第 5 步。它們各有獨立的章節。
第 1 步 — 建立 Shopify 應用程式並安裝
在 Shopify 中:設定 → 應用程式和銷售管道 → 開發應用程式 → 建立應用程式。 取一個你之後認得出來的名字。
勾選這些權限
開啟設定 → 管理員 API 整合 → 設定,授予:
| 權限 | 用途 |
|---|---|
read_orders | 查明這位購物者最後有沒有下單 |
read_all_orders | 對超過 60 天的訂單做同一項核查 |
read_customers | 對方的姓名和電話號碼 |
read_products | 讀取購物車裡有什麼 |
你會想找結帳權限,但找不到。 read_checkouts 確實存在,但 Shopify
把它列為受保護權限:它不在你能勾選的清單裡,申請它需要 Shopify 本身的核准。
沒有它就去呼叫結帳 API,Shopify 會回答:
This action requires merchant approval for
read_checkoutsscope.
這沒有關係,而這正是本流程從不讀取結帳的原因。它改問一個更好的問題 —
有沒有出現訂單? — 這只需要 read_orders。
安裝它
這一步所有人都忘。 設定應用程式不會有任何效果,直到你在應用程式的 Overview 頁面按下安裝應用程式。在那之前,沒有可複製的管理員 API 存取 權杖,後續每一步都會失敗,而且失敗的樣子像是別的東西壞了。
複製兩個金鑰,別搞混
你需要兩樣不同的東西,而且它們都長得像隨機字串,很容易混淆。
| 東西 | 在哪裡 | 作用 |
|---|---|---|
| 管理員 API 存取權杖 | 應用程式的 API 憑證分頁,安裝之後。以 shpat_ 開頭 | 讓 Omni Octo 向 Shopify 提問 |
| Webhook 簽署金鑰 | 設定 → 通知 → Webhook,頁面底部 | 讓 Omni Octo 驗證 Shopify 傳來的訊息 |
一個用來和 Shopify 對話。一個用來核實訊息真的是 Shopify 傳的。把它們弄混是 整套設定裡代價最高的錯誤,而且症狀和原因毫無相似之處 — 見 當一切毫無動靜時。
第 2 步 — 把兩個金鑰都存進 Omni Octo
進入連線頁面,一次新增一個。
管理員 API 存取權杖。 按新增連線,選「其他」下的 HTTP / API
金鑰卡片。貼上 shpat_ 權杖。給連線取一個在清單裡認得出來的名字 —
「Shopify 管理員 API 權杖」比「Shopify」好。
Webhook 簽署金鑰。 再按一次新增連線,選 Signing secret,然後貼上 通知頁面上的金鑰。表單上寫著值得記住的那句話:
The secret the sender signs with, not a key you call them with.
兩個連線,兩個方向。在搭建任何東西之前,把兩個都存好。
第 3 步 — 請 Octo 搭建流程
自動化不是你寫的。開啟聊天,把想要的東西描述出來,包括把購物者儲存為聯絡人 那部分:
當有人在我的 Shopify 商店棄購時,等大約三十分鐘再打電話。先把這個人儲存為 聯絡人,連同姓名和電話號碼,讓智慧體能直呼姓名地打招呼。用我的 Shopify Cart Recovery 智慧體,從 +1 555 0100 打出。
聯絡人那部分要講清楚。 不講的話,Octo 也會搭出一個能跑的流程,但智慧體 開場會是「你好」而不是「你好,Sarah」— 因為問候語裡的名字取自你的聯絡人 紀錄,而不是 Shopify 的訊息。多講這一句,就是挽回電話和陌生開發電話的差別。
Octo 會讀取你的連線、找到你的智慧體,如果你存了不止一個簽署金鑰,它可能會問 要用哪一個。回答簽署金鑰,不是管理員權杖。
然後確認它顯示為使用中。 仍標為草稿的流程會拒絕 Shopify 傳來的一切, 而 Shopify 的傳送紀錄裡會堆滿看起來像網址寫錯了的失敗。
第 4 步 — 把網址交給 Shopify
開啟流程,在圖上方找到 Webhook endpoint 卡片。它顯示網址和一個狀態:
- Ready — 已上線,且已儲存簽署金鑰
- Inactive — 已暫停或仍是草稿,所以 Shopify 的訊息會被拒絕
按 Copy。然後在 Shopify 裡進入設定 → 通知 → Webhook → 建立 Webhook,建立兩個,都貼上同一個網址:
| 事件 | 格式 | 原因 |
|---|---|---|
| 結帳頁面建立 | JSON | 有人進入結帳時觸發 |
| 結帳頁面更新 | JSON | 有人填入更多資料時觸發 |
為什麼要兩個,說白了
有人剛開始結帳,Shopify 就會通知你 — 而那往往還在對方輸入電話號碼之前。 對方每填一項,Shopify 就再通知一次,而後來的某一則訊息通常就是帶號碼的那則。
只訂閱第一個,你的流程啟動時沒有人可打。兩個都訂閱,就有人可打。
同一個下拉式選單裡還有購物車建立,聽起來對,其實不是。購物車只是個 籃子 — Shopify 沒有它的電子郵件、電話和姓名,所以無人可打。只有當你想要一個 無害的訊號來確認 webhook 確實在送達時,才用它。
這些 webhook 要在 Shopify 管理介面的這一頁手動建立。 不要透過 Shopify API 建立。兩種我們都測過:在這一頁建立的大約三十秒內就到了;透過 API 建立的, 一個多小時裡一則也沒到,而且 Shopify 兩種情況都不回報錯誤。
在其中一個上按傳送測試。一分鐘內,流程的執行清單裡應該會出現點什麼。 這一下點按是證明鏈路通了最快的方式,而且不花一毛錢。
第 5 步 — 一分鐘內測試
請 Octo 把等待時間改成一分鐘。
先把你自己的電話號碼放到一筆顧客紀錄上。 在 Shopify 中:顧客 → 選一位用你電子郵件的顧客,或建立一位 → 加上你的電話號碼並儲存。
要在下單之前做這件事。只在結帳頁面輸入電話號碼不夠 — Shopify 的單頁結帳 在付款之前沒有送出它的步驟,你在那裡輸入的號碼可能根本到不了 Shopify。 我們為此浪費了一個晚上。顧客紀錄上的號碼從第一則訊息起就跟著結帳一起傳遞, 這才讓測試成立。
然後:
- 以該顧客身分登入你的店面
- 把商品加進購物車
- 進入結帳,讓頁面載入完成
- 關閉分頁
Shopify 送出訊息後大約一分鐘,你的手機應該會響。你不需要在結帳表單裡填任何 東西。
然後請 Octo 把等待時間改回三十分鐘。 若維持一分鐘,流程會打給那些還在輸入 卡號的人。
當一切毫無動靜時
這一節就是我們當初希望手邊有的。按順序往下查 — 每一條都是真實擋下過一次 測試的東西。
流程根本沒收到東西
你按了安裝應用程式嗎? 設定權限不等於安裝。
webhook 是在 Shopify 管理介面建的,不是透過 API? 見上文。這一條讓我們 花的時間遠超其他所有。
流程是使用中嗎? 草稿會拒絕一切。
你是剛剛建立或編輯了流程? 給它幾分鐘。全新的流程在被接起來的短暫時間裡 會回應「尚未就緒」,而 Shopify 會自行重試。
先查 Shopify 自己的傳送紀錄,就在你建立的那個 webhook 上。如果 Shopify 沒有顯示傳送,問題在線路的那一側,Omni Octo 裡沒有任何東西能解釋它。
Shopify 傳了,但流程拒絕
幾乎總是金鑰用錯了。用哪個金鑰簽署取決於 webhook 是怎麼建立的,而這並 不直觀:
| webhook 建立方式… | 用什麼簽署 |
|---|---|
| 在通知頁面上手動建立 | 同一頁面上的簽署金鑰 |
| 由某個應用程式透過 API 建立 | 該應用程式自己的 API 金鑰 |
如果你照著本指南做,你要的是第一列。把流程指向第 2 步的簽署金鑰連線。
流程啟動了,但沒人被呼叫
有電話號碼嗎? 開啟這次執行,看到達了什麼。沒有號碼就沒有電話,這是設計 使然。
只加進購物車不夠。 購物車本身什麼都不會告訴 Shopify。對方必須抵達結帳 頁面,而且 Shopify 必須有聯絡對方的途徑 — 來自登入中的帳號,或來自對方填寫 的內容。
輸入電話號碼不等於送出了它。 Shopify 的單頁結帳在付款前沒有「繼續」 按鈕,所以別人輸入的號碼可能根本到不了 Shopify。可靠的解法是下一條。
在顧客紀錄上放一個電話號碼。 在 Shopify 中:顧客 → 那個人 → 加上電話。登入中的購物者的號碼會從第一則訊息起就跟著結帳傳遞,上面那些問題 就都不重要了。讓我們自己的測試跑通的,就是這一個改動。
用簡訊登入不算數。 如果 Shopify 是傳簡訊驗證碼讓人登入的,那個號碼屬於 Shopify 的登入系統。它永遠不會進入你的顧客紀錄,你也用不了它。
在試用商店或密碼保護的商店上測試
你需要店面密碼才能在自己的商店購物,在網路商店 → 偏好設定 → 密碼 保護。
不要把 onlineStoreUrl 當成商品已發布的標誌。 在密碼保護的商店裡,
Shopify 對每一件商品都把它回報為空,無論發布與否。我們把已經發布的商品
又發布了一遍,白白浪費時間。帶著密碼打開商品頁面,親眼看一下就好。
什麼會攔下一通電話
四道核查。每一道都是執行安靜而正確地結束的地方,而不是失敗。之後你看到的 樣式各不相同,所以分清哪個是哪個是值得的。
對方買了。 等待結束後,我們問 Shopify 那筆結帳現在有沒有對應的訂單。 如果有,執行停止。等待存在的全部理由就是這個:Shopify 在有人輸入電子郵件的 那一刻就把結帳計為棄購,而那一刻對方往往還在摸自己的卡片。
我們無法判斷。 如果這道核查失敗 — 權杖過期、權限被移除、網路問題 — 執行會不打電話就停止。往另一個方向猜,就會打給已經付過錢的人。
這兩種都發生在第一個步驟之前,因為核查是觸發器的一部分。所以這樣停止的 執行會顯示為已完成、沒有執行任何步驟 — 什麼都沒儲存,也沒播任何號。 目前,執行畫面還無法寫明是這兩種中的哪一種;如果執行不斷以無步驟完成而你 期待的是電話,先檢查管理員 API 連線。
那是對方的深夜。 可撥打時段來自號碼的國碼,而我們無法放進某個時區的 號碼,就是一個我們不會撥的號碼。跨多個時區的國家,必須每一處都是白天。
對方要求你別再打。 該號碼的勿擾項目會在播號之前攔下電話,執行記錄的是 拒絕,而不是失敗。
這套東西不會做什麼
它不會替你建立 Shopify 的 webhook。 網址要你自己貼,貼兩次。
它不會捏造電話號碼。 沒有號碼,就沒有電話。
把挽回電話當作「至少一次」,而不是「恰好一次」。 購物者每改動一樣東西, Shopify 就傳一則訊息,每一則都啟動自己的一次執行。這些執行會被歸併,所以 通常只產生一通電話,但訊息之間隔得夠久時,仍可能出現第二通。把它指向真實 顧客之前,值得先知道這一點。
保持 API 版本是新的。 管理員 API 連線記錄著要使用的 Shopify API 版本。 Shopify 對每個版本大約支援一年,然後不聲不響地改用舊版本回應你,而不告知。 如果已經過了一年,去更新它。