$repoToken) { if(hash_equals(hash_hmac($sigParts[0], $rawData, $repoToken), $sigParts[1])) { $repoAuthenticated = true; break; } } if(!$repoAuthenticated) die('signature check failed'); $data = json_decode($_SERVER['CONTENT_TYPE'] === 'application/x-www-form-urlencoded' ? $_POST['payload'] : $rawData); if(empty($data)) die('body is corrupt'); if(empty($data->repository->full_name)) die('body is corrupt'); if($data->repository->full_name !== $repoName) die('invalid repository token'); $message = ''; switch($_SERVER['HTTP_X_GITHUB_EVENT']) { case 'ping': $message = "ping received from {$data->repository->full_name}!"; break; case 'create': switch ($data->ref_type) { case 'tag': $message = "[b][url={$data->repository->html_url}]{$data->repository->full_name}[/url][/b]: [url={$data->sender->html_url}]{$data->sender->login}[/url] created tag [url={$data->repository->html_url}/releases/tag/{$data->ref}]{$data->ref}[/url]"; break; case 'branch': $message = "[b][url={$data->repository->html_url}]{$data->repository->full_name}[/url][/b]: [url={$data->sender->html_url}]{$data->sender->login}[/url] created branch [url={$data->repository->html_url}/tree/{$data->ref}]{$data->ref}[/url]"; break; case 'repository': // doubt we'll ever get here // TODO: test organisation level webhooks? break; } break; case 'delete': switch($data->ref_type) { case 'tag': if (acl_check(ACL_BROADCAST)) $message = "[b][url={$data->repository->html_url}]{$data->repository->full_name}[/url][/b]: [url={$data->sender->html_url}]{$data->sender->login}[/url] deleted tag {$data->ref}"; break; case 'branch': if (acl_check(ACL_BROADCAST)) $message = "[b][url={$data->repository->html_url}]{$data->repository->full_name}[/url][/b]: [url={$data->sender->html_url}]{$data->sender->login}[/url] deleted branch {$data->ref}"; break; case 'repository': if (acl_check(ACL_BROADCAST)) $message = "[b]{$data->repository->full_name}[/b]: [url={$data->sender->html_url}]{$data->sender->login}[/url] deleted the repository :crying:"; break; } break; case 'push': $commitCount = count($data->commits); if($commitCount < 1) break; $message .= "[b]{$data->repository->full_name}:" . substr($data->ref, strrpos($data->ref, '/') + 1) . "[/b] {$commitCount} new commit" . ($commitCount === 1 ? '' : 's') . "\r\n"; foreach($data->commits as $commit) { $timestamp = strtotime($commit->timestamp); $commit->message = trim($commit->message); $message .= "[b][url={$commit->url}][code]" . substr($commit->id, 0, 7) . "[/code][/url][/b] {$commit->message} - [url=" . ($isGitea ? 'https://git.flash.moe/' : 'https://github.com/') . "{$commit->author->username}]{$commit->author->username}[/url]\r\n"; } break; case 'status': $status_colour['failure'] = '#cb2431'; //$status_colour['pending'] = '#b5ab86'; $status_colour['success'] = '#28a745'; $status_colour['error'] = '#586069'; $status_emotes['failure'] = [':angry:', ':angrier:', ':angriest:', ':sad:', ':ouch:', ':dizzy:', ':sweat:', ':fat:', ':jew:']; $status_emotes['success'] = [':happy:', ':lol:', ':yay:']; $status_emotes['error'] = [':blank:']; $status_name['continuous-integration/travis-ci/push'] = 'Unit Tests'; $status_name['continuous-integration/styleci/push'] = 'Style Check'; if (!array_key_exists($data->context, $status_name) || !array_key_exists($data->state, $status_colour)) { //$message = "/msg flash {$data->context}: {$data->state}"; break; } $message = "[b][url={$data->commit->html_url}]{$data->repository->full_name}[/url] [url={$data->target_url}]" . $status_name[$data->context] . '[/url][/b]: [b][i][color=' . $status_colour[$data->state] . ']' . ucfirst($data->state) . ' ' . $status_emotes[$data->state][array_rand($status_emotes[$data->state])] . '[/color][/i][/b]'; break; case 'watch': switch($data->action) { case 'started': $message = "[url={$data->sender->html_url}]{$data->sender->login}[/url] starred [url={$data->repository->html_url}]{$data->repository->full_name}[/url] :love:"; break; } break; case 'fork': $message = "[url={$data->forkee->html_url}]{$data->forkee->owner->login}[/url] forked [url={$data->repository->html_url}]{$data->repository->full_name}[/url] :omg:"; break; case 'issues': if(!in_array($data->action, ['opened', /*'edited',*/ 'closed', 'reopened'])) break; $message = "[b][url={$data->repository->html_url}]{$data->repository->full_name}[/url] [url={$data->sender->html_url}]{$data->sender->login}[/url] {$data->action} issue [/b][url={$data->issue->html_url}][b]#{$data->issue->number}[/b]: {$data->issue->title}[/url]"; break; case 'pull_request': if(!in_array($data->action, ['opened', /*'edited',*/ 'closed', 'reopened'])) break; $message = "[b][url={$data->repository->html_url}]{$data->repository->full_name}[/url]: [url={$data->sender->html_url}]{$data->sender->login}[/url] {$data->action} pull request [/b][url={$data->pull_request->html_url}][b]#{$data->pull_request->number}[/b]: {$data->pull_request->title}[/url]"; break; } if(!empty($message)) { var_dump($message); $sock = fsockopen($config['boat']['host'], $config['boat']['port'], $errno, $errstr, 5); $message = chr(1) . $message; $message = hash_hmac('sha256', $message, $config['boat']['secret'], true) . $message; fwrite($sock, $message); }