Skip to content

Commit 58cde38

Browse files
committed
updates to github webhook handler adding teams messaging in and improvements to the messages
1 parent cd1fe29 commit 58cde38

2 files changed

Lines changed: 293 additions & 29 deletions

File tree

web/github-old.php

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
/**
5+
* @link https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads
6+
* @link https://github.com/github/docs/blob/main/content/developers/webhooks-and-events/webhooks/webhook-events-and-payloads.md
7+
* @link https://github.com/organizations/interserver/settings/hooks/359889086?tab=deliveries
8+
*
9+
*/
10+
11+
header('Content-Type: text/plain; charset=utf-8');
12+
// set default response code
13+
http_response_code(500);
14+
15+
require __DIR__ . '/../src/config.php';
16+
require __DIR__ . '/../src/GithubWebhook.php';
17+
require __DIR__ . '/../src/IgnoredEventException.php';
18+
require __DIR__ . '/../src/NotImplementedException.php';
19+
20+
$Hook = new GitHubWebHook();
21+
try {
22+
if (!$Hook->ValidateHubSignature(GITHUB_WEBHOOKS_SECRET)) {
23+
throw new Exception('Secret validation failed.');
24+
}
25+
$Hook->ProcessRequest();
26+
$RepositoryName = $Hook->GetFullRepositoryName();
27+
$EventType = $Hook->GetEventType();
28+
// format message
29+
//$Converter = new Converter($Hook->GetEventType(), $Hook->GetPayload());
30+
//$Message = $Converter->GetEmbed();
31+
$Message = $Hook->GetPayload();
32+
$log = ['repo' => $RepositoryName, 'event' => $EventType, 'data' => $Message];
33+
$Msg = [];
34+
if (isset($Message[$EventType]['app']['name'])) {
35+
$User = $Message[$EventType]['app']['name'];
36+
} else {
37+
$User = $Message['sender']['login'];
38+
}
39+
if (isset($Message[$EventType]['app']['owner']['avatar_url'])) {
40+
$Msg['avatar'] = $Message[$EventType]['app']['owner']['avatar_url'];
41+
} elseif (isset($Message['avatar_url'])) {
42+
$Msg['avatar'] = $Message['avatar_url'];
43+
} else {
44+
$Msg['avatar'] = $Message['sender']['avatar_url'];
45+
}
46+
if (isset($Message['head_commit'])) {
47+
$Msg['alias'] = $Message['head_commit']['author']['name'];
48+
} elseif (isset($Message['commits']) && isset($Message['commits'][0]['author']['name'])) {
49+
$Msg['alias'] = $Message['commits'][0]['author']['name'];
50+
} elseif (isset($Message['commit']) && isset($Message['commit']['commit']['author']['name'])) {
51+
$Msg['alias'] = $Message['commit']['commit']['author']['name'];
52+
}
53+
file_put_contents(__DIR__.'/../log/'.date('Ymd_His').'_'.$EventType.(isset($Message['action']) ? '_'.$Message['action'] : '').'_'.$User.'_'.str_replace(['/', '-', ' '], ['_', '_', '_'], $RepositoryName).'.json', json_encode($log, JSON_PRETTY_PRINT));
54+
if (empty($Message)) {
55+
throw new Exception('Empty message, not sending.');
56+
}
57+
58+
59+
switch ($EventType) {
60+
case 'issues':
61+
if ($Message['action'] == 'opened') {
62+
$ChatMsg = "[{$User}](https://github.com/{$User}) opened a new [Issue](https://github.com/{$RepositoryName}/issues/{$Message['issue']['number']}) for [{$RepositoryName}](https://github.com/{$RepositoryName}) _{$Message['issue']['title']}_.";
63+
$Msg['text'] = $ChatMsg;
64+
//error_log($Msg['text']);
65+
SendToChat('int-dev', $Msg);
66+
} else {
67+
$ChatMsg = "{$User} triggered a {$EventType} event ".(isset($Message['action']) ? $Message['action'].' action ' : '')." notification on https://github.com/{$RepositoryName} ".(isset($Message['ref']) ? str_replace('refs/heads/', '', $Message['ref']) : '').".";
68+
$Msg['text'] = $ChatMsg;
69+
//error_log($Msg['text']);
70+
SendToChat('notifications', $Msg);
71+
}
72+
// no break
73+
case 'push':
74+
$Branch = isset($Message['ref']) && !is_null($Message['ref']) ? str_replace('refs/heads/', '', $Message['ref']) : '';
75+
if (isset($Message['head_commit']['message'])) {
76+
$CommitMsg = $Message['head_commit']['message'];
77+
} elseif (isset($Message['data']['issue']['title'])) {
78+
$CommitMsg = $Message['data']['issue']['title'];
79+
} else {
80+
$CommitMsg = '';
81+
}
82+
$CommitCount = isset($Message['commits']) ? count($Message['commits']) : 1;
83+
$ChatMsg = "{$Msg['alias']} pushed ".($CommitCount == 1 ? 'a commit' : $CommitCount.' commits')." to https://github.com/{$RepositoryName} [*{$Branch}*]\n🕮 {$CommitMsg}";
84+
$Msg['text'] = $ChatMsg;
85+
//error_log($Msg['text']);
86+
SendToChat('notifications', $Msg);
87+
break;
88+
case 'check_suite':
89+
case 'check_run':
90+
case 'create':
91+
case 'pull_request':
92+
case 'workflow_run':
93+
case 'workflow_job':
94+
break;
95+
default:
96+
$ChatMsg = "{$Msg['alias']} triggered a {$EventType} event ".(isset($Message['action']) ? $Message['action'].' action ' : '')." notification on https://github.com/{$RepositoryName} ".(isset($Message['ref']) ? str_replace('refs/heads/', '', $Message['ref']) : '').".";
97+
$Msg['text'] = $ChatMsg;
98+
//error_log($Msg['text']);
99+
SendToChat('notifications', $Msg);
100+
break;
101+
}
102+
/*
103+
foreach($githubWebhooks as $Event => $Repos) {
104+
if (!WildMatch($EventType, $Event))
105+
foreach ($Repos as $Repo => $SendTargets) {
106+
if (!WildMatch($RepositoryName, $Repo))
107+
continue;
108+
foreach($SendTargets as $ChannelName) {
109+
SendToChat($ChannelName, $Message);
110+
}
111+
}
112+
}
113+
*/
114+
//error_log('GitHub Hook '.$EventType.' on '.$RepositoryName.' called');
115+
http_response_code(202);
116+
} catch (IgnoredEventException $e) {
117+
http_response_code(200);
118+
error_log('This GitHub event is ignored.');
119+
} catch (NotImplementedException $e) {
120+
http_response_code(501);
121+
error_log('Unsupported GitHub event: ' . $e->EventName);
122+
} catch (Exception $e) {
123+
error_log('Exception: ' . $e->getMessage() . PHP_EOL);
124+
}
125+
126+
function WildMatch(string $string, string $expression) : bool
127+
{
128+
if (strpos($expression, '*') === false) {
129+
return strcmp($expression, $string) === 0;
130+
}
131+
$expression = preg_quote($expression, '/');
132+
$expression = str_replace('\*', '.*', $expression);
133+
return preg_match('/^' . $expression . '$/', $string) === 1;
134+
}
135+
136+
function SendToChat(string $Where, array $Payload) : bool
137+
{
138+
global $chatChannels;
139+
$Url = $chatChannels['rocketchat'][$Where];
140+
$c = curl_init();
141+
curl_setopt_array($c, [
142+
CURLOPT_USERAGENT => 'https://github.com/xPaw/GitHub-WebHook',
143+
CURLOPT_RETURNTRANSFER => true,
144+
CURLOPT_FOLLOWLOCATION => 0,
145+
CURLOPT_TIMEOUT => 30,
146+
CURLOPT_CONNECTTIMEOUT => 30,
147+
CURLOPT_URL => $Url,
148+
CURLOPT_POST => true,
149+
CURLOPT_POSTFIELDS => json_encode($Payload),
150+
CURLOPT_HTTPHEADER => [
151+
'Content-Type: application/json',
152+
],
153+
]);
154+
curl_exec($c);
155+
$Code = curl_getinfo($c, CURLINFO_HTTP_CODE);
156+
curl_close($c);
157+
//error_log('Rocket Chat HTTP ' . $Code . PHP_EOL);
158+
$c = curl_init();
159+
$Url = $chatChannels['teams'][$Where];
160+
curl_setopt_array($c, [
161+
CURLOPT_USERAGENT => 'https://github.com/xPaw/GitHub-WebHook',
162+
CURLOPT_RETURNTRANSFER => true,
163+
CURLOPT_FOLLOWLOCATION => 0,
164+
CURLOPT_TIMEOUT => 30,
165+
CURLOPT_CONNECTTIMEOUT => 30,
166+
CURLOPT_URL => $Url,
167+
CURLOPT_POST => true,
168+
CURLOPT_POSTFIELDS => json_encode([
169+
'type' => 'message',
170+
'message' => $Payload['text']
171+
]),
172+
CURLOPT_HTTPHEADER => [
173+
'Content-Type: application/json',
174+
],
175+
]);
176+
curl_exec($c);
177+
$Code = curl_getinfo($c, CURLINFO_HTTP_CODE);
178+
curl_close($c);
179+
180+
return $Code >= 200 && $Code < 300;
181+
}

web/github.php

Lines changed: 112 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -54,46 +54,106 @@
5454
if (empty($Message)) {
5555
throw new Exception('Empty message, not sending.');
5656
}
57+
58+
5759
switch ($EventType) {
5860
case 'issues':
59-
if ($Message['action'] == 'opened') {
60-
$ChatMsg = "[{$User}](https://github.com/{$User}) opened a new [Issue](https://github.com/{$RepositoryName}/issues/{$Message['issue']['number']}) for [{$RepositoryName}](https://github.com/{$RepositoryName}) _{$Message['issue']['title']}_.";
61-
$Msg['text'] = $ChatMsg;
62-
//error_log($Msg['text']);
63-
SendToRocketChat($rocketChatChannels['int-dev'], $Msg);
64-
SendToRocketChat($rocketChatChannels['notifications'], $Msg);
65-
} else {
66-
$ChatMsg = "{$User} triggered a {$EventType} event ".(isset($Message['action']) ? $Message['action'].' action ' : '')." notification on https://github.com/{$RepositoryName} ".(isset($Message['ref']) ? str_replace('refs/heads/', '', $Message['ref']) : '').".";
67-
$Msg['text'] = $ChatMsg;
68-
//error_log($Msg['text']);
69-
SendToRocketChat($rocketChatChannels['notifications'], $Msg);
61+
$Issue = $Message['issue'];
62+
$IssueUrl = $Issue['html_url'];
63+
$IssueTitle = $Issue['title'];
64+
$Action = $Message['action'];
65+
66+
$ChatMsg = "🐛 [{$User}](https://github.com/{$User}) **{$Action}** issue [#{$Issue['number']} {$IssueTitle}]({$IssueUrl}) "
67+
. "in [{$RepositoryName}](https://github.com/{$RepositoryName}).";
68+
69+
if (!empty($Issue['body'])) {
70+
$ChatMsg .= "\n\n> " . substr($Issue['body'], 0, 200) . (strlen($Issue['body']) > 200 ? "" : "");
7071
}
71-
// no break
72-
case 'push':
73-
$Branch = isset($Message['ref']) && !is_null($Message['ref']) ? str_replace('refs/heads/', '', $Message['ref']) : '';
74-
if (isset($Message['head_commit']['message'])) {
75-
$CommitMsg = $Message['head_commit']['message'];
76-
} elseif (isset($Message['data']['issue']['title'])) {
77-
$CommitMsg = $Message['data']['issue']['title'];
78-
} else {
79-
$CommitMsg = '';
72+
73+
$Msg['text'] = $ChatMsg;
74+
SendToChat('int-dev', $Msg);
75+
break;
76+
77+
case 'pull_request':
78+
$PR = $Message['pull_request'];
79+
$Action = $Message['action'];
80+
$PRUrl = $PR['html_url'];
81+
$PRTitle = $PR['title'];
82+
83+
$ChatMsg = "🔀 [{$User}](https://github.com/{$User}) **{$Action}** pull request "
84+
. "[#{$PR['number']} {$PRTitle}]({$PRUrl}) "
85+
. "in [{$RepositoryName}](https://github.com/{$RepositoryName}).";
86+
87+
if (!empty($PR['body'])) {
88+
$ChatMsg .= "\n\n> " . substr($PR['body'], 0, 200) . (strlen($PR['body']) > 200 ? "" : "");
8089
}
90+
91+
$Msg['text'] = $ChatMsg;
92+
SendToChat('notifications', $Msg);
93+
break;
94+
95+
case 'push':
96+
$Branch = isset($Message['ref']) ? str_replace('refs/heads/', '', $Message['ref']) : '';
8197
$CommitCount = isset($Message['commits']) ? count($Message['commits']) : 1;
82-
$ChatMsg = "{$Msg['alias']} pushed ".($CommitCount == 1 ? 'a commit' : $CommitCount.' commits')." to https://github.com/{$RepositoryName} [*{$Branch}*]\n:notepad_spiral: {$CommitMsg}";
98+
$Commits = [];
99+
100+
if (!empty($Message['commits'])) {
101+
foreach ($Message['commits'] as $Commit) {
102+
$Commits[] = "• [".substr($Commit['id'], 0, 7)."]({$Commit['url']}) _{$Commit['message']}_ "
103+
. "by {$Commit['author']['name']}";
104+
}
105+
}
106+
107+
$ChatMsg = "📦 {$Msg['alias']} pushed {$CommitCount} "
108+
. ($CommitCount === 1 ? "commit" : "commits")
109+
. " to [{$RepositoryName}](https://github.com/{$RepositoryName}) "
110+
. "[`{$Branch}`](https://github.com/{$RepositoryName}/tree/{$Branch})";
111+
112+
if (!empty($Commits)) {
113+
$ChatMsg .= "\n" . implode("\n", $Commits);
114+
}
115+
83116
$Msg['text'] = $ChatMsg;
84-
//error_log($Msg['text']);
85-
SendToRocketChat($rocketChatChannels['notifications'], $Msg);
117+
SendToChat('notifications', $Msg);
86118
break;
119+
87120
case 'check_suite':
88121
case 'check_run':
122+
$Status = $Message['check_suite']['conclusion'] ?? $Message['check_run']['conclusion'] ?? 'in_progress';
123+
$Name = $Message['check_suite']['app']['name'] ?? $Message['check_run']['name'];
124+
$Url = $Message['check_suite']['url'] ?? $Message['check_run']['html_url'];
125+
126+
$Emoji = $Status === 'success' ? "" : ($Status === 'failure' ? "" : "");
127+
$ChatMsg = "{$Emoji} Check **{$Name}** {$Status} "
128+
. "for [{$RepositoryName}](https://github.com/{$RepositoryName}) "
129+
. "([details]({$Url}))";
130+
131+
$Msg['text'] = $ChatMsg;
132+
SendToChat('notifications', $Msg);
133+
break;
134+
89135
case 'workflow_run':
90136
case 'workflow_job':
137+
$Workflow = $Message['workflow']['name'] ?? $Message['workflow_job']['name'] ?? "Workflow";
138+
$Status = $Message['workflow_run']['conclusion'] ?? $Message['workflow_job']['conclusion'] ?? "in_progress";
139+
$Url = $Message['workflow_run']['html_url'] ?? "#";
140+
$Emoji = $Status === 'success' ? "" : ($Status === 'failure' ? "" : "");
141+
142+
$ChatMsg = "{$Emoji} Workflow **{$Workflow}** {$Status} "
143+
. "for [{$RepositoryName}](https://github.com/{$RepositoryName}) "
144+
. "([view run]({$Url}))";
145+
146+
$Msg['text'] = $ChatMsg;
147+
SendToChat('notifications', $Msg);
91148
break;
149+
92150
default:
93-
$ChatMsg = "{$Msg['alias']} triggered a {$EventType} event ".(isset($Message['action']) ? $Message['action'].' action ' : '')." notification on https://github.com/{$RepositoryName} ".(isset($Message['ref']) ? str_replace('refs/heads/', '', $Message['ref']) : '').".";
151+
$ChatMsg = "ℹ️ {$Msg['alias']} triggered a **{$EventType}** event "
152+
. (isset($Message['action']) ? "({$Message['action']}) " : "")
153+
. "on [{$RepositoryName}](https://github.com/{$RepositoryName}).";
154+
94155
$Msg['text'] = $ChatMsg;
95-
//error_log($Msg['text']);
96-
SendToRocketChat($rocketChatChannels['notifications'], $Msg);
156+
SendToChat('notifications', $Msg);
97157
break;
98158
}
99159
/*
@@ -103,8 +163,7 @@
103163
if (!WildMatch($RepositoryName, $Repo))
104164
continue;
105165
foreach($SendTargets as $ChannelName) {
106-
$ChannelUrl = $rocketChatChannels[$ChannelName];
107-
SendToRocketChat($Target, $Message);
166+
SendToChat($ChannelName, $Message);
108167
}
109168
}
110169
}
@@ -131,8 +190,10 @@ function WildMatch(string $string, string $expression) : bool
131190
return preg_match('/^' . $expression . '$/', $string) === 1;
132191
}
133192

134-
function SendToRocketChat(string $Url, array $Payload) : bool
193+
function SendToChat(string $Where, array $Payload) : bool
135194
{
195+
global $chatChannels;
196+
$Url = $chatChannels['rocketchat'][$Where];
136197
$c = curl_init();
137198
curl_setopt_array($c, [
138199
CURLOPT_USERAGENT => 'https://github.com/xPaw/GitHub-WebHook',
@@ -151,5 +212,27 @@ function SendToRocketChat(string $Url, array $Payload) : bool
151212
$Code = curl_getinfo($c, CURLINFO_HTTP_CODE);
152213
curl_close($c);
153214
//error_log('Rocket Chat HTTP ' . $Code . PHP_EOL);
215+
$c = curl_init();
216+
$Url = $chatChannels['teams'][$Where];
217+
curl_setopt_array($c, [
218+
CURLOPT_USERAGENT => 'https://github.com/xPaw/GitHub-WebHook',
219+
CURLOPT_RETURNTRANSFER => true,
220+
CURLOPT_FOLLOWLOCATION => 0,
221+
CURLOPT_TIMEOUT => 30,
222+
CURLOPT_CONNECTTIMEOUT => 30,
223+
CURLOPT_URL => $Url,
224+
CURLOPT_POST => true,
225+
CURLOPT_POSTFIELDS => json_encode([
226+
'type' => 'message',
227+
'message' => $Payload['text']
228+
]),
229+
CURLOPT_HTTPHEADER => [
230+
'Content-Type: application/json',
231+
],
232+
]);
233+
curl_exec($c);
234+
$Code = curl_getinfo($c, CURLINFO_HTTP_CODE);
235+
curl_close($c);
236+
154237
return $Code >= 200 && $Code < 300;
155238
}

0 commit comments

Comments
 (0)