Hello, I’m Rich

Recently, I took a task to make a code submission monitoring function with Webhook, which means that after someone submits the code to the remote warehouse, a message will be sent in the wechat group of the enterprise, similar to @XXX submitting XXXX code to the XXX project at XXX time.

As for why I want to make such a tool, there is no way to crush people at a higher level. In fact, I refuse it in my heart. It feels strange as if I am being watched. Could it be that I usually secretly lift code, quietly fix the Bug?

webhook

Webhook is often referred to as hook. If you are not familiar with hook, it does not matter if we change the concept, callback URL should be heard of, for example: Third-party platforms such as wechat Pay support the configuration of callback URL, notification of payment status.

When some event is triggered, such as “push code to remote repository “, or “raise an issue”, the source site can make an HTTP request to the Webhook configured URL.

The following figure shows the workflow of this tool. Developers submit code to GitHub project, which will trigger GitHub pull event, and then send a POST request to the tripartite URL configured in GitHub Webhook. This tripartite platform can be Dingding.com, Feishu.com, enterprise wechat and other platforms.

Below, we use GitHub + enterprise wechat to realize code submission monitoring and automatically push messages to enterprise wechat group.

Configuration making webhook

First, go to GitHub’s Settings for the corresponding project to do the basic webhook configuration.

The main configuration includes four parts:

Payload URL Address of the callback service;

Content Type Callback request header. JSON format is recommended.

Secret To perform security verification, the following two attributes are added to the request header to distinguish the source of the request and prevent exposed requests from being accessed maliciously.

X-Hub-Signature: sha1=2478e400758f6114aa18abc4380ef8fad0b16fb9
X-Hub-Signature-256: sha256=68bde5bee18bc36fd95c9b71b4a89f238cb01ab3bf92fd67de3a1de12b4f5c72
Copy the code

Finally, we choose which events trigger the Webhook callback: push event (code push event), everything (all events), and certain events.

You can view the Webhook callback record in Recent Deliveries, complete with request and parameter data, and redeliver to simulate sending the request.

Configure enterprise wechat

In fact, the configuration of enterprise wechat is simpler. We first create a group, and there is an option to add robots in the group right click. After successfully adding robots, webhook address will be generated. We just send a POST request to that address and the group gets a push message.

Message content supports four types of message: text, Markdown, image, and news. It also supports @group members within the group. The text format is shown below.

   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 ":" hello, I am a programmer in something "}}'

Copy the code

If the URL discovery notification push request succeeds, the configuration is correct.

GitHub and wechat are incompatible with each other. GitHub and wechat are incompatible with each other. GitHub and wechat are incompatible with each other.

Forward requests

Since they are not compatible, there is no way, then we can only do a layer of adaptation in the middle, who let both sides can not afford it!

The logic of forwarding is also relatively simple. You only need to accept the request data called back from GitHub, modify it slightly and assemble it into the data format required by the enterprise wechat, and send it directly.

The data GitHub pushes over includes the warehouse, author, submitter, and submitted content, which is basically enough.

The code implementation is rather rough, but let’s take a look

@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
     * @authorProgrammers have internal issues@Description: Github callback *@date2021/05/19 * /
    @PostMapping("/webhook")
    public String webhookGithub(@RequestBody GithubWebhookPullVo webhook) {

        log.info("Webhook entry accepts weChatWebhook {}", JSON.toJSONString(webhook));
        / / warehouse
        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() + "]" +
                    "To:" + now + "," +
                    "To the author: [" + commitsDTO.getAuthor().getName() + "] remote warehouse" + name + "Push code" +
                    "Details:";

            List<String> addeds = commitsDTO.getAdded();
            if (addeds.size() > 0) {
                content += "Add file :";
                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 += "Modify file :";
                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 += "Delete file :";
                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);

        /** * Send a Webhook request to the enterprise wechat after assembling the parameters */
        log.info("Enterprise wechat sending parameters {}", JSON.toJSONString(weChatWebhook));
        String post = HttpUtil.sendPostJsonBody(WECHAT_URL, JSON.toJSONString(weChatWebhook));
        log.info("Enterprise wechat send result post {}", post);
        returnJSON.toJSONString(post); }}Copy the code

Note that some of the data that GitHub Webhook calls back cannot be used directly. In some cases, GitHub API is called to exchange for some data.

The document address: https://docs.github.com/en/rest/reference

After the above configuration was completed, the forwarded code was deployed to the server and the whole link was tested to see the effect. After the submission of the POM. XML file was deliberately modified, it was found that the message was successfully sent to the wechat of the enterprise after the submission of the code, which was consistent with our expected effect.

Source address: [https://github.com/chengxy-nds/Springboot-Notebook/] (https://github.com/chengxy-nds/Springboot-Notebook/)

This project contains all the cases in my past articles, such as: Douyin to watermarking tool source code, face recognition project source code, as well as redis, Seata, MQ and other middleware problem solving cases, interested students can Star, the actual development will be used.

I have sorted out hundreds of technical e-books for students who need them. The technology group is almost full, want to enter the students can add my friend, and the big guys blow technology together.

Ebook address