Download icon
Upload icon

Send a Slack file attachment with the Slack App API

Download a CSV over HTTP and upload it as a real Slack file attachment via the Slack App API, no webhook workaround needed.

Categories
Business
id: send-slack-attachment
namespace: company.team

tasks:
  - id: dataset
    type: io.kestra.plugin.core.http.Download
    uri: https://huggingface.co/datasets/kestra/datasets/raw/main/csv/products.csv

  - id: upload_to_slack
    type: io.kestra.plugin.slack.app.files.Upload
    token: "{{ secret('SLACK_BOT_TOKEN') }}"
    channels:
      - "#general"
    from: "{{ outputs.dataset.uri }}"
    filename: data.csv
    title: Here is your dataset
    initialComment: Here is your dataset, attached as a CSV file.

Automate delivering a downloaded file straight to a Slack channel as a real attachment, not just a link in a text message. This blueprint downloads a CSV dataset over HTTP, then uploads it to Slack as a data.csv file using the Slack App API, so you can replace manual "here's the file" uploads with a repeatable, auditable workflow.

File attachments require Slack's App API (a bot token with the files:write scope): Slack's Incoming Webhooks cannot send files, only text and Block Kit messages.

How it works

  1. The dataset task (io.kestra.plugin.core.http.Download) downloads a CSV file from a public HTTP URL and stores it in Kestra's internal storage, exposing it as {{ outputs.dataset.uri }}.
  2. The upload_to_slack task (io.kestra.plugin.slack.app.files.Upload) authenticates with a bot token pulled from {{ secret('SLACK_BOT_TOKEN') }} and uploads the downloaded file to #general as data.csv, with title shown alongside it and initialComment attaching a message to the file in the same call.

What you get

  • A CSV automatically downloaded and delivered to Slack as a real file attachment.
  • Delivery through the Slack App API without exposing the bot token in your flow definition.
  • A reusable pattern for sharing any generated or downloaded file straight to a channel.

Who it's for

  • Data engineers shipping recurring report or dataset exports to a Slack channel.
  • Platform and ops teams that want files delivered where their team already works.
  • Anyone replacing manual file-sharing steps with automation.

Why orchestrate this with Kestra

The Slack API can accept a file upload, but it cannot schedule the job, build the file, or react to upstream events. Kestra adds event and schedule triggers, automatic retries on transient HTTP or Slack API failures, full execution lineage so you can see exactly which file was sent and when, and a declarative YAML definition that lives in version control. The Slack upload becomes the last link in a pipeline rather than a disconnected manual action.

Prerequisites

  • A Slack App with the files:write scope, installed to your workspace, and its bot token.
  • The bot invited to the target channel (#general here).
  • Network access from your Kestra instance to the Slack API.

Secrets

  • SLACK_BOT_TOKEN: your Slack App bot token, used to authenticate the upload.

Quick start

  1. Create a Slack App with the files:write scope, install it to your workspace, and invite the bot to the target channel.
  2. Add the bot token as the SLACK_BOT_TOKEN secret in your Kestra instance.
  3. Update the channels list in upload_to_slack to your target channel(s).
  4. Execute the flow and confirm the channel receives data.csv as an attachment.

How to extend

  • Swap the dataset URL or replace it with a task that generates a report (for example a query export) and upload that output instead.
  • Add a schedule trigger to send the file daily or weekly.
  • Fan out the same downloaded file to email as well, using io.kestra.plugin.email.MailSend with an attachments entry pointing at {{ outputs.dataset.uri }}.
  • Post the file as a thread reply to an existing message by setting timestamp to that message's Slack ts.

Links

Orchestrate with Kestra
Orchestrate Slack with Kestra
Share this Blueprint
See How

New to Kestra?

Use blueprints to kickstart your first workflows.