TinyPilot:第 24 個月
一句話總結
我該如何讓 TinyPilot 的銷售維持永續?
亮點
- TinyPilot 創下 $74k 營收的歷史新高。
- 我正在思考軟體授權的最佳做法。
- 我仍在尋找一個能讓我真心喜愛的網頁框架。
目標評分
每個月月初,我都會訂下想完成的目標。以下是本月目標的達成情況:
建立用於安裝 TinyPilot 的獨立 tarball 壓縮檔
- 結果:我們現在已有可運作的 tarball 套件
- 評分:A
TinyPilot 的安裝流程隨著時間變得越來越複雜。它會從多個程式碼儲存庫和第三方相依套件中拉取程式碼,要追蹤這些關聯性也變得愈來愈困難。
我們目前正透過將所有內容整合到單一 tarball 來徹底改造安裝流程。這樣能將所有相依套件集中到清楚的位置。我們正在將免費版 TinyPilot 切換到新的更新系統,之後很快也會遷移 TinyPilot Pro。
完成關於 TinyPilot 網站重新設計的完整部落格文章初稿
- 結果:已完成初稿
- 評分:A
我原本以為寫這篇部落格文章會很容易,因為我在回顧文章中已經寫了很多相關經驗,但完整長文的寫作風格不同,所以仍需大幅重寫。文章長達 5,200 字,大約是我平常文章的兩倍長,因此我正在設法精簡內容。
將付費搜尋廣告的 ROAS(廣告投資報酬率)提升至 2.0
- 結果:將 ROAS 從 1.79 提升至 1.99
- 評分:A
與 TinyPilot 合作的數位行銷自由工作者將廣告投資報酬率提升至 1.99。我估計,每投入 1 美元的廣告費,大約可賺得 0.55 美元的利潤。
可惜的是,我無法單純將廣告支出加倍就讓銷售額跟著加倍,因為當你試圖爭取更高的搜尋曝光佔比時,成本也會隨之上升。儘管如此,我對目前的表現感到滿意,我們也正持續探索新的行銷管道。
TinyPilot 數據統計
| 指標 | 2022 年 5 月 | 2022 年 6 月 | 變化 |
|---|---|---|---|
| 不重複訪客 | 14,296 | 10,056 | -4,240 (-30%) |
| 總瀏覽量 | 24,131 | 18,764 | -5,367 (-22%) |
| 銷售營收 | $54,844.20 | $72,476.80 | +$17,632.60 (+32%) |
| 企業訂閱 | $47.75 | $47.75 | 0 |
| 權利金 | $3,269.56 | $1,710.27 | -$1,559.29 (-48%) |
| 總營收 | $58,161.51 | $67,355.75 | +$9,174.24 (+15%) |
| 獲利 | $6,445.38 | -$4,230.17 | -$10,675.55 (-inf%) |
這是 TinyPilot 有史以來營收 最強勁(更新:第二強勁,詳見下方備註)的一個月。令人振奮的是,6 月其實沒有任何特別之處。
過去所有創下紀錄的月份都與某種一次性事件有關,例如新產品發布或正面評價。但 6 月實際上只是個平淡無奇、沒有發生任何異常事件的月份。而這正是好事!這表示我們可以重複目前的做法,而無需依賴外部事件來推動銷售。
網站訪客數相較上月下滑,但僅是因為 5 月份因我上一篇部落格文章而異常偏高。整體訪客數仍顯著高於第一季。我將訪客數的增加歸功於我們新的行銷活動。
TinyPilot Pro 使用者如何證明其授權?
我一直希望 TinyPilot 的軟體本身就能永續經營,無論我們是否持續銷售新硬體。使用者在購買 TinyPilot 硬體時可免費獲得我們的進階軟體,但在某個時間點之後,需要有付費機制來支持軟體的維護。
我在 2020 年 12 月推出了名為 TinyPilot Pro 的付費版本。我原本計畫在推出時就加入授權金鑰檢查,但我暫緩了該功能,認為要到 2021 年底授權開始到期前才需要它。
如今已過了 18 個月,TinyPilot Pro 仍從未檢查使用者是否持有有效授權。我估計約有三分之一的使用者授權已過期卻渾然不知。
我計畫在使用者升級到最新版本時加入有效授權的檢查。這樣一來,若使用者對目前版本感到滿意,就可以永久使用下去。若想取得最新功能,則在初始一年授權到期後,需為軟體更新付費。
為了確認使用者是否有權下載最新更新,我需要一種方式讓使用者向更新伺服器證明其擁有有效的 TinyPilot Pro 授權。
以下是我考慮中的選項:
裝置 ID
TinyPilot 執行於 Raspberry Pi 上,每台 Pi 裝置都有一個硬體序號,可以像這樣取得:
$ cat /proc/cpuinfo | grep Serial | cut -d ' ' -f 2
10000000ecf8821b我們可以在銷售給客戶前記錄每台 Pi 的裝置 ID。當使用者嘗試升級時,只需檢查其裝置 ID 是否已預先註冊,再依此啟用。
- 優點
- 對使用者來說很方便——不會遺失或忘記裝置 ID
- 缺點
- 需要我們追蹤所有裝置 ID
- 在裝置製造流程中增加一道額外步驟
- 對於在我們開始記錄裝置 ID 之前購買的使用者,仍需另尋解決方案
訂單資訊
目前,當客戶想下載官方 TinyPilot 磁碟映像檔時,我們會要求提供訂單編號以及與購買相關的電子郵件地址:

