[破事氵]Lark机器人实践

缘起

某位大佬入职字节之后,日常和我推荐Lark(Aka飞书).体验之后发现确实比微信更简洁且贴近团队需求,但是可能是部分基于React Native的关系,某些页面没有原生那么流畅,而且Lark缺少了使用回车键发送消息这个对我来讲很刚需的功能.不过Lark机器人这项功能很有意思,支持Markdown富文本排版且有类似Inline Button的交互功能,很适合做Telegram 机器人的国内替代品.正好菜鸡最近在刷力扣,于是尝试下做一个力扣每日一题的机器人.

GraphQL

打开https://leetcode-cn.com/problemset/all/ ,F12 Network,发现XHR请求大多数是向/graphql路由发送请求.看来力扣使用了GraphQL查询语言,在国内网站几乎是凤毛麟角了.

GraphQL是什么?

GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时。 GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述,使得客户端能够准确地获得它需要的数据,而且没有任何冗余,也让 API 更容易地随着时间推移而演进,还能用于构建强大的开发者工具。

不同于RESTful对万物皆资源的执着,GraphQL更侧重于由请求者定制返回字段的功能.GraphQL在执行查询时需要向服务端描述其需要的字段,服务端将只返回约定的字段.看上去它可以极大增强前端的话语权和灵活性,并在某种程度上可以统一某些冗余API,但是GraphQL的实现可能需要整个后端的重构,或者需要一个中间层来完成,极大增大了后端的复杂度,与其收益不成正比.同时由于GraphQL支持任意类似join的查询,导致一条query可能涉及多个表,带来可能的性能损失.

言归正传,我们来分析下力扣的API.

{"operationName":"questionOfToday","variables":{},"query":"query questionOfToday {\n  todayRecord {\n    question {\n      questionFrontendId\n      questionTitleSlug\n          }\n      date\n     }\n}\n"}

questionOfToday查询每日一题的id与slug,后续会通过slug查询题目内容,按照GraphQL的约定,我们可以将多余的Field删除,只留question中的questionTitleSlug字段来减少数据量.

{"operationName":"questionData","variables":{"titleSlug":"ones-and-zeroes"},"query":"query questionData($titleSlug: String) {\n  question(titleSlug: $titleSlug) {\n    questionId\n    questionFrontendId\n    categoryTitle\n    boundTopicId\n    title\n    titleSlug\n     translatedTitle\n    translatedContent\n     difficulty\n    likes\n      similarQuestions\n        topicTags {\n      name\n      slug\n      translatedName\n         }\n    companyTagStats\n      stats\n    hints\n     sampleTestCase\n             isDailyQuestion\n        exampleTestcases\n     }\n}\n"}

此API是带参数请求questionData,将问题的slug传入名为titleSlug的变量,执行查询.其中translatedContent为中文题目内容,形式为HTML片段,便于前端直接插入.

Lark机器人

申请和添加机器人不赘述,我们更关注发送消息的API:

https://open.feishu.cn/open-apis/message/v4/send/这里,可以找到API文档.不过如果你也是使用Lark注册开发者,需要将域名改为open.larksuite.com.

当然,在调用之前需要获取access_token,好在Lark没有设置所谓的refresh_token机制,你在任何时候都可以传入AppID与AppSecret兑换access_token,且重新兑换不会作废之前的未过期token,这比Microsoft Graph API要好用多了,也不需要考虑token的储存和定期更新问题.

消息卡片

Lark提供了可组装的消息卡片功能,你可以将多个元素以流式排版的方式组装为一个卡片.你可以在这里,预览消息卡片.

但是Lark的Markdown不支持代码元素,因此我们需要使用其他形式来代替代码,我采取的方式是链接形式,即将行内代码元素转换为href为(http://)的行内链接元素,会展示为蓝色,在桌面端不可点,或者也可以采用加粗等方式区分.同时,将代码段转换为普通文段.

此外,可以利用Lark提供的按钮元素,跳转到LeetCode查看原文.

效果如下:

image-20210608100522746

编写

将上述流程编写为脚本,并固定时间执行即可.我用的语言是Go,使用JohannesKaufmann/html-to-markdown库将HTML片段转换为markdown.

tag(s): none
show comments · back · home
Edit with markdown