虽然我是一个程序员,但是我一直想开一个餐厅。希望开一个极客范儿的餐厅,大家通过 issue 来点菜。受到推特上一位大佬 Andrew Schmelyun 的影响,我在 Gitlab 上实现了该功能。
话不多说,先看效果。
接下来,我来介绍下是怎么实现的。
硬件列表
我这里是惠普的普通办公打印机,换成那种打印小票的热敏打印机效果更好。纸张更小,可以夹在后厨。
我这里是用 Mac 直接连接添加的网络打印机,可以通过 lp filename
直接打印文件。
发送数据给打印机
作为一个 Go 的开发者,很容易就想到用 Gin 框架起一个 http 服务。用来接受 客户的菜单请求。
func main() {
router := gin.New()
// post请求
router.POST("/postReq", func(ctx *gin.Context) {
var req GitlabIssue
err := ctx.ShouldBindJSON(&req) // 解析req参数
if err != nil {
fmt.Println("ctx.ShouldBindJSON err: ", err)
return
}
rspMap := map[string]interface{}{ // 也可用结构体方式返回
"code": 0,
"rsp": fmt.Sprintf("welcome %v!", req.User.Name),
}
ctx.JSON(http.StatusOK, rspMap)
fmt.Printf("rsp: %+v\n", rspMap)
writeMemu(req.ObjectAttributes.Title+"\n"+req.ObjectAttributes.Description)
cmdShell()
})
router.Run(":8080") // 8080端口,底层调用的是net/http包,也是单独启协程进行监听
return
}
复制代码
打印菜单命令,菜单保存在 memu.txt
文件中。
func cmdShell() {
cmd := exec.Command("lp","memu.txt")
stdout, err := cmd.Output()
if err != nil {
fmt.Println("error======",err.Error())
return
}
// Print the output
fmt.Println(string(stdout))
}
func writeMemu(memu string) {
f, err := os.Create("memu.txt")
if err != nil {
log.Fatal(err)
}
defer f.Close()
_, err2 := f.WriteString(memu)
if err2 != nil {
log.Fatal(err2)
}
fmt.Println("done")
}
复制代码
其中 GitlabIssue 结构体的构造可以参考 Gitlab 文档上关于 Webhook 事件的例子,来构造 议题 请求的结构体。
type GitlabIssue struct {
ObjectKind string `json:"object_kind"`
EventType string `json:"event_type"`
User struct {
ID int `json:"id"`
Name string `json:"name"`
Username string `json:"username"`
AvatarURL string `json:"avatar_url"`
Email string `json:"email"`
} `json:"user"`
ObjectAttributes struct {
ID int `json:"id"`
Title string `json:"title"`
AssigneeIds []int `json:"assignee_ids"`
AssigneeID int `json:"assignee_id"`
复制代码
关于 json 怎么转结构体,可以参考该连接
go run main.go
服务就在本地的 8080 端口起来了。
链接 Gitlab
添加 Webhooks
这个时候,发送一个 curl 请求,就可以调试打印了。但是想要从 Gitlab 议题触发,就要用到 Gitlab 的 Webhooks 。Gitlab Webhooks 使用起来也很方便。进入 设置---Webhooks,输入要请求的 URL 和出发事件。
需要允许对本地网络的请求
由于本地网络上运行非 GitLab Web 服务,则这些服务可能容易受到 Webhook 的利用。所以要允许对本地网络的请求。
在顶部栏上,选择 菜单 > 管理员。
在左侧边栏中,选择 设置 > 网络。
展开 出站请求 部分:
选择 允许来自 web hooks 和服务对本地网络的请求。
添加本地请求的许可名单
在顶部栏上,选择 菜单 > 管理员。
在左侧边栏中,选择 设置 > 网络 (/admin/application_settings/network
) ,输入以下内容,允许本地服务
127.0.0.1,1:0:0:0:0:0:0:1
127.0.0.0/8 1:0:0:0:0:0:0:0/124
[1:0:0:0:0:0:0:1]:8080
127.0.0.1:8080
复制代码
具体设置可以参考官网文档
更多 Webhooks 用法可以参考链接
内网穿透
由于服务是本地的,需要顾客点菜,所以需要其他人可以访问该网络,最简单做法就是使用 ngrok
Webhooks
网址就填写:https://e9b1-61-164-43-2.jp.ngrok.io/postReq
完整代码
完整代码已经放在了 极狐 Gitlab 上了
源码地址:https://jihulab.com/zyg/Restaurant/-/tree/dev-zyg
后期规划
参考链接
https://aschmelyun.com/blog/i-built-a-receipt-printer-for-github-issues/
https://docs.gitlab.cn/jh/user/project/integrations/webhooks.html#configure-a-webhook-in-gitlab
评论