TinyPilot 網站目前是根據使用者能否提供訂單詳細資訊來授予 TinyPilot 映像檔的下載權限。
我們可以在 TinyPilot 網頁應用程式中使用相同的邏輯來管控升級。
- 優點
- 可大幅減少行政作業,因為我們無需追蹤金鑰或裝置 ID,畢竟已儲存了訂單資訊
- 適用於所有過去的客戶,因為我們已擁有他們的訂單資訊
- 缺點
- 終端使用者不一定知道自己的訂單資訊
- 有時他們是透過經銷商購買,或是由公司內的其他人購買裝置
- 每當我們透過新通路(例如 Amazon、eBay)開始銷售,就必須撰寫客製化程式碼來查詢該通路的訂單資訊
- 終端使用者不一定知道自己的訂單資訊
印製的啟用金鑰
我們可以產生一組啟用金鑰,類似啟用 Microsoft Windows 或 Office 的方式(例如 1F9PA-V4JD5-4JPOM)。這些金鑰可以印出並隨附於每台裝置中,使用者輸入該金鑰即可證明其擁有授權。
- 優點
- 無論使用者是直接向我們購買,還是透過 Amazon、eBay 等通路購買,運作方式皆相同
- 缺點
- 使用者容易遺失或忽略訂單中附帶的紙本單據
- 對於在我們開始發放啟用金鑰之前購買的使用者,仍需另尋解決方案
內建於軟體中的授權
我們會將映像檔燒錄到客戶的裝置上,因此理論上可以在每台客戶裝置上放置一個獨特的金鑰檔案來授予 TinyPilot Pro 授權。
- 優點
- 無論使用者是直接向我們購買,還是透過 Amazon、eBay 等通路購買,運作方式皆相同
- 使用者不會遺失金鑰
- 缺點
- 極度不切實際且實作複雜
- 我們必須為每位客戶產生客製化的磁碟映像檔,並確保客戶始終安裝其專屬的映像檔
- 對於在我們開始內建啟用金鑰之前購買的使用者,仍需另尋解決方案
- 極度不切實際且實作複雜
綜合方案
我傾向於採用混合式做法,盡可能使用最自動化的方法,但針對邊緣情況回退到較手動的方法:
- 檢查裝置的硬體 ID 是否已預先註冊。
- 若裝置未預先註冊,請使用者輸入訂單編號與電子郵件,以便我們自動找到其訂單。
- 若無法透過訂單編號與電子郵件自動找到訂單,請使用者來信聯絡客服,讓我們手動核發授權。
在我能想到的選項中,這似乎是最不容易出錯、也最能減輕終端使用者負擔的做法。
放棄希望吧,踏入 Amazon 賣家市集的人
長久以來,我一直考慮在 Amazon 上銷售 TinyPilot,因為許多人把 Amazon 當作一站式的線上購物平台。我之所以遲遲未行動,是因為申請成為 Amazon 賣家看起來就是件痛苦又繁瑣的過程。實際經歷過後,我可以說,它比我想像的還要更痛苦、更繁瑣。
我花了三週才終於能在 Amazon 上架產品。每隔幾天,Amazon 就會告訴我需要新的核准,或必須證明關於我身分或產品的某些事項。
首先,Amazon 必須透過我的駕照和信用卡號碼來驗證身分。接著,我必須參加現場視訊通話,手持駕照對著臉部並彎折駕照,以證明它不是列印的複印件。
接著,Amazon 以無法驗證我的信用卡為由凍結帳號一天。這張信用卡我已在 Amazon 上登記了一年,並用它在 Amazon 上消費了約 $50k。
接著,Amazon 又凍結了我的帳號,以便驗證我是否有權使用「TinyPilot」品牌名稱。我向他們出示了我是 TinyPilot, LLC 擁有者的證明,並寄送了產品側面印有「TinyPilot」字樣的照片。

我寄給 Amazon 作為品牌名稱「TinyPilot」出現在產品上的證明照片
他們說會在三天內審查,但實際花了 10 天。他們的結論是,我的照片不足以充分證明「TinyPilot」已永久固定於產品上……

Amazon 認為「TinyPilot」並未充分永久地固定於我的產品上。
因此,我寄送了更聚焦於品牌名稱的新照片,直到那時他們才終於核准了產品。

