拉仇恨!webhook + 企業微信給同事做了個程式碼提交監聽工具
大家好,我是小富~
最近接個任務,用webhook
做了個程式碼提交監聽功能,就是有人向遠程倉庫提交程式碼後,會在企業微信群內發送一條消息,類似 @XXX 在XXX時間,向XXX項目提交 XXXX 程式碼
這樣的文案。
至於為啥要做這麼個工具,沒辦法官大一級壓死人,其實我內心是拒絕的,總像是被監視一樣感覺怪怪的。難不成是發現了我平時偷偷提程式碼,悄無聲息的修Bug?
webhook
webhook
也就是我們經常說的鉤子
,如果對鉤子不熟悉,沒關係那我們換一個概念,回調URL
應該聽說過吧,例如:微信支付這類的三方平台都支援配置回調URL,通知支付狀態。
當一些事件觸發,例如:”push
程式碼到遠程倉庫”,或者”提一個issue
“等,源網站可以發起一個HTTP
請求到webhook
配置的URL。
下圖是這個工具的工作流程,開發者向GitHub
項目提交程式碼,會觸發GitHub的pull event
,緊接著向GitHub webhook中配置的三方URL發送一個POST
請求,這個三方平台可以是釘釘、飛書、企業微信這類平台。
下面我們以 GitHub
+ 企業微信 來實現程式碼提交監聽,自動向企業微信群組推送消息。
配置GitHub webhook
首先進入GitHub對應項目的 Settings
,做webhook
的基礎配置。
主要配置四部分:
Payload URL
回調服務的地址;
Content type
回調請求頭,建議JSON
格式;
Secret
為了做安全校驗,設置後會在請求 header
中增加如下兩個屬性,用來區分請求的來源,避免暴露的請求被惡意訪問;
X-Hub-Signature: sha1=2478e400758f6114aa18abc4380ef8fad0b16fb9
X-Hub-Signature-256: sha256=68bde5bee18bc36fd95c9b71b4a89f238cb01ab3bf92fd67de3a1de12b4f5c72
最後我們選擇由哪些事件來觸發webhook
回調,push event
(程式碼推送事件)、everything
(所有事件)、某些特定事件三種。
我們可以在 Recent Deliveries
查看webhook
回調記錄,以及完整的請求和參數數據,還可以redelivery
模擬發送請求。
配置企業微信
企業微信的配置其實更簡單,我們先創建一個群組,在群組右鍵有個添加機器人
選項,添加成功後會生成webhook
地址。我們只要向這個地址發送POST
請求,群組內就會收到推送消息。
消息內容支援文本(text)、markdown(markdown)、圖片(image)、圖文(news)四種消息類型,而且還支援在群內@群成員,下邊以文本格式做示範。
curl '//qyapi.weixin.qq.com/cgi-bin/webhook/send?key=145a516a-dd15-421f-97a3-ba3bf1479369' \
-H 'Content-Type: application/json' \
-d '
{
"msgtype": "text",
"text": {
"content": "你好,我是程式設計師內點事"
}
}'
直接請求 url 發現消息推送成功,說明配置的沒問題。
但是到這大家發現一個問題沒,GitHub
和企業微信
一個只管往出發請求,一個只管接受固定數據格式的請求,兩個介面的數據根本無法兼容啊?
請求轉發
既然他們之間不兼容,沒辦法,那就只能我們自己在中間做一層適配,誰讓兩邊都惹不起呢!
轉發的邏輯也比較簡單,只需接受GitHub
回調過來的請求數據,稍加修改組裝成企業微信要求的數據格式,直接發送就可以了。
GitHub
推送過來的數據包括,倉庫、作者、提交者、提交內容等資訊,基本上夠用。
程式碼實現比較粗糙,將就看下吧
@Slf4j
@RestController
public class WebhookController {
private static String WECHAT_URL = "//qyapi.weixin.qq.com/cgi-bin/webhook/send?key=145a516a-dd15-421f-97a3-ba3bf1479369";
private static String GITHUB_API = "//api.github.com/users/";
/**
* @param webhook webhook
* @author 程式設計師內點事
* @Description: github 回調
* @date 2021/05/19
*/
@PostMapping("/webhook")
public String webhookGithub(@RequestBody GithubWebhookPullVo webhook) {
log.info("webhook 入參接收 weChatWebhook {}", JSON.toJSONString(webhook));
// 倉庫名
String name = webhook.getRepository().getName();
SimpleDateFormat simpleFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String now = simpleFormatter.format(new Date());
String content = null;
if (webhook.getCommits().size() > 0) {
GithubWebhookPullVo.CommitsDTO commitsDTO = webhook.getCommits().get(0);
content = "[" + commitsDTO.getCommitter().getName() + "]" +
"於:" + now + "," +
"向作者:[" + commitsDTO.getAuthor().getName() + "]的,遠程倉庫" + name + "推送程式碼" +
"詳情:";
List<String> addeds = commitsDTO.getAdded();
if (addeds.size() > 0) {
content += "添加文件:";
for (int i = 0; i < addeds.size(); i++) {
content = (i + 1) + content + addeds.get(i);
}
}
List<String> modifieds = commitsDTO.getModified();
if (modifieds.size() > 0) {
content += "修改文件:";
for (int i = 0; i < modifieds.size(); i++) {
content = (i + 1) + content + modifieds.get(i);
}
}
List<String> removeds = commitsDTO.getRemoved();
if (removeds.size() > 0) {
content += "刪除文件:";
for (int i = 0; i < removeds.size(); i++) {
content = (i + 1) + content + removeds.get(i);
}
}
}
log.info(content);
WeChatWebhook weChatWebhook = new WeChatWebhook();
weChatWebhook.setMsgtype("text");
WeChatWebhook.TextDTO textDTO = new WeChatWebhook.TextDTO();
textDTO.setContent(content);
textDTO.setMentionedList(Arrays.asList("@all"));
textDTO.setMentionedMobileList(Arrays.asList("@all"));
weChatWebhook.setText(textDTO);
/**
* 組裝參數後向企業微信發送webhook請求
*/
log.info("企業微信發送參數 {}", JSON.toJSONString(weChatWebhook));
String post = HttpUtil.sendPostJsonBody(WECHAT_URL, JSON.toJSONString(weChatWebhook));
log.info("企業微信發送結果 post {}", post);
return JSON.toJSONString(post);
}
}
這裡要提醒一下,GitHub webhook 回調過來的數據有些並不能直接拿來用,某些場景還是要調用GitHub API
來換取一些數據的。
文檔地址://docs.github.com/en/rest/reference
上邊的配置工作完成,再將轉發的程式碼部署到伺服器,測試下整個鏈路看看效果,故意修改pom.xml
文件提交,發現提交程式碼後成功向企業微信發送了消息,和我們預期的效果一致。
源碼地址://github.com/chengxy-nds/Springboot-Notebook/
這個工程包含我過往文章里所有的案例,比如:抖音去水印工具源碼
、人臉識別項目源碼
、以及redis
、Seata
、MQ
等中間件的各種問題解決案例,感興趣的同學可以Star
個,實際開發一定會用得到。