Add more context data to webhook templating (#1706)

Enable additional context data when building webhooks payload.
This commit is contained in:
Matias Bordese 2023-04-06 14:52:23 -03:00 committed by GitHub
parent 6884a42603
commit 2fbf3f503d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 73 additions and 4 deletions

View file

@ -5,8 +5,10 @@ from json import JSONDecodeError
from celery.utils.log import get_task_logger
from django.apps import apps
from django.conf import settings
from django.db.models import Prefetch
from apps.alerts.models import AlertGroup, AlertGroupLogRecord, EscalationPolicy
from apps.base.models import UserNotificationPolicyLogRecord
from apps.user_management.models import User
from apps.webhooks.models import Webhook, WebhookResponse
from apps.webhooks.utils import (
@ -89,7 +91,18 @@ def execute_webhook(webhook_pk, alert_group_id, user_id, escalation_policy_id):
return
try:
alert_group = AlertGroup.unarchived_objects.get(pk=alert_group_id)
personal_log_records = UserNotificationPolicyLogRecord.objects.filter(
alert_group_id=alert_group_id,
author__isnull=False,
type=UserNotificationPolicyLogRecord.TYPE_PERSONAL_NOTIFICATION_SUCCESS,
).select_related("author")
alert_group = (
AlertGroup.unarchived_objects.prefetch_related(
Prefetch("personal_log_records", queryset=personal_log_records, to_attr="sent_notifications")
)
.select_related("channel")
.get(pk=alert_group_id)
)
except AlertGroup.DoesNotExist:
return

View file

@ -5,6 +5,7 @@ import pytest
from django.utils import timezone
from apps.alerts.models import AlertGroupLogRecord, EscalationPolicy
from apps.base.models import UserNotificationPolicyLogRecord
from apps.public_api.serializers import IncidentSerializer
from apps.webhooks.models import Webhook
from apps.webhooks.tasks import execute_webhook, send_webhook_event
@ -180,14 +181,32 @@ def test_execute_webhook_via_escalation_ok(
@pytest.mark.django_db
def test_execute_webhook_ok_forward_all(
make_organization, make_user_for_organization, make_alert_receive_channel, make_alert_group, make_custom_webhook
make_organization,
make_user_for_organization,
make_alert_receive_channel,
make_alert_group,
make_user_notification_policy_log_record,
make_custom_webhook,
):
organization = make_organization()
user = make_user_for_organization(organization)
notified_user = make_user_for_organization(organization)
other_user = make_user_for_organization(organization)
alert_receive_channel = make_alert_receive_channel(organization)
alert_group = make_alert_group(
alert_receive_channel, acknowledged_at=timezone.now(), acknowledged=True, acknowledged_by=user.pk
)
for i in range(3):
make_user_notification_policy_log_record(
author=notified_user,
alert_group=alert_group,
type=UserNotificationPolicyLogRecord.TYPE_PERSONAL_NOTIFICATION_SUCCESS,
)
make_user_notification_policy_log_record(
author=other_user,
alert_group=alert_group,
type=UserNotificationPolicyLogRecord.TYPE_PERSONAL_NOTIFICATION_FAILED,
)
webhook = make_custom_webhook(
organization=organization,
url="https://something/{{ alert_group_id }}/",
@ -209,7 +228,24 @@ def test_execute_webhook_ok_forward_all(
"type": "acknowledge",
"time": alert_group.acknowledged_at.isoformat(),
},
"user": user.username,
"user": {
"id": user.public_primary_key,
"username": user.username,
"email": user.email,
},
"integration": {
"id": alert_receive_channel.public_primary_key,
"type": alert_receive_channel.integration,
"name": alert_receive_channel.short_name,
"team": None,
},
"notified_users": [
{
"id": notified_user.public_primary_key,
"username": notified_user.username,
"email": notified_user.email,
}
],
"alert_group": IncidentSerializer(alert_group).data,
"alert_group_id": alert_group.public_primary_key,
"alert_payload": "",

View file

@ -114,6 +114,16 @@ class EscapeDoubleQuotesDict(dict):
return original_str
def _serialize_event_user(user):
if not user:
return None
return {
"id": user.public_primary_key,
"username": user.username,
"email": user.email,
}
def serialize_event(event, alert_group, user, responses=None):
from apps.public_api.serializers import IncidentSerializer
@ -124,10 +134,20 @@ def serialize_event(event, alert_group, user, responses=None):
data = {
"event": event,
"user": user.username if user else None,
"user": _serialize_event_user(user),
"alert_group": IncidentSerializer(alert_group).data,
"alert_group_id": alert_group.public_primary_key,
"alert_payload": alert_payload_raw,
"integration": {
"id": alert_group.channel.public_primary_key,
"type": alert_group.channel.integration,
"name": alert_group.channel.short_name,
"team": alert_group.channel.team.name if alert_group.channel.team else None,
},
"notified_users": [
_serialize_event_user(user)
for user in set(notification.author for notification in alert_group.sent_notifications)
],
}
if responses:
data["responses"] = responses