DEV Community

Javid Jamae
Javid Jamae

Posted on • Originally published at ffmpeg-micro.com

Build a Slack Bot That Converts Videos on Demand

Originally published at ffmpeg-micro.com.

Your team uploads videos in Slack all day. Marketing shares raw footage, product records demos, support gets screen recordings from customers. Every time someone needs a video compressed, resized, or converted, the request goes to "that person who knows FFmpeg." That person is tired of it.

You can fix this with a Slack bot. User types /convert, the bot grabs the video, sends it to an FFmpeg API for processing, and posts the result back in the channel. No manual work. No one needs to learn FFmpeg. Total build time with n8n: about 30 minutes.

What You're Building

A Slack slash command (/convert) that:

  1. Takes a video file URL from Slack
  2. Sends it to FFmpeg Micro for processing (compress, transcode, resize)
  3. Posts the converted video back to the channel

The workflow runs in n8n. Slack handles the user interface. FFmpeg Micro handles the video processing. You write zero FFmpeg commands.

Prerequisites

  • A Slack workspace where you can create apps (you need admin access or permission to install apps)
  • An n8n instance (cloud or self-hosted)
  • An FFmpeg Micro API key (free tier works for testing: get one here)

Step 1: Create the Slack App

Go to api.slack.com/apps and create a new app. You need two things:

Slash command: Create a /convert command. Set the request URL to your n8n webhook URL (you'll get this in Step 2). The command description should be something like "Convert a video to MP4."

Bot permissions: Under OAuth & Permissions, add these scopes:

  • commands (for the slash command)
  • files:read (to download uploaded videos)
  • chat:write (to post the result back)
  • files:write (to upload the converted video)

Install the app to your workspace and save the Bot Token (xoxb-...).

Step 2: Build the n8n Workflow

Create a new workflow in n8n with these nodes:

Webhook Node (trigger)

Set method to POST. This receives the Slack slash command payload. Copy the webhook URL back to your Slack app's slash command configuration.

The payload from Slack includes text (whatever the user typed after /convert), channel_id, and user_id.

HTTP Request Node (download from Slack)

The user types /convert <file_url>. Extract the file URL from the webhook payload's text field. Download the file from Slack using an HTTP Request node:

GET {{ $json.body.text }}
Headers:
  Authorization: Bearer xoxb-your-bot-token
Enter fullscreen mode Exit fullscreen mode

Save the response as binary data.

HTTP Request Node (upload to FFmpeg Micro)

Upload the downloaded file to FFmpeg Micro using the presigned URL flow:

POST https://api.ffmpeg-micro.com/v1/upload/presigned-url
Headers:
  Authorization: Bearer YOUR_FFMPEG_MICRO_KEY
  Content-Type: application/json
Body:
{
  "filename": "slack-video.mp4",
  "contentType": "video/mp4",
  "fileSize": {{ $binary.data.fileSize }}
}
Enter fullscreen mode Exit fullscreen mode

This returns a result.uploadUrl. Use another HTTP Request node to PUT the binary file to that URL. Then confirm the upload:

POST https://api.ffmpeg-micro.com/v1/upload/confirm
Headers:
  Authorization: Bearer YOUR_FFMPEG_MICRO_KEY
  Content-Type: application/json
Body:
{
  "filename": "{{ $json.result.filename }}",
  "fileSize": {{ $binary.data.fileSize }}
}
Enter fullscreen mode Exit fullscreen mode

HTTP Request Node (create transcode)

Now trigger the actual video processing:

POST https://api.ffmpeg-micro.com/v1/transcodes
Headers:
  Authorization: Bearer YOUR_FFMPEG_MICRO_KEY
  Content-Type: application/json
Body:
{
  "inputs": [{"url": "{{ $json.result.gcsUrl }}"}],
  "outputFormat": "mp4",
  "preset": {
    "quality": "high",
    "resolution": "1080p"
  }
}
Enter fullscreen mode Exit fullscreen mode

This returns a job ID and status queued.

Wait Node + Poll for Completion

Add a Wait node (10 seconds) followed by an HTTP Request that checks the job status:

GET https://api.ffmpeg-micro.com/v1/transcodes/{{ $json.id }}
Headers:
  Authorization: Bearer YOUR_FFMPEG_MICRO_KEY
Enter fullscreen mode Exit fullscreen mode

Use an IF node to check if status equals completed. If not, loop back to the Wait node. If yes, continue to the next step.

The completed response includes an outputUrl with the download link.

HTTP Request Node (post result to Slack)

Download the processed video from outputUrl, then upload it to Slack:

POST https://slack.com/api/files.uploadV2
Headers:
  Authorization: Bearer xoxb-your-bot-token
  Content-Type: multipart/form-data
Body:
  channel_id: {{ $json.body.channel_id }}
  filename: converted-video.mp4
  file: [binary data from outputUrl]
Enter fullscreen mode Exit fullscreen mode

Add a final Slack message node to confirm:

POST https://slack.com/api/chat.postMessage
Headers:
  Authorization: Bearer xoxb-your-bot-token
  Content-Type: application/json
Body:
{
  "channel": "{{ $json.body.channel_id }}",
  "text": "Video converted and uploaded. Check the thread above."
}
Enter fullscreen mode Exit fullscreen mode

The Full Workflow at a Glance

Webhook (Slack /convert)
  → Download video from Slack
  → Upload to FFmpeg Micro (presign → PUT → confirm)
  → Create transcode job
  → Poll until completed
  → Download result
  → Upload to Slack channel
  → Post confirmation message
Enter fullscreen mode Exit fullscreen mode

Seven nodes in n8n. No code except the JSON bodies above. The whole thing runs on Slack's infrastructure (for the UX) and FFmpeg Micro's infrastructure (for the processing).

Making It Production-Ready

Error handling: Add an Error Trigger node in n8n. If any step fails, post a message to the requesting channel: "Video conversion failed. Try again or contact #engineering."

File validation: Before sending to FFmpeg Micro, check the file size. The free tier has limits. Post a helpful message if the file is too large.

Multiple operations: Instead of always compressing to MP4, parse the command text for options. /convert webm converts to WebM. /convert 720p resizes. You can map these to different FFmpeg Micro presets.

Rate limiting: If your team processes a lot of videos, add a Queue node before the FFmpeg Micro API call. This prevents hitting rate limits during busy periods.

Common Pitfalls

Slack file URLs need authentication. You can't just fetch a Slack file URL directly. You need the bot token in the Authorization header. Without it, you'll get a 302 redirect to a login page.

Presigned URLs expire. The upload URL from FFmpeg Micro is valid for a limited time. Don't add a long delay between getting the URL and uploading the file.

Large files take time. A 500MB video might take a few minutes to process. Make sure your n8n Wait/poll loop has enough iterations and a reasonable timeout so you don't give up too early.

FAQ

Can I use Make.com instead of n8n for this?

Yes. Make.com has HTTP modules that work the same way. The flow is identical: webhook trigger, HTTP requests to Slack and FFmpeg Micro, poll for completion, upload result. n8n gives you more control over error handling and looping, which matters for the polling step.

What video formats does this support?

FFmpeg Micro accepts MP4, WebM, AVI, QuickTime (MOV), and MKV as inputs. You can convert to any of these as output. Most Slack uploads are MP4 or MOV, so the bot handles them without format detection.

How much does this cost to run?

FFmpeg Micro's free tier includes processing time to test with. For a team converting 10-20 videos per week, the Starter plan at $19/month covers it. n8n's free tier handles the workflow automation. Total cost for most teams: under $20/month.

Do I need to install FFmpeg anywhere?

No. That's the point. FFmpeg Micro runs FFmpeg in the cloud. Your n8n instance makes HTTP requests. Your Slack workspace handles the user interface. No binaries, no servers, no Docker containers with FFmpeg compiled in.

Last verified: June 2026. All API endpoints tested against FFmpeg Micro v1 and Slack API v2.

Top comments (0)