Skip to content

Instantly share code, notes, and snippets.

@Benjaminhu
Last active November 14, 2022 14:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Benjaminhu/90471b8f4fc51305a8212223996c4994 to your computer and use it in GitHub Desktop.
Save Benjaminhu/90471b8f4fc51305a8212223996c4994 to your computer and use it in GitHub Desktop.
This script can act as a middleman between Sentry's webhook system and Google Chat Incoming Webhooks
<?php
$googleChatWebhookURL = '<YOUR-GOOGLE-CHAT-WEBHOOK-URL>';
$integrationClientSecret = '<YOUR-Sentry-Settings-integration-Edit Integration-CREDENTIALS-Client Secret>';
/**
* https://developers.google.com/chat/how-tos/webhooks#step_2_write_the_webhook_script
* https://developers.google.com/chat/api/guides/message-formats/basic
*/
function getSimpleChatMessage(array $params): array
{
return [
'text' => sprintf('🚨 <%s|Sentry issue>: `%s` 📣 *%s count* 🚨' . PHP_EOL . '```%s```',
getSentryIssueURL($params),
$params['issueId'],
number_format($params['count'], 0, null, ' '),
$params['metadataValue'],
)
];
}
/**
* https://developers.google.com/chat/api/guides/message-formats/cards
* TODO: SOON
*/
function getCardChatMessage(array $params): array
{
return [];
}
function verifySignature(string $body, string $signature, string $secret = ''): bool
{
return (getHash($secret, $body) === $signature);
}
function getHash(string $secret, string $content): string
{
return hash_hmac('sha256', $content, utf8_encode($secret));
}
/**
* @throws JsonException
*/
function getSentryData(string $content): array
{
return json_decode($content, true, 512, JSON_THROW_ON_ERROR);
}
/**
* https://docs.sentry.io/product/integrations/integration-platform/webhooks/issues/
*/
function getChatMessageParams(array $json): array
{
$issue = $json['data']['issue'];
return [
'organisation' => $issue['project']['name'],
'projectId' => $issue['project']['id'],
'issueId' => $issue['id'],
'title' => $issue['title'],
'metadataValue' => $issue['metadata']['value'],
'count' => $issue['count'],
];
}
function getSentryIssueURL(array $params): string
{
return sprintf('https://sentry.io/organizations/%s/issues/%s/?project=%s',
$params['organisation'],
$params['issueId'],
$params['projectId'],
);
}
/**
* @throws JsonException
*/
function sendGoogleChatMessage(string $webhookURL, array $message): void
{
$ch = curl_init($webhookURL);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($message, JSON_THROW_ON_ERROR));
curl_setopt( $ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_exec($ch);
}
$sentrySignature = $_SERVER['HTTP_SENTRY_HOOK_SIGNATURE'] ?? '';
$sentryBodyContent = (string)file_get_contents('php://input');
if ( ! verifySignature($sentryBodyContent, $sentrySignature, $integrationClientSecret)) {
header('Location: /');
exit;
}
$jsonData = getSentryData($sentryBodyContent);
$params = getChatMessageParams($jsonData);
$message = getSimpleChatMessage($params);
sendGoogleChatMessage($googleChatWebhookURL, $message);
@Benjaminhu
Copy link
Author

Preview example:
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment