作為一名技術(shù)向作者,平時(shí)寫(xiě)寫(xiě)腳本、做做數(shù)據(jù)采集是常事。
但是等到要采集的數(shù)據(jù)逐漸變多起來(lái),我們就沒(méi)有充足的時(shí)間每天查看它們的執(zhí)行結(jié)果了,但是有些數(shù)據(jù)是不可重現(xiàn)的,一旦錯(cuò)過(guò)就無(wú)法再采集,有時(shí)一個(gè)腳本報(bào)錯(cuò)停止好幾天之后才發(fā)現(xiàn)異常,而中間的數(shù)據(jù)已經(jīng)無(wú)法補(bǔ)回。
所以我們需要一個(gè)消息服務(wù),在我們的腳本成功運(yùn)行或者報(bào)錯(cuò)時(shí)將信息發(fā)送到手機(jī)上,便于我們掌握腳本的運(yùn)行狀態(tài)。
盤點(diǎn)我曾用過(guò)的方案
首先是阿里云的短信推送,但價(jià)格算不上香,一條 0.045 元,如果有五個(gè)腳本,每個(gè)月就要花費(fèi) 6.75 元,如果要推送給更多人,成本還會(huì)增加,對(duì)于預(yù)算敏感的人來(lái)說(shuō),并不是好的選擇。
而且阿里云的短信服務(wù)配置相對(duì)復(fù)雜,模板需要審核,而且有字?jǐn)?shù)限制,推送渠道為短信也讓它被忽略的概率大大提高。
接下來(lái)是 Server 醬,配置簡(jiǎn)單,免費(fèi)可用,不需要過(guò)多審核,消息可以自定義,但免費(fèi)版每天只能推送三條消息,渠道選擇雖然多樣,但有些需要配置企業(yè)微信,有些要軟件后臺(tái)常駐,有些可能被隨時(shí)關(guān)停,限制有點(diǎn)多。
我在一年之前用過(guò)一段時(shí)間飛書(shū),對(duì)于團(tuán)隊(duì)管理而言,這是一個(gè)不錯(cuò)的工具,但今天我們用到的是它的 API 接口,用來(lái)實(shí)現(xiàn)一個(gè)屬于自己的消息推送服務(wù)。
操作流程
創(chuàng)建機(jī)器人
下載并注冊(cè)飛書(shū)略過(guò)。
如果沒(méi)有綁定郵箱,請(qǐng)先進(jìn)行綁定。
進(jìn)入飛書(shū)開(kāi)放平臺(tái),點(diǎn)擊“創(chuàng)建應(yīng)用”,應(yīng)用名稱和描述根據(jù)自己需求填寫(xiě)即可,注意圖標(biāo)一定要上傳,否則后面會(huì)出現(xiàn)報(bào)錯(cuò)。

在“企業(yè)自建應(yīng)用”中找到我們剛剛創(chuàng)建的 Bot,點(diǎn)擊進(jìn)入:

進(jìn)入“應(yīng)用功能” > “機(jī)器人”,啟用機(jī)器人:

進(jìn)入“權(quán)限管理”,添加“獲取與發(fā)送單聊、群組消息”權(quán)限:

進(jìn)入“應(yīng)用發(fā)布” > “版本管理與發(fā)布”,發(fā)布一個(gè)新版本,并提交審核申請(qǐng),這里的版本號(hào)和更新說(shuō)明是必填項(xiàng)。

在飛書(shū)消息頁(yè)面,“開(kāi)發(fā)者小助手”會(huì)提示你有新的應(yīng)用等待審核,不用理會(huì),因?yàn)槟阕?cè)的飛書(shū)是個(gè)人版,審核需要升級(jí)為團(tuán)隊(duì),雖然不收費(fèi),但操作較為復(fù)雜。
調(diào)試接口
查閱飛書(shū)開(kāi)放平臺(tái)相關(guān)文檔,我們可以找到發(fā)送消息接口的調(diào)用方式。我們的需求不需要消息卡片,所以使用的是老版本接口,新版本發(fā)送消息卡片的接口需要更多配置,有興趣的小伙伴可以自行研究。
在編寫(xiě)程序之前,我們需要確認(rèn)接口的可用性?;氐綉?yīng)用頁(yè)面,選擇“憑證與基礎(chǔ)信息”,復(fù)制 App ID 和 App Secret 備用。

打開(kāi) API 鑒權(quán)機(jī)制文檔,點(diǎn)擊“嘗試一下”,在左側(cè)填入App ID 和 App Secret,點(diǎn)擊“發(fā)起調(diào)用”。

復(fù)制返回的 tenant_access_token 備用。

可以使用任何能發(fā)送網(wǎng)絡(luò)請(qǐng)求的工具對(duì)接口進(jìn)行調(diào)試,這里我使用 VS Code 的 Thunder Client 插件,請(qǐng)求配置如下:
請(qǐng)求網(wǎng)址: https://open.feishu.cn/open-apis/message/v4/send/
請(qǐng)求方式:POST
需要兩個(gè) Headers,一個(gè)是之前獲取的 tenant_access_token,注意要加固定前綴“Bearer ”;另一個(gè)是固定字符串,根據(jù)開(kāi)發(fā)文檔填寫(xiě)即可。

請(qǐng)求體格式是 Json,第一個(gè)參數(shù)可以填 open_id、user_id、email 或者 chat_id,這里為了簡(jiǎn)化流程使用 email。
msg_type 是固定值“text”。
“content”項(xiàng)里有一個(gè)子項(xiàng)“text”,里面填入要發(fā)送的文本。

完成填寫(xiě)后點(diǎn)擊發(fā)送,返回信息類似這樣:

code 為 0 代表發(fā)送成功,返回的 message_id 我們不需要用到,msg 為“ok”。
同時(shí),你將在飛書(shū)中看到你發(fā)送的消息:

至此,你已經(jīng)使用這個(gè)接口成功發(fā)送了一次消息。
但每次都需要獲取鑒權(quán)信息、設(shè)置請(qǐng)求頭和請(qǐng)求體未免有些麻煩,接下來(lái)我們使用代碼實(shí)現(xiàn)這一流程。
代碼實(shí)現(xiàn)
我們使用 Python 的 Requests 庫(kù)進(jìn)行開(kāi)發(fā),完整代碼如下:
import requests
request_url = "https://open.feishu.cn/open-apis/message/v4/send/"
headers = {
"Authorization": "Bearer t-e9214fc4*************************76957a5",
"Content-Type": "application/json; charset=utf-8"
}
data = {
"email": "yehaowei20060411@qq.com",
"msg_type": "text",
"content": {
"text": "測(cè)試消息"
}
}
req = requests.post(request_url, headers=headers, json=data)
if req.status_code != 200 or req.json()["code"] != 0:
raise Exception(req.json()["code"])
else:
print("發(fā)送成功!")
print("message_id:", req.json()["data"]["message_id"])
運(yùn)行代碼,輸出“發(fā)送成功”和 message_id。
為了便于使用,我們將其封裝為一個(gè)函數(shù),并增加自動(dòng)獲取鑒權(quán)信息的邏輯,代碼如下:
import requests
def SendByFeishu(app_id, app_secret, email, text):
headers = {
"Content-Type": "application/json; charset=utf-8"
}
data_to_get_token = {
"app_id": app_id,
"app_secret": app_secret
}
headers["Authorization"] = "Bearer " + requests.post("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",
headers=headers, json=data_to_get_token).json()["tenant_access_token"]
data_to_send_message = {
"email": email,
"msg_type": "text",
"content": {
"text": text
}
}
req = requests.post("https://open.feishu.cn/open-apis/message/v4/send/", headers=headers, json=data_to_send_message)
if req.json()["code"] != 0:
raise Exception("消息發(fā)送失敗,錯(cuò)誤碼:" + str(req.json()["code"]))
else:
return req.json()["data"]["message_id"]
調(diào)用該函數(shù),返回 message_id 即為發(fā)送成功。
SendByFeishu("cli_a1b4*******8d00c", "FvUtRVSA********************LW00t", "yehaowei20060411@qq.com", "測(cè)試消息")
至此,我們成功使用飛書(shū)完成了腳本運(yùn)行狀態(tài)推送服務(wù)的搭建。