Skip to content

Commit

Permalink
use channel id with new slack api for file uploads
Browse files Browse the repository at this point in the history
  • Loading branch information
eschutho committed Jun 1, 2024
1 parent 35e1820 commit 384b043
Show file tree
Hide file tree
Showing 3 changed files with 207 additions and 164 deletions.
84 changes: 52 additions & 32 deletions superset/reports/notifications/slack.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
import logging
from collections.abc import Sequence
from io import IOBase
from typing import Union
from typing import List, Union

import backoff
import pandas as pd
from flask import g
from flask_babel import gettext as __
from slack_sdk import WebClient
from slack_sdk.errors import (
BotUserAccessError,
SlackApiError,
Expand Down Expand Up @@ -60,16 +61,24 @@ class SlackNotification(BaseNotification): # pylint: disable=too-few-public-met

type = ReportRecipientType.SLACK

def _get_channel(self) -> str:
def _get_channels(self, client: WebClient) -> List[str]:
"""
Get the recipient's channel(s).
Note Slack SDK uses "channel" to refer to one or more
channels. Multiple channels are demarcated by a comma.
:returns: The comma separated list of channel(s)
:returns: A list of channel ids: "EID676L"
"""
recipient_str = json.loads(self._recipient.recipient_config_json)["target"]

return ",".join(get_email_address_list(recipient_str))
channel_recipients = get_email_address_list(recipient_str)

conversations_list_response = client.conversations_list(
types="public_channel,private_channel"
)

return [
c["id"]
for c in conversations_list_response["channels"]
if c["name"] in channel_recipients
]

def _message_template(self, table: str = "") -> str:
return __(
Expand Down Expand Up @@ -115,15 +124,19 @@ def _get_body(self) -> str:

# Flatten columns/index so they show up nicely in the table
df.columns = [
" ".join(str(name) for name in column).strip()
if isinstance(column, tuple)
else column
(
" ".join(str(name) for name in column).strip()
if isinstance(column, tuple)
else column
)
for column in df.columns
]
df.index = [
" ".join(str(name) for name in index).strip()
if isinstance(index, tuple)
else index
(
" ".join(str(name) for name in index).strip()
if isinstance(index, tuple)
else index
)
for index in df.index
]

Expand Down Expand Up @@ -162,37 +175,44 @@ def _get_body(self) -> str:

def _get_inline_files(
self,
) -> tuple[Union[str, None], Sequence[Union[str, IOBase, bytes]]]:
) -> Sequence[Union[str, IOBase, bytes]]:
if self._content.csv:
return ("csv", [self._content.csv])
return [self._content.csv]
if self._content.screenshots:
return ("png", self._content.screenshots)
return self._content.screenshots
if self._content.pdf:
return ("pdf", [self._content.pdf])
return (None, [])
return [self._content.pdf]
return []

@backoff.on_exception(backoff.expo, SlackApiError, factor=10, base=2, max_tries=5)
@statsd_gauge("reports.slack.send")
def send(self) -> None:
file_type, files = self._get_inline_files()
title = self._content.name
channel = self._get_channel()
body = self._get_body()
global_logs_context = getattr(g, "logs_context", {}) or {}
try:
client = get_slack_client()
channels = self._get_channels(client)

if channels == []:
raise NotificationParamException("No valid channel found")

files = self._get_inline_files()
title = self._content.name

body = self._get_body()

# files_upload returns SlackResponse as we run it in sync mode.
if files:
for file in files:
client.files_upload_v2(
channels=channel,
file=file,
initial_comment=body,
title=title,
filetype=file_type,
)
else:
client.chat_postMessage(channel=channel, text=body)
for channel in channels:
if len(files):
for file in files:
client.files_upload_v2(
channel=channel,
file=file,
initial_comment=body,
title=title,
)
else:
client.chat_postMessage(channel=channel, text=body)

logger.info(
"Report sent to slack",
extra={
Expand Down
62 changes: 0 additions & 62 deletions superset/tasks/slack_util.py

This file was deleted.

Loading

0 comments on commit 384b043

Please sign in to comment.