使用阿里云函数计算实现 GitLab Webhook 钉钉推送

在 DevOps 流程中,及时的消息通知对于团队协作至关重要。虽然 GitLab 自带了一些集成,但往往难以满足个性化的通知需求。本文将介绍如何利用阿里云函数计算(FC)搭建一个轻量、低成本且高度可定制的 GitLab Webhook 转发服务,将代码提交、合并请求、Pipeline 状态等实时推送到钉钉群。

为什么选择云函数?

  1. 低成本:按需计费,对于低频的 Webhook 请求,几乎可以免费使用。
  2. 免运维:无需购买和维护服务器。
  3. 高定制:可以根据 GitLab 发送的 Payload 自由编写逻辑,过滤无关通知或格式化消息。

环境准备

  1. 钉钉机器人:在钉钉群中添加自定义机器人,获取 Webhook 地址和 加签 Secret
  2. 阿里云账号:开通函数计算服务。
  3. GitLab 项目:拥有配置 Webhook 的权限。

代码实现

我们使用 Python 编写云函数,并使用 dingtalkchatbot 库来简化钉钉消息的发送。

1. 核心逻辑

函数需要处理 GitLab 发送的 JSON 数据,并根据 object_kind 区分事件类型。

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
import json
import os
import base64
from dingtalkchatbot.chatbot import DingtalkChatbot

# 初始化钉钉机器人
DINGTALK_WEBHOOK = os.getenv('DINGTALK_WEBHOOK')
DINGTALK_SECRET = os.getenv('DINGTALK_SECRET')
webhook = DingtalkChatbot(DINGTALK_WEBHOOK, secret=DINGTALK_SECRET)

def handler(event, context):
# 处理 API 网关或 HTTP 触发器的事件
if isinstance(event, bytes):
event_dict = json.loads(event.decode('utf-8'))
else:
event_dict = event

# 验证 GitLab Token
headers = event_dict.get('headers', {})
gitlab_token = headers.get('X-Gitlab-Token') or headers.get('x-gitlab-token')
if gitlab_token != os.getenv('GITLAB_TOKEN'):
return {'statusCode': 403, 'body': 'Forbidden'}

# 解析 Payload
body_str = event_dict.get('body', '')
if event_dict.get('isBase64Encoded', False):
body_str = base64.b64decode(body_str).decode('utf-8')
payload = json.loads(body_str)

kind = payload.get('object_kind')

# 根据事件类型调用不同的消息构建函数
if kind == 'push':
# 处理 Push 事件...
pass
elif kind == 'merge_request':
# 处理 Merge Request 事件...
pass
# ... 其他事件处理

return {'statusCode': 200, 'body': 'OK'}

2. 事件处理细节

为了避免消息轰炸,我们在代码中加入了一些启发式逻辑:

  • 合并去重:如果是由于 MR 合并产生的 Push,通常不需要再次通知,可以通过检查提交信息中的关键词来过滤。
  • 失败提醒:对于 Job/Build 任务,通常只关心失败的情况。
  • Tag 过滤:过滤掉 Tag 删除的通知。

部署步骤

1. 阿里云函数计算配置

  1. 创建函数,选择 Python 3.10 运行时。
  2. 配置 HTTP 触发器
  3. 设置环境变量:
    • DINGTALK_WEBHOOK: 钉钉机器人地址。
    • DINGTALK_SECRET: 钉钉机器人加签密钥。
    • GITLAB_TOKEN: 自定义的 Secret Token,用于 GitLab 验证。

2. GitLab Webhook 配置

  1. 进入 GitLab 项目设置 -> Webhooks。
  2. URL: 填写阿里云函数的触发器地址。
  3. Secret token: 填写与云函数环境变量 GITLAB_TOKEN 相同的值。
  4. 选择触发事件:Push events, Merge request events, Tag push events, Pipeline events, Job events

总结

通过阿里云函数计算,我们以极低的成本实现了一个功能强大的 GitLab 通知机器人。代码中可以根据实际需求进一步扩展,例如根据分支名发送到不同的钉钉群,或者在消息中加入更丰富的项目元数据。