我在 GitHub 上发布了几个开源项目,其中一些很受欢迎。我倾向于不断优化它们,还不时发布一些问题。一些用户通常会告诉我迷失在我的邮件里,我也会忘掉存储库,只能并将新项目添加到待办事项列表中提醒自己。
每次我看到某个问题消息通知的时候,我会偶尔在便笺上写下问题,但我总想找个借口来简化流程。前几天看到外卖打印小票订单,我就想能不能也利用一下票据打印机,在每次将问题添加到我的一个存储库时,打印出来一个小票。
于是我就开始研究,想不到,它做成了!
我把它公布在推特上,供大家品鉴。没想到反应还是很强烈。

为了让大家能够深入研究,我将向各位展示我使用的详细内容,以及我是如何设置它们的。
硬件清单
下面我们开始!我有一台热敏收据打印机和一些将数据录入其中的方法。我最终使用了以下这些物件:
- 爱普生 TM-T88IV 打印机
- Raspberry Pi Zero W(树莓派 Zero W)
- 微型 USB 转 USB 适配器
- USB B 型电缆
我之所以选择爱普生热敏打印机,原因它使用的是 ESC/POS 命令集,它已经建立了各种编程语言的库。还有一个重要原因,它们在二手市场上随处可见,我还可以在网上以相当便宜的价格买到票据用纸。
我需要的另一部分是一些硬件,用于从互联网连接到打印机,然后将实际数据发送给它。
这些设备需要连接到我的电脑上,是一个功能齐全的设备。我有一个旧的Raspberry Pi Zero W,我没怎么太用,一直闲在角落里吃灰。所以我选择它做为打印机接口板。
Raspberry Pi只有一个微型 USB 端口,所以我通过适配器和 USB Type-B 电缆将它们连接到票据打印机。
将数据发送到打印机
现在,我们已经连接了打印机。
现在我需要一种方法从Raspberry Pi向打印机发送数据。可以使用 Node 或 Python 等编程语言完成,我是一名 PHP 开发人员,而且我喜欢扩展编程语言的原有限制,也会努力做到这一点。
对我来说挺幸运的,有一个非常可靠的PHP库可以用于处理 ESC/POS 命令。
在我写代码之前,必须确保打印机可以被于我的程序调用。我在 Raspberry Pi 上使用 Ubuntu 系统,从理论上能够通过/dev/usb/lp0(或另一个 lp# 编号)访问它。
我们需要再做一些准备工作。
首先,我打开一个终端,连接我的打印机设备(其实就是 Raspberry Pi)。我运行命令lsusb从打印机中获取产品 ID和供应商 ID。它返回了如下内容:
接下来,创建一个 udev 规则,让属于dialout组的用户可以使用打印机。
我创建了文件在/etc/udev/rules.d/99-escpos.rules 中,向其中添加以下内容:
确保将供应商和产品 ID 的十六进制值替换为我从lsusb。如果用户不属于dialout组,我现在尝试将它们添加到里面:
接下来,重新启动 udev:
现在我们已经准备好连接,接下可以开始编写代码来测试调用。
首先,我需要使用 Composer ,引用刚才我说的那个库:
安装完毕后,接下来写代码将数据发送到打印机。
我创建一个名叫 index.php 的文件,并添加了以下内容:
现在我们来运行它,当然是CLI模式,我所要做的就是让 PHP ,使用 root 权限执行:
如果一切顺利,“Hello,World”将打印在票据上,跳过两行后小票将被剪断。
工作原理非常简单。
创建一个新的FilePrintConnector对象connector,连接的是/dev/usb/lp0,它是打印机连接的 USB 适配器。随后使用的printer实例 ,(如 text(), feed(), cut()方法) 通过该实例连接将与这些操作关联的命令传输到打印机处理。
注意:如果发送到
/dev/usb/lp0或类似的情况下收到有关权限的错误,请运行sudo chmod +777 /dev/usb/lp0,然后再看是否可以修复。
接下来继续与 GitHub 连接,并使用一些真实数据来填写小票。

连接到 GitHub
GitHub 使用webhooks可以很容易地监听 repos 上的事件。
通过转到我的存储库的一个设置页面并导航到 webhook 部分,我可以创建一个hooks,该hooks将在给定操作上发布到特定 URL地址。
我的目标是在创建新新问题时打印一张小票,所以选择“问题”部分,另外我还将数据类型设置为 JSON,因为这是我喜欢用的数据格式。
在继续之前,我需要一个 GitHub 确认能将该 POST 请求发送到指定 URL 。首先,我通过 ssh 连接到 Raspberry Pi ,在该项目目录中加入 -S 参数启动本地 PHP 服务器:
现在它已经正常运行了,接下来需要一种方法来访问Raspberry Pi 的那个端口,而它是在我的本地局域网络上。我不想暴露我家的 IP 地址或创建穿透路由器的通道。
最后我用ngrok隧道,暴露出有用的端口。
加载完毕后,我复制提供的 url 地址,粘贴到 GitHub webhook url 字段中。
接下来我保存了该 webhook。
接下来发出一个测试请求,ngrok 接受该请求,将它传送到本地 PHP 服务器,后面的一个新的 Hello,world!被打印了出来。
现在我们已经准备好实际来自 GitHub 的传入请求来构建小票。
最终代码
现在将对我之前的代码进行一些修改。
首先,我丢弃任何不是 POST 请求的内容。在初始化 FilePrintConnection 之前,我添加了这些代码行:
在 FilePrintConnection 和 Printer 初始化之后,我会将来自 GitHub 的整个 JSON 请求解析为关联数组:
现在,我可以使用之前的打印方法结合来自 GitHub 的数组来构建我想要的小票!
值得一是的是,在使用 Escpos 库时,格式化文本需要大量重复的代码。举个代码例子,问题的粗体和下划线标题以及纯文本正文如下所示:
现在要对其进行测试,我转到我设置 webhook 的存储库,创建一个新问题,然后等待打印机打印出票据。
以上代码,可以到作者的GitHub查看:https:///aschmelyun/github-receipts
总结
我们还可以通过几种不同的方式对其进行扩展。
对于小票本身,还可以添加二维码直接链接到 GitHub 上的问题。还可以从问题本身添加更多详细信息,例如标签和严重性等属性。
你还可以使用此概念来处理来自 webhook 或通过 API 请求的任何数据。就像从 Jira 或 Bugsnag 等应用程序、生产机中应用程序抛出的异常,甚至是每日待办事项和购物清单!
你怎么看?如果对如何改进有任何想法,或者只是有问题或评论,请在下面的讨论中告诉我。
