這樣固定得夠永久了嗎,Amazon?
新的問題是,如果搜尋「tinypilot」,TinyPilot 根本不會出現在搜尋結果中:

搜尋「tinypilot」時,TinyPilot 並未出現在搜尋結果中
特別詭異的是,Amazon 自家的自動完成建議卻顯然全都與我的產品有關:

Amazon 對「tinypilot」的搜尋建議顯然全都與我的產品有關,但產品仍未出現在搜尋結果中。
即使搜尋「tinypilot kvm over ip」,我的產品也要到搜尋結果的第二或第三頁才會出現。
我最後乾脆在 Amazon 上購買廣告,這才終於帶來了最初的幾筆銷售。

搜尋「tinypilot」時,TinyPilot 並未出現在搜尋結果中
我希望最艱難的部分已經過去,所以會繼續堅持下去,看看隨著在 Amazon 上累積評價,銷售是否會成長。
Amazon 客戶是截然不同的族群
Amazon 客戶的期望似乎與直接從 TinyPilot 網站購買的客戶截然不同。
第一位透過 Amazon 購買的客戶在訂單中留言要求「請用 UPS 2-day 寄送」,但我們並未提供 UPS 寄送服務。我回覆了該客戶的訊息,但不確定下一步該怎麼做。我該取消訂單並承擔來自 Amazon 的處罰嗎?還是等待客戶回覆並承擔因延遲出貨而被 Amazon 處罰的風險?我最後等了一天後在未收到回覆的情況下取消了訂單。接著,該客戶又下了相同的訂單,於是我們就用 USPS 出貨,也未再收到任何抱怨。
幾天後,另一位 Amazon 客戶傳訊息給我,說她對產品尚未送達感到「非常失望」,因為她已付了 $10 的加急運費。我查詢了物流追蹤,發現我們已透過 USPS Priority 提早一天出貨,但 USPS 配送延誤了。這顯然非我們所能控制,但我懷疑客戶並不理解向第三方賣家購買與直接向擁有自家配送車隊的 Amazon 購買之間的差別。
我們有時也會收到直接下單客戶的這類抱怨,但頻率遠不及在 Amazon 上看到的情況。
仍在尋找令人喜愛的網頁框架
如我在上次更新中所提,我正在重建 WanderJest,這是一個用來搜尋現場喜劇演出的工具,我在疫情初期將其暫停了。

我使用 Go、VanillaJS 與 SQLite 重新實作 WanderJest 網站的進行中版本。
在多年嘗試使用 Angular 和 Vue 等 SPA 框架後,我正以 Go + VanillaJS + SQLite 作為「回歸基本」的技術堆疊來重寫 WanderJest。Chris Ferdinandi(克里斯·費迪南迪)在他的文章 「SPAs were a mistake.」中道出了我的部分挫折。
我比起過去嘗試過的任何網頁框架,都更喜歡目前的技術堆疊,但我仍稱不上熱愛它。我大部分時間都花在繁瑣的整合工作上。
例如,為了讓使用者能在 WanderJest 上建立包含照片、簡介及連結至其他社群網路的個人檔案,我需要:
- 建立網頁表單,讓使用者能建立與編輯個人檔案
- 建立伺服器端端點以接收使用者提交的資料
- 建立資料模型來表示個人檔案資訊
- 撰寫序列化/反序列化程式碼,以便在資料儲存區之間搬移資料
- 撰寫 SQL 查詢以在資料儲存區中插入與擷取資料
- 建立用於呈現個人檔案資訊的網頁介面
這比我用過的其他框架步驟要少,但這些事情真的很無聊。
Phoenix LiveView 在我的清單上已經有一年了。這正是 fly.io 上那些很酷的傢伙們熱衷的技術。Phoenix 的部分承諾是自動化我上面列出的許多重複性工作。Chris McCord(克里斯·麥考德)曾做了一個精彩的示範,展示如何用 Phoenix 在 15 分鐘內打造一個基本的 Twitter 複刻版。
同時,我也擔心自己抱持「別人的草地比較綠」的心態,不斷在不同框架間跳來跳去,卻沒有把任何一套技術堆疊學精。也許一個不錯的折衷方案是 Ruby on Rails,我認為它與 Phoenix 有類似的開發體驗,但擁有更成熟的生態系。
總結
完成了哪些事?
- 開始在 Amazon 上銷售 TinyPilot
- 完成了一篇全新完整部落格文章的初稿
- 完成了 TinyPilot 安裝套件的產生流程
經驗教訓
- Amazon Seller Marketplace 比看起來還要更令人不快。
下個月的目標
- 確定 TinyPilot 授權管理的最終方案。
- 將 TinyPilot Community 遷移至下一代更新系統。
- 發布關於 TinyPilot 網站重新設計的部落格文章。
隨機一篇部落格