Github中Webhooks的应用

WebhooksGithub 为我们提供的一种订阅某些时间的功能。当这些事件被触发时,Github 会将信息以POST方式发送到我们指定的URL。通过Webhooks 我们可以记录更新,触发CI构建、更新备份镜像,甚至服务器的自动部署等等我们能够想到的各个地方。

Github 上对于每个账号或者项目上的每个事件最多可以创建20个 Webhooks

事件

配置 Webhook 时,我们可以自定义具体的事件。只有定义定义的这些事件才会触发对指定的URL的请求。默认,webhooks 只订阅 push 事件,不过我们也可通过 API 或者 UI 来更改订阅事件的列表。

每个事件对应于可能发生在我们组织或 Repository 中的一组特定操作。 例如,如果订阅 issues 事件,则每次打开,关闭,标记 issues 时,我们都会收到详细的有效内容。

可用事件有:

事件名称 描述
* 任何时间触发任何事件(通配符事件)。
commit_comment 每次提交被注释时。
create 每次分支或标记被创建时。
delete 每次分支或标记被删除时。
deployment 每次 Repository 被部署。
deployment_status 任何时候,Repository的部署有来自API的状态更新时。
fork 每次Repositoryfork时。
gollum 每次Wiki Page 被更新时。
issue_comment 每次 Issue 中的评论被添加、编辑、或删除时。
issues 每次 issue 被分配、未分配,标记,未标记,打开,编辑,重大事件,拆除,关闭或重新打开时。
label 每次标签被创建、编辑、或删除时。
member 每次添加或删除一个协作者用户,或者更改他们的权限时。
membership 任何时候添加或删除团队中用户。(仅组织钩子)
milestone 每次创建、关闭、打开、编辑或删除 milestone (里程碑)时。
organization 任何时候添加,删除或邀请用户加入组织。 仅组织钩子。
page_build 每次页面网站建立时。
project_card 项目卡片创建,更新或删除。
project_column 项目 column 创建,更新,移动或删除时。
project 项目创建、编辑、或删除时。
public Repository 从private更改为public时。
pull_request_review_comment 每次pull请求被创建,编辑或删除差异注释时。
pull_request_review 每次提交Pull请求审核时。
pull_request 每次 pull 请求被打开,关闭,重新打开,编辑,分配,未分配,请求审核,审核请求已移除,已标记,未标记或已同步时。
push 每次 push 时(默认事件)

repository|每次 Repository 被创建、删除、公开或 私有化时。
release|每次 release 被发布到 Repository 中时
status |每次从API中更新版本库状态时。
team |任何时候创建,删除,修改 Repository 的团队。 仅组织钩子
team_add|每次添加或修改 Repository 中的 team 成员时。
watch |每次用户对Repository加星标时。

有效载荷

每个事件类型具有特定的有效载荷格式以及相关的事件信息。 即,不同的事件被触发发送到我们配置的 URLPOST 数据格式和内容也会不同。

例如,一个 commit_comment 事件如果被触发,将会向 URL 发送类似下面的内容。

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
{
"action": "created",
"comment": {
"url": "https://api.github.com/repos/baxterthehacker/public-repo/comments/11056394",
"html_url": "https://github.com/baxterthehacker/public-repo/commit/9049f1265b7d61be4a8904a9a27120d2064dab3b#commitcomment-11056394",
"id": 11056394,
"user": {
"login": "baxterthehacker",
"id": 6752317,
"avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/baxterthehacker",
"html_url": "https://github.com/baxterthehacker",
"followers_url": "https://api.github.com/users/baxterthehacker/followers",
"following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}",
"gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}",
"starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions",
"organizations_url": "https://api.github.com/users/baxterthehacker/orgs",
"repos_url": "https://api.github.com/users/baxterthehacker/repos",
"events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}",
"received_events_url": "https://api.github.com/users/baxterthehacker/received_events",
"type": "User",
"site_admin": false
},
"position": null,
"line": null,
"path": null,
"commit_id": "9049f1265b7d61be4a8904a9a27120d2064dab3b",
"created_at": "2015-05-05T23:40:29Z",
"updated_at": "2015-05-05T23:40:29Z",
"body": "This is a really good change! :+1:"
},
"repository": {
"id": 35129377,
"name": "public-repo",
"full_name": "baxterthehacker/public-repo",
"owner": {
"login": "baxterthehacker",
"id": 6752317,
"avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/baxterthehacker",
"html_url": "https://github.com/baxterthehacker",
"followers_url": "https://api.github.com/users/baxterthehacker/followers",
"following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}",
"gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}",
"starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions",
"organizations_url": "https://api.github.com/users/baxterthehacker/orgs",
"repos_url": "https://api.github.com/users/baxterthehacker/repos",
"events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}",
"received_events_url": "https://api.github.com/users/baxterthehacker/received_events",
"type": "User",
"site_admin": false
},
"private": false,
"html_url": "https://github.com/baxterthehacker/public-repo",
"description": "",
"fork": false,
"url": "https://api.github.com/repos/baxterthehacker/public-repo",
"forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks",
"keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}",
"collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}",
"teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams",
"hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks",
"issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}",
"events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events",
"assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}",
"branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}",
"tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags",
"blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}",
"git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}",
"git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}",
"trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}",
"statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}",
"languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages",
"stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers",
"contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors",
"subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers",
"subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription",
"commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}",
"git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}",
"comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}",
"issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}",
"contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}",
"compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}",
"merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges",
"archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}",
"downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads",
"issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}",
"pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}",
"milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}",
"notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}",
"labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}",
"releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}",
"created_at": "2015-05-05T23:40:12Z",
"updated_at": "2015-05-05T23:40:12Z",
"pushed_at": "2015-05-05T23:40:27Z",
"git_url": "git://github.com/baxterthehacker/public-repo.git",
"ssh_url": "git@github.com:baxterthehacker/public-repo.git",
"clone_url": "https://github.com/baxterthehacker/public-repo.git",
"svn_url": "https://github.com/baxterthehacker/public-repo",
"homepage": null,
"size": 0,
"stargazers_count": 0,
"watchers_count": 0,
"language": null,
"has_issues": true,
"has_downloads": true,
"has_wiki": true,
"has_pages": true,
"forks_count": 0,
"mirror_url": null,
"open_issues_count": 2,
"forks": 0,
"open_issues": 2,
"watchers": 0,
"default_branch": "master"
},
"sender": {
"login": "baxterthehacker",
"id": 6752317,
"avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/baxterthehacker",
"html_url": "https://github.com/baxterthehacker",
"followers_url": "https://api.github.com/users/baxterthehacker/followers",
"following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}",
"gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}",
"starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions",
"organizations_url": "https://api.github.com/users/baxterthehacker/orgs",
"repos_url": "https://api.github.com/users/baxterthehacker/repos",
"events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}",
"received_events_url": "https://api.github.com/users/baxterthehacker/received_events",
"type": "User",
"site_admin": false
}
}

其它事件的内容和格式,参考(https://developer.github.com/v3/activity/events/types/)

注意: 有效负载上限为5 MB。 如果我们的事件产生一个更大的有效载荷,webhook 将不会被触发。 例如,如果同时推送了多个分支或标签,则可能会发生在创建事件上。 所以建议监控我们的有效负载大小以确保 webhooks 能够被触发。

请求Header

Webhook 配置的 URL 端点发出的 HTTP 请求将包含几个特殊Header头:

Header Description
X-GitHub-Event 触发本次请求的事件的名称。
X-Hub-Signature HMAC对有效负载的十六进制摘要,使用钩子的密钥作为密钥(如果已配置)。
X-GitHub-Delivery 本次请求的唯一ID。

此外,请求的User-Agent将具有前缀GitHub-Hookshot/

请求示例

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
POST /payload HTTP/1.1

Host: localhost:4567
X-Github-Delivery: 72d3162e-cc78-11e3-81ab-4c9367dc0958
User-Agent: GitHub-Hookshot/044aadd
Content-Type: application/json
Content-Length: 6615
X-GitHub-Event: issues

{
"action": "opened",
"issue": {
"url": "https://api.github.com/repos/octocat/Hello-World/issues/1347",
"number": 1347,
...
},
"repository" : {
"id": 1296269,
"full_name": "octocat/Hello-World",
"owner": {
"login": "octocat",
"id": 1,
...
},
...
},
"sender": {
"login": "octocat",
"id": 1,
...
}
}

Ping事件

当我们创建新的 webhooks 时,Github 会向我们配置的 URL 发送一个简单的 ping 事件,以检测我们配置的 URL 是否正确可用。 该事件未存储,因此无法通过Events API检索。 可以通过调用ping端点再次触发ping

Ping事件有效负载

zen GitHub产生的随机字符串
hook_id 触发pingwebhookID
hook webhook配置
0%