Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion docs/configuration/sinks/ms-teams.rst
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,35 @@ For example:
- ms_teams_sink:
name: main_ms_teams_sink
webhook_url: teams-incoming-webhook
prefer_redirect_to_platform: false
prefer_redirect_to_platform: false

File Attachments
-------------------------------------------------------------------

MS Teams Power Automate workflow webhooks have a strict 28KB payload size limit.
Robusta automatically detects Power Automate URLs and disables file attachments
to avoid exceeding this limit.

**Auto-detection behavior:**

- Power Automate URLs (``*.api.powerplatform.com``): files disabled by default
- Legacy webhook URLs (``*.webhook.office.com``): files enabled by default

**Override auto-detection:**

You can explicitly control file attachments using the ``send_files`` parameter:

.. code-block:: yaml

sinksConfig:
- ms_teams_sink:
name: main_ms_teams_sink
webhook_url: teams-incoming-webhook
send_files: true # Force enable files (override auto-detection)
# send_files: false # Force disable files

.. note::

When ``send_files`` is false (or auto-detected as false for Power Automate),
all file attachments (images, logs, graphs, etc.) will not be included in
the MS Teams message. Text-based content will still be sent normally.
7 changes: 7 additions & 0 deletions src/robusta/core/sinks/msteams/msteams_sink.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ def __init__(self, sink_config: MsTeamsSinkConfigWrapper, registry):
self.sink_config = sink_config.ms_teams_sink

def write_finding(self, finding: Finding, platform_enabled: bool):
"""Write a finding to the MS Teams channel via webhook.

Args:
finding: The finding to send to MS Teams.
platform_enabled: Whether the Robusta platform is enabled for enhanced links.
"""
MsTeamsSender.send_finding_to_ms_teams(
self.webhook_url,
finding,
Expand All @@ -20,4 +26,5 @@ def write_finding(self, finding: Finding, platform_enabled: bool):
self.account_id,
self.webhook_override,
self.sink_config.prefer_redirect_to_platform,
self.sink_config.send_files,
)
1 change: 1 addition & 0 deletions src/robusta/core/sinks/msteams/msteams_sink_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
class MsTeamsSinkParams(SinkBaseParams):
webhook_url: str
webhook_override: Optional[str] = None
send_files: Optional[bool] = None # Auto-detect: False for Power Automate, True for legacy

@classmethod
def _get_sink_type(cls):
Expand Down
35 changes: 35 additions & 0 deletions src/robusta/integrations/msteams/sender.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
from typing import Optional

from robusta.core.reporting import (
BaseBlock,
Expand All @@ -18,6 +19,15 @@
from robusta.integrations.msteams.msteams_msg import MsTeamsMsg


def _is_power_automate_url(url: str) -> bool:
"""Check if URL is a Power Automate workflow webhook (has 28KB payload limit).

Power Automate URLs contain '.api.powerplatform.com' or '/powerautomate/'.
Legacy connector URLs use '*.webhook.office.com' and don't have the 28KB limit.
"""
return ".api.powerplatform.com" in url or "/powerautomate/" in url


class MsTeamsSender:
@classmethod
def __to_ms_teams(cls, block: BaseBlock, msg: MsTeamsMsg):
Expand Down Expand Up @@ -61,15 +71,40 @@ def send_finding_to_ms_teams(
account_id: str,
webhook_override: str,
prefer_redirect_to_platform: bool,
send_files: Optional[bool] = None,
):
"""Send a finding to MS Teams via webhook.

Args:
webhook_url: The MS Teams webhook URL.
finding: The finding to send.
platform_enabled: Whether the Robusta platform is enabled.
cluster_name: The name of the cluster.
account_id: The Robusta account ID.
webhook_override: Optional webhook URL override pattern.
prefer_redirect_to_platform: Whether to prefer platform links over Prometheus.
send_files: Whether to include file attachments. None (default) auto-detects
based on webhook URL: disabled for Power Automate (28KB limit), enabled
for legacy webhooks. Explicit True/False overrides auto-detection.
"""
webhook_url = MsTeamsWebhookUrlTransformer.template(
webhook_override=webhook_override, default_webhook_url=webhook_url, annotations=finding.subject.annotations
)

# Auto-detect send_files based on webhook URL if not explicitly set
if send_files is None:
send_files = not _is_power_automate_url(webhook_url)

msg = MsTeamsMsg(webhook_url, prefer_redirect_to_platform)
msg.write_title_and_desc(platform_enabled, finding, cluster_name, account_id)

for enrichment in finding.enrichments:
files_blocks, other_blocks = cls.__split_block_to_files_and_all_the_rest(enrichment)

# Filter out all files when send_files is False to avoid 28KB payload limit
if not send_files:
files_blocks = []

for block in other_blocks:
cls.__to_ms_teams(block, msg)

Expand Down
Loading