예제 #1
0
def send_notification_as_slack(
    notification: BaseNotification,
    users: Set[User],
    shared_context: Mapping[str, Any],
    extra_context_by_user_id: Mapping[str, Any],
) -> None:
    """
    Send an "activity notification" to a Slack user which are workflow and deploy notification types
    """

    external_actors_by_user = get_integrations_by_user_id(
        notification.organization, users)

    client = SlackClient()
    for user in users:
        extra_context = (extra_context_by_user_id or {}).get(user.id, {})
        try:
            channel, token = get_channel_and_token(external_actors_by_user,
                                                   user)
        except AttributeError as e:
            logger.info(
                "notification.fail.invalid_slack",
                extra={
                    "error": str(e),
                    "notification": notification,
                    "user": user.id,
                },
            )
            continue

        context = get_context(notification, user, shared_context,
                              extra_context)
        attachment = [build_notification_attachment(notification, context)]
        payload = {
            "token": token,
            "channel": channel,
            "link_names": 1,
            "attachments": json.dumps(attachment),
        }
        try:
            client.post("/chat.postMessage", data=payload, timeout=5)
        except ApiError as e:
            logger.info(
                "notification.fail.slack_post",
                extra={
                    "error": str(e),
                    "notification": notification,
                    "user": user.id,
                    "channel_id": channel,
                },
            )
            continue

    metrics.incr(
        "activity.notifications.sent",
        instance="slack.activity.notification",
        skip_internal=False,
    )
예제 #2
0
def send_notification_as_slack(
    notification: BaseNotification,
    recipients: Union[Set[User], Set[Team]],
    shared_context: Mapping[str, Any],
    extra_context_by_user_id: Mapping[str, Any],
) -> None:
    """ Send an "activity" or "alert rule" notification to a Slack user or team. """
    external_actors_by_recipient = get_integrations_by_recipient_id(
        notification.organization, recipients)
    client = SlackClient()
    for recipient in recipients:
        extra_context = (extra_context_by_user_id or {}).get(recipient.id, {})
        try:
            channel, token = get_channel_and_token(
                external_actors_by_recipient, recipient)
        except AttributeError as e:
            logger.info(
                "notification.fail.invalid_slack",
                extra={
                    "error": str(e),
                    "notification": notification,
                    "recipient": recipient.id,
                },
            )
            continue

        context = get_context(notification, recipient, shared_context,
                              extra_context)
        attachment = [build_notification_attachment(notification, context)]
        payload = {
            "token": token,
            "channel": channel,
            "link_names": 1,
            "attachments": json.dumps(attachment),
        }
        try:
            client.post("/chat.postMessage", data=payload, timeout=5)
        except ApiError as e:
            logger.info(
                "notification.fail.slack_post",
                extra={
                    "error": str(e),
                    "notification": notification,
                    "recipient": recipient.id,
                    "channel_id": channel,
                },
            )
            continue

    key = get_key(notification)
    metrics.incr(
        f"{key}.notifications.sent",
        instance=f"slack.{key}.notification",
        skip_internal=False,
    )
예제 #3
0
def send_notification_as_slack(
    notification: ActivityNotification,
    users: Mapping[User, int],
    shared_context: Mapping[str, Any],
) -> None:
    external_actors_by_user = get_integrations_by_user_id(
        notification.organization, users.keys())

    client = SlackClient()
    for user, reason in users.items():
        try:
            channel, token = get_channel_and_token(external_actors_by_user,
                                                   user)
        except AttributeError as e:
            logger.info(
                "notification.fail.invalid_slack",
                extra={
                    "error": str(e),
                    "notification": notification,
                    "user": user.id,
                },
            )
            continue

        context = get_context(notification, user, reason, shared_context)
        attachment = [build_notification_attachment(notification, context)]
        payload = {
            "token": token,
            "channel": channel,
            "link_names": 1,
            "attachments": json.dumps(attachment),
        }
        try:
            client.post("/chat.postMessage", data=payload, timeout=5)
        except ApiError as e:
            logger.info(
                "notification.fail.slack_post",
                extra={
                    "error": str(e),
                    "notification": notification,
                    "user": user.id,
                    "channel_id": channel,
                },
            )
            continue

    metrics.incr(
        "activity.notifications.sent",
        instance="slack.activity.notification",
        skip_internal=False,
    )
예제 #4
0
def send_notification_as_slack(notification: ActivityNotification, user: User,
                               context: Mapping[str, Any]) -> None:
    external_actors = ExternalActor.objects.filter(
        provider=ExternalProviders.SLACK.value,
        actor=user.actor,
        organization=notification.organization,
    ).select_related("integration")
    client = SlackClient()
    for external_actor in external_actors:
        attachment = [build_notification_attachment(notification, context)]
        integration = external_actor.integration
        if integration:
            token = integration.metadata["access_token"]
        payload = {
            "token": token,
            "channel": external_actor.external_id,
            "link_names": 1,
            "attachments": json.dumps(attachment),
        }
        try:
            client.post("/chat.postMessage", data=payload, timeout=5)
        except ApiError as e:
            logger.info(
                "notification.fail.slack_post",
                extra={
                    "error": str(e),
                    "notification": notification,
                    "user": user.id,
                    "channel_id": external_actor.external_id,
                },
            )
        metrics.incr(
            "activity.notifications.sent",
            instance="slack.activity.notification",
            skip_internal=False,
        )
예제 #5
0
def send_notification_as_slack(
    notification: BaseNotification,
    recipients: Union[Set[User], Set[Team]],
    shared_context: Mapping[str, Any],
    extra_context_by_user_id: Mapping[str, Any],
) -> None:
    """Send an "activity" or "alert rule" notification to a Slack user or team."""
    client = SlackClient()
    data = get_channel_and_token_by_recipient(notification.organization,
                                              recipients)

    for recipient, tokens_by_channel in data.items():
        is_multiple = True if len([token for token in tokens_by_channel
                                   ]) > 1 else False
        if is_multiple:
            logger.info(
                "notification.multiple.slack_post",
                extra={
                    "notification": notification,
                    "recipient": recipient.id,
                },
            )
        extra_context = (extra_context_by_user_id or {}).get(recipient.id, {})
        context = get_context(notification, recipient, shared_context,
                              extra_context)
        attachment = [
            build_notification_attachment(notification, context, recipient)
        ]
        for channel, token in tokens_by_channel.items():
            # unfurl_links and unfurl_media are needed to preserve the intended message format
            # and prevent the app from replying with help text to the unfurl
            payload = {
                "token": token,
                "channel": channel,
                "link_names": 1,
                "unfurl_links": False,
                "unfurl_media": False,
                "text": notification.get_notification_title(),
                "attachments": json.dumps(attachment),
            }
            try:
                client.post("/chat.postMessage", data=payload, timeout=5)
            except ApiError as e:
                logger.info(
                    "notification.fail.slack_post",
                    extra={
                        "error": str(e),
                        "notification": notification,
                        "recipient": recipient.id,
                        "channel_id": channel,
                        "is_multiple": is_multiple,
                    },
                )
                continue

    key = get_key(notification)
    metrics.incr(
        f"{key}.notifications.sent",
        instance=f"slack.{key}.notification",
        skip_internal=False,
    )