Service D'analyse De Webhook Github

1 Webhook

Un Webhook est une fonction de rappel basée sur HTTP qui permet une communication événementielle légère entre deux interfaces de programmation d’applications (API). Le client fournit une URL unique à l’API du serveur et spécifie les événements qu’il souhaite connaître. Une fois le Webhook configuré, le client n’a plus besoin d’interroger le serveur ; lorsque l’événement spécifié se produit, le serveur envoie automatiquement la charge utile pertinente à l’URL du Webhook du client.

Le Webhook peut être un élément important de l’automatisation, et sa mise en œuvre est simple (une seule requête HTTP, pouvant être intégrée n’importe où). En Chine, Feishu, DingTalk et WeChat d’entreprise prennent tous en charge l’envoi de messages via Webhook.

Ce sont les avantages, mais l’inconvénient est que les paramètres de la requête HTTP ne sont pas unifiés, car c’est trop simple, il n’y a pas de normes de protocole, chaque plateforme a sa propre façon de faire, par exemple, sur une plateforme, le message s’appelle “msg”, sur une autre, cela pourrait être “message” ou “text”. Pour vraiment tirer parti des Webhooks, il est nécessaire de mettre en place son propre service d’analyse et de traitement des Webhooks, heureusement, ce n’est pas compliqué. Cet article prendra l’exemple du Webhook Github, basé sur Flask, pour analyser et pousser vers WeChat d’entreprise.

Cependant, si vous n’avez pas de besoins hautement personnalisés et que vous souhaitez simplement utiliser le Webhook Github sans utiliser d’autres plateformes, vous pouvez utiliser Dingling, qui peut transférer le Webhook Github vers WeChat d’entreprise. Dingling ne peut envoyer que des messages au format Markdown (qui ne peuvent pas être consultés directement dans WeChat), c’est pourquoi je l’ai abandonné.

2 Webhook CloudFlare

Le corps du message du Webhook CloudFlare est très simple, comme suit :

1
{"text":"CloudFlare est vraiment une conscience de l'industrie !"}

Utilisez Flask pour analyser et transférer le message vers WeChat d’entreprise :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from flask import Flask, request, jsonify, abort
import requests
from config import config
app = Flask(__name__)

@app.route('/cloudflare', methods=['POST'])
def cloudflare():
  if request.method == 'POST':
    print(request.json)
    text = request.json['text']
    data = {
        "msgtype": "text",
        "text": {
            "content": text
        }
        }
    r = requests.post('https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key='+config['API_KEY_3'], json=data)
    print(r.json())
    return 'success', 200
  else:
    abort(400)
 
if __name__ == '__main__':
    app.run(port=5700, host='0.0.0.0', debug=True)

Déployez le processus Flask sur le serveur et entrez l’adresse sur Cloudflare, comme indiqué ci-dessous

image-20240229160731848

Après avoir enregistré et testé, vous devriez recevoir un court message de test sur WeChat d’entreprise.

3 Webhook Github

Si le Webhook de CloudFlare est un court message, alors Github veut vous transmettre toutes les informations du site, avec des dizaines de paramètres, mais aucun n’est en langage naturel, il est donc nécessaire de les analyser selon vos besoins. Le code suivant commence par déterminer le type d’événement, puis extrait les informations nécessaires en fonction du type d’événement pour les transférer. Le contenu analysé ci-dessous inclut les actions push, release, issue, pull, etc.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
@app.route('/github', methods=['POST'])
def github():
    githubEvent = request.headers['x-github-event']
    if githubEvent == 'push':
        respority = request.json['repository']['name']
        branch = request.json['ref'].split('/')[-1]
        commits = request.json['commits']
        for commit in commits:
            author = commit['author']['name']
            message = commit['message']
            data = {
                "msgtype": "text",
                "text": {
                    "content": f"{respority} quelqu'un a soumis du code\nBranche : {branch}\nAuteur : {author}\nMessage de soumission : {message}"
                }
            }
            r = requests.post('https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key='+config['API_KEY_2'], json=data)
        return 'success', 200
    if githubEvent == 'issues':
        action = request.json['action']
        if action == 'opened':
            respority = request.json['repository']['name']
            issue = request.json['issue']
            title = issue['title']
            body = issue['body']
            user = issue['user']['login']
            data = {
                "msgtype": "text",
                "text": {
                    "content": f"{respority} quelqu'un a soumis un issue\nTitre : {title}\nContenu : {body}\nSoumis par : {user}"
                }
            }
            r = requests.post('https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key='+config['API_KEY_2'], json=data)
        if action == 'closed':
            respority = request.json['repository']['name']
            issue = request.json['issue']
            title = issue['title']
            body = issue['body']
            user = issue['user']['login']
            data = {
                "msgtype": "text",
                "text": {
                    "content": f"{respority} quelqu'un a fermé un issue\nTitre : {title}\nContenu : {body}\nSoumis par : {user}"
                }
            }
            r = requests.post('https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key='+config['API_KEY_2'], json=data)
        if action == 'reopened':
            respority = request.json['repository']['name']
            issue = request.json['issue']
            title = issue['title']
            body = issue['body']
            user = issue['user']['login']
            data = {
                "msgtype": "text",
                "text": {
                    "content": f"{respority} quelqu'un a rouvert un issue\nTitre : {title}\nContenu : {body}\nSoumis par : {user}"
                }
            }
            r = requests.post('https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key='+config['API_KEY_2'], json=data)
        return 'success', 200
    if githubEvent == 'pull_request':
        action = request.json['action']
        if action == 'opened':
            respority = request.json['repository']['name']
            pull_request = request.json['pull_request']
            title = pull_request['title']
            body = pull_request['body']
            user = pull_request['user']['login']
            data = {
                "msgtype": "text",
                "text": {
                    "content": f"{respority} quelqu'un a soumis un pull request\nTitre : {title}\nContenu : {body}\nSoumis par : {user}"
                }
            }
            r = requests.post('https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key='+config['API_KEY_2'], json=data)
        if action == 'closed':
            respority = request.json['repository']['name']
            pull_request = request.json['pull_request']
            title = pull_request['title']
            body = pull_request['body']
            user = pull_request['user']['login']
            data = {
                "msgtype": "text",
                "text": {
                    "content": f"{respority} quelqu'un a fermé un pull request\nTitre : {title}\nContenu : {body}\nSoumis par : {user}"
                }
            }
            r = requests.post('https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key='+config['API_KEY_2'], json=data)
        if action == 'reopened':
            respority = request.json['repository']['name']
            pull_request = request.json['pull_request']
            title = pull_request['title']
            body = pull_request['body']
            user = pull_request['user']['login']
            data = {
                "msgtype": "text",
                "text": {
                    "content": f"{respority} quelqu'un a rouvert un pull request\nTitre : {title}\nContenu : {body}\nSoumis par : {user}"
                }
            }
            r = requests.post('https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key='+config['API_KEY_2'], json=data)
        return 'success', 200
    if githubEvent == 'release':
        action = request.json['action']
        if action == 'published':
            respority = request.json['repository']['name']
            release = request.json['release']
            tag_name = release['tag_name']
            body = release['body']
            user = release['author']['login']
            data = {
                "msgtype": "text",
                "text": {
                    "content": f"{respority} quelqu'un a publié un release\nVersion : {tag_name}\nContenu : {body}\nPublié par : {user}"
                }
            }
            r = requests.post('https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key='+config['API_KEY_2'], json=data)
        return 'success', 200
    if githubEvent == 'ping':
        data = {
            "msgtype": "text",
            "text": {
                "content": "test du webhook github"
            }
        }
        r = requests.post('https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key='+config['API_KEY_2'], json=data)
        return 'success', 200
    if githubEvent == 'create':
        ref_type = request.json['ref_type']
        if ref_type == 'branch':
            respority = request.json['repository']['name']
            branch = request.json['ref']
            user = request.json['sender']['login']
            data = {
                "msgtype": "text",
                "text": {
                    "content": f"{respority} quelqu'un a créé une branche\nBranche : {branch}\nCréé par : {user}"
                }
            }
            r = requests.post('https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key='+config['API_KEY_2'],
                              json=data)
        if ref_type == 'tag':
            respority = request.json['repository']['name']
            tag = request.json['ref']
            user = request.json['sender']['login']
            data = {
                "msgtype": "text",
                "text": {
                    "content": f"{respority} quelqu'un a créé un tag\ntag : {tag}\nCréé par : {user}"
                }
            }
            r = requests.post('https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key='+config['API_KEY_2'],
                              json=data)
        return 'success', 200
    if githubEvent == 'delete':
        ref_type = request.json['ref_type']
        if ref_type == 'branch':
            respority = request.json['repository']['name']
            branch = request.json['ref']
            user = request.json['sender']['login']
            data = {
                "msgtype": "text",
                "text": {
                    "content": f"{respority} quelqu'un a supprimé une branche\nBranche : {branch}\nSupprimé par : {user}"
                }
            }
            r = requests.post('https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key='+config['API_KEY_2'],
                              json=data)
        if ref_type == 'tag':
            respority = request.json['repository']['name']
            tag = request.json['ref']
            user = request.json['sender']['login']
            data = {
                "msgtype": "text",
                "text": {
                    "content": f"{respority} quelqu'un a supprimé un tag\ntag : {tag}\nSupprimé par : {user}"
                }
            }
            r = requests.post('https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key='+config['API_KEY_2'],
                              json=data)
        return 'success', 200
    if githubEvent == 'pull_request_review':
        action = request.json['action']
        if action == 'submitted':
            respority = request.json['repository']['name']
            pull_request = request.json['pull_request']
            title = pull_request['title']
            body = pull_request['body']
            user = pull_request['user']['login']
            review = request.json['review']
            state = review['state']
            data = {
                "msgtype": "text",
                "text": {
                    "content": f"{respority} quelqu'un a soumis un pull request review\nTitre : {title}\nContenu : {body}\nSoumis par : {user}\nÉtat : {state}"
                }
            }
            r = requests.post(
                'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key='+config['API_KEY_2'],
                json=data)
        return 'success', 200
    if githubEvent == 'pull_request_review_comment':
        action = request.json['action']
        if action == 'created':
            respority = request.json['repository']['name']
            pull_request = request.json['pull_request']
            title = pull_request['title']
            body = pull_request['body']
            user = pull_request['user']['login']
            comment = request.json['comment']
            comment_body = comment['body']
            data = {
                "msgtype": "text",
                "text": {
                    "content": f"{respority} quelqu'un a soumis un commentaire de pull request review\nTitre : {title}\nContenu : {body}\nSoumis par : {user}\nContenu : {comment_body}"
                }
            }
            r = requests.post(
                'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key='+config['API_KEY_2'],
                json=data)
        return 'success', 200
    # if githubEvent == 'check_run':
    #     action = request.json['action']
    #     if action == 'created':
    #         respority = request.json['repository']['name']
    #         check_run = request.json['check_run']
    #         name = check_run['name']
    #         conclusion = check_run['conclusion']
    #         data = {
    #             "msgtype": "text",
    #             "text": {
    #                 "content": f"{respority} quelqu'un a soumis un check run\nNom : {name}\nÉtat : {conclusion}"
    #             }
    #         }
    #         r = requests.post(
    #             'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key='+config['API_KEY_2'],
    #             json=data)
    #     return 'success', 200
    if githubEvent == 'check_suite':
        action = request.json['action']
        if action == 'completed':
            respority = request.json['repository']['name']
            check_suite = request.json['check_suite']
            conclusion = check_suite['conclusion']
            data = {
                "msgtype": "text",
                "text": {
                    "content": f"{respority} quelqu'un a soumis un check suite\nÉtat : {conclusion}"
                }
            }
            r = requests.post(
                'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key='+config['API_KEY_2'],
                json=data)
        return 'success', 200

Une fois le serveur et Github configurés, vous pouvez consulter les informations de push détaillées dans l’historique.

image-20240229160811295

4 Documents de référence

Documentation officielle de Github

Buy me a coffee~
Tim AlipayAlipay
Tim PayPalPayPal
Tim WeChat PayWeChat Pay
0%