TinyPilot:第 24 个月
一句话总结
如何让 TinyPilot 的销售保持可持续?
亮点
- TinyPilot 的收入创下 7.4 万美元的历史新高。
- 我正在探索软件授权的最佳方案。
- 我仍在寻找一个令我心动的 Web 框架。
目标评分
每月初,我都会定下当月想要完成的目标。以下是本月目标的完成情况:
创建用于安装 TinyPilot 的自包含 tar 包
- 结果:我们现在已有一个可用的 tar 包
- 评分:A
TinyPilot 的安装流程随着时间推移变得越来越复杂。它需要从多个代码仓库和第三方依赖中拉取代码,理清这些关系也变得越来越困难。
我们目前正在通过将所有内容整合到单个 tar 包中来彻底改造安装流程。这样可以将所有依赖集中到一个清晰的位置。我们正在将免费版 TinyPilot 切换到新的更新系统,之后很快也会迁移 TinyPilot Pro。
完成关于 TinyPilot 网站改版的长篇博文初稿
- 结果:已完成初稿
- 评分:A
我原以为写这篇博文会很容易,因为我在回顾中已经写了大量相关内容,但长篇文章的写作风格不同,所以仍需大量重写。这篇文章有 5200 字,大约是我平时文章长度的两倍,所以我正在努力精简。
将付费搜索广告的 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 月本身并无任何特别之处。
TinyPilot 以往所有创纪录的月份都与新产品发布或好评等一次性事件有关。但 6 月实际上只是一个平淡无奇的普通月份。而这正是好事!这表明我们无需依赖外部事件来推动销售,就可以复制现有的做法。
网站访客数较上月有所下降,但这只是因为 5 月由于我上一篇博文而异常偏高。我们整体的访问量仍显著高于第一季度。我将访客量的增长归功于新的营销活动。
TinyPilot Pro 用户如何证明其授权?
我一直希望 TinyPilot 的软件即便不再销售新硬件也能独立维持下去。用户购买 TinyPilot 硬件时会免费获得我们的高级软件,但一段时间后,需要有一种付费方式来为软件维护提供资金。
我早在 2020 年 12 月就推出了 TinyPilot 的付费版本 TinyPilot Pro。我最初计划在发布时就加入授权密钥验证,但我推迟了这一功能,认为直到 2021 年底授权开始到期前都不需要它。
如今,18 个月过去了,TinyPilot Pro 仍然不会检查用户是否拥有有效授权。我估计约有 1/3 的用户的授权已过期而自己却未察觉。
我计划在用户升级到最新版本时增加有效授权检查。这样,如果用户对当前版本满意,就可以永久使用下去。如果他们想要最新版本,就需要在初始的一年授权到期后为软件更新付费。
要验证用户是否有权下载最新更新,我需要一种方式让用户向更新服务器证明他们拥有有效的 TinyPilot Pro 授权。
以下是我正在考虑的几种方案:
设备 ID
TinyPilot 运行在 Raspberry Pi 上,每台 Pi 设备都有一个硬件序列号,可以通过如下方式获取:
$ cat /proc/cpuinfo | grep Serial | cut -d ' ' -f 2
10000000ecf8821b我们可以在向客户出售前记录每台 Pi 的设备 ID。当用户尝试升级时,只需检查其设备 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 是否已预先注册。
- 如果设备未预先注册,则提示用户输入订单 ID 和邮箱,以便我们自动查找其订单。
- 如果通过订单 ID + 邮箱无法自动找到其订单,则请用户发送邮件联系客服,以便我们手动配置授权。
在我能想到的方案中,这似乎最不容易出错,也给终端用户带来的工作量最小。
凡入 Amazon 卖家市场者,弃绝一切希望
很长一段时间以来,我一直在考虑在 Amazon 上销售 TinyPilot,因为许多人把 Amazon 当作网购的一站式商店。我一直对此有所抵触,因为注册成为 Amazon 卖家似乎是一个痛苦而繁琐的过程。亲身经历后,我可以说,实际过程比我预想的还要痛苦和繁琐。
光是让我能够在 Amazon 上架产品就花了三周时间。每隔几天,Amazon 就会告诉我需要新的审批,或需要我就身份或产品提供证明。
首先,Amazon 需要用我的驾照和信用卡号验证我的身份。然后,我需要在实时视频通话中手持驾照置于脸前并弯折它,以证明它不是打印件。
随后,Amazon 冻结了我的账户一天,原因是无法验证我的信用卡。而这张信用卡已经在 Amazon 存档一年,我用它在 Amazon 上进行了约 5 万美元的消费。
接着,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 日达发货”,但我们并不提供 UPS 配送。我回复了该客户的消息,但不确定接下来该怎么做。我应该取消订单并冒着被 Amazon 处罚的风险吗?还是等待客户回复并冒着因发货延迟而被 Amazon 处罚的风险?我最终等了一天后取消了订单。随后,该客户又下了同样的订单,于是我们就用 USPS 发货了,也没有收到任何投诉。
几天后,另一位 Amazon 客户发消息称,她对产品迟迟未到“非常失望”,因为她付了 10 美元加急运费。我查看了物流信息,发现我们已通过 USPS Priority 提前一天发货,但 USPS 配送延迟了。这显然超出了我们的控制范围,但我怀疑客户并不理解从第三方卖家购买与直接从拥有自有配送车队的 Amazon 购买之间的区别。
我们有时也会收到直接下单客户的此类投诉,但远没有在 Amazon 上看到的频率高。
仍在寻找心仪的 Web 框架
正如我在上次更新中提到的,我正在重建 WanderJest,这是一个用于寻找现场喜剧演出的工具,我在疫情开始时将其搁置了。

我使用 Go、VanillaJS 和 SQLite 对 WanderJest 网站进行的重构,仍在进行中。
在尝试使用 Angular 和 Vue 等 SPA(单页应用)框架多年后,我正使用 Go + VanillaJS + SQLite 这种“回归基础”的技术栈重写 WanderJest。Chris Ferdinandi(克里斯·费迪南迪)在他的文章 “SPAs were a mistake.”(《单页应用是个错误》)中表达了我的一些困扰。
我比以往尝试过的任何 Web 框架都更喜欢当前的技术栈,但我仍然谈不上热爱。我大部分时间都花在将各种东西粘合在一起的繁琐任务上。
例如,为了让用户能够创建包含照片、简介以及指向其他社交网络链接的个人资料,我需要:
- 创建用于让用户创建和编辑个人资料的网页表单
- 创建用于接收用户提交内容的服务端端点
- 创建用于表示个人资料信息的数据模型
- 编写序列化/反序列化代码,以便在数据存储中移入和移出数据
- 编写用于从数据存储中插入和检索数据的 SQL 查询
- 创建用于渲染个人资料信息的网页界面
这比我用过的其他框架步骤要少,但这些事情真的很枯燥。
Phoenix LiveView 已经在我的待尝试清单上待了一年。它是 fly.io 那些潮人们都为之兴奋的技术。Phoenix 的承诺之一就是能自动完成我上面列出的许多重复性任务。Chris McCord(克里斯·麦考德)做了一个精彩演示,用 Phoenix 在 15 分钟内构建了一个基本的 Twitter 克隆。
同时,我也担心“这山望着那山高”的心态让我不断在不同框架之间跳来跳去,却没有把任何一个技术栈学精。也许一个折中的好选择是 Ruby on Rails,我认为它能提供与 Phoenix 相似的开发体验,但拥有更成熟的生态系统。
总结
完成了什么?
- 开始在 Amazon 上销售 TinyPilot
- 完成了新长篇博文的初稿
- 完成了 TinyPilot 安装包的生成流程
经验教训
- Amazon 卖家平台比看起来还要令人不快。
下月目标
- 确定 TinyPilot 授权管理的最终方案。
- 将 TinyPilot Community 迁移至下一代更新系统。
- 发布关于 TinyPilot 网站改版的博文。
随机一篇博客