大家好,我是小富~
最近接個任務,用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 'https://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 = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=145a516a-dd15-421f-97a3-ba3bf1479369";
private static String GITHUB_API = "https://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
來換取一些資料的。
文件地址:https://docs.github.com/en/rest/reference
上邊的配置工作完成,再將轉發的程式碼部署到伺服器,測試下整個鏈路看看效果,故意修改pom.xml
檔案提交,發現提交程式碼後成功向企業微信傳送了訊息,和我們預期的效果一致。
原始碼地址:https://github.com/chengxy-nds/Springboot-Notebook/
這個工程包含我過往文章裡所有的案例,比如:抖音去水印工具原始碼
、人臉識別專案原始碼
、以及redis
、Seata
、MQ
等中介軟體的各種問題解決案例,感興趣的同學可以Star
個,實際開發一定會用得到。