Skip to content

About

This is a discord webhook docker container that allows you to easily and reliably upload .jpg images passed through 'run a program' on Streamerbot to a Discord Webhook.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

8 Commits

Folders and files

Repository files navigation

Discord Uploader (Docker) + Streamer.bot Integration

Upload images to a Discord channel via webhook, archive the originals, and (optionally) post the Discord jump link to Twitch chat using Streamer.bot.


Repository Contents

  • Dockerfile — Python 3.11-slim base for a tiny FastAPI service.
  • requirements.txt — Python dependencies for the service.
  • app.py — FastAPI app exposing POST /upload:
    • reads a file from a host-mounted folder,
    • posts it to a Discord webhook (?wait=true),
    • returns the Discord jump URL,
    • moves the original file into an archive (preserves subfolders, avoids name collisions).
  • docker-compose.yml — service definition with environment variables, volume mounts, and host port binding.
  • discord_push.ps1 — helper PowerShell script you can call from Streamer.bot ("Run Program") to post a file + caption.

Typically you will generate a caption file (e.g., image_info.txt) with your own script (such as extract_info.py or a .cmd), then call discord_push.ps1 with the image path.


How It Works (Flow)

  1. Your automation (e.g., Streamer.bot File Watcher) creates image_info.txt and produces an image under your configured upload folder.
  2. Streamer.bot runs discord_push.ps1 "<full path to image>".
  3. The script computes a relative path (under your upload root), reads image_info.txt, and POSTs JSON to the Docker service:
    {
      "rel_path": "sub/dirs/filename.jpg",
      "caption": "Shot on ...\n1/125s • f/2.8 • ISO 400"
    }
  4. The Docker service loads the file from /shared/<rel_path>, uploads to Discord via webhook using ?wait=true, builds the jump URL, returns it, and moves the original file to /archive/<rel_path>.
  5. The script writes the link to last_discord_link.txt in the upload root so you can post it to Twitch chat in a later step.
[ Streamer.bot ] --(Run Program)--> [ discord_push.ps1 ]
        |                                      |
        | JSON: rel_path + caption             v
        |------------------------------> [ Docker service ]
                                              |
                           Discord upload (webhook with ?wait=true)
                                              |
                               <--- returns message id (jump URL)
                                              |
                              moves original to /archive/...

Requirements

  • Docker Desktop on Windows (enable drive sharing for the drive you mount, e.g., X:/Your_working_dir/).
  • A Discord webhook for the target text channel (Server → Channel → Integrations → Webhooks).
  • The channel’s Guild (Server) ID and Channel ID (Discord Settings → Advanced → enable Developer Mode; then right‑click server/channel → Copy ID).
  • Optional: Streamer.bot (Windows).

Inside the container, Python deps are minimal (from requirements.txt):

fastapi
uvicorn[standard]
requests

Configuration

1) docker-compose.yml (example)

The example binds host port 8082 → container 8080 to avoid conflicts (e.g., SRTLA info ports). Change as needed.

version: "3.8"

services:
  discord-uploader:
    build: .
    container_name: discord-uploader
    environment:
      DISCORD_WEBHOOK_URL: "https://discord.com/api/webhooks/xxxxx/xxxxx"
      DISCORD_GUILD_ID: "123456789012345678"
      DISCORD_CHANNEL_ID: "234567890123456789"
      SHARED_DIR: "/shared"      # service reads images from here
      ARCHIVE_DIR: "/archive"    # originals are moved here after upload
      API_KEY: "super-secret-long-random-string"  # shared secret required by the API
    volumes:
      - "X:/Your_working_dir/upload:/shared:ro"
      - "X:/Your_working_dir/archive:/archive:rw"
    ports:
      - "127.0.0.1:8082:8080"   # host:container
    restart: always

Windows path tips

  • Keep the quotes around host paths with spaces.
  • Use forward slashes with the drive letter (H:/...) in Docker Desktop.
  • Ensure the H: drive is shared in Docker Desktop (Settings → Resources → File sharing).

2) Environment Variables

  • DISCORD_WEBHOOK_URL — the webhook to receive uploads.
  • DISCORD_GUILD_ID / DISCORD_CHANNEL_ID — used to build the clickable jump link.
  • SHARED_DIR — container path where files are read. Bind-mount your upload folder to this.
  • ARCHIVE_DIR — container path where originals are moved after successful upload.
  • API_KEY — a shared secret. Requests must include header X-API-Key: <value>, otherwise 401. (If unset/empty, the check is skipped.)

Build & Run

From the folder with Dockerfile, app.py, and docker-compose.yml:

docker compose up -d --build
docker compose logs -f discord-uploader

Common gotchas

  • If Docker can’t find your compose file, ensure it’s named docker-compose.yml and you’re in that folder.
  • After editing volumes or env vars, recreate the service:
    docker compose down
    docker compose up -d --build

API Contract

  • POST /upload

    Body (JSON):

    {
      "rel_path": "sub/dir/file.jpg",
      "caption": "text to post with the image"
    }

    Headers: X-API-Key: <your secret> (required if API_KEY is set).

    Success (200):

    {
      "jump_url": "https://discord.com/channels/<guild>/<channel>/<message_id>",
      "archived_to": "/archive/sub/dir/file.jpg"
    }

    Behavior summary: validates rel_path stays within /shared, reads the file, posts to Discord with ?wait=true to retrieve the created message, then moves the original to /archive (creates subfolders and avoids collisions).


Streamer.bot — “Run Program” Integration

1) Helper script: discord_push.ps1

This script:

  • Verifies the image is under your upload root,
  • Computes the relative path for the API,
  • Reads the caption from $Root/image_info.txt (UTF‑8),
  • POSTs to the Docker service with your API_KEY,
  • Saves the returned link to $Root/last_discord_link.txt (so you can post it to Twitch later).
param(
  [Parameter(Mandatory=$true, Position=0)]
  [string]$ImagePath,

  [string]$Root   = "X:/Your_working_dir/",
  [string]$Api    = "http://127.0.0.1:8082/upload",
  [string]$ApiKey = "super-secret-long-random-string"
)

$ErrorActionPreference = "Stop"

# Normalize paths
$full     = [IO.Path]::GetFullPath((Resolve-Path -LiteralPath $ImagePath))
$rootFull = ([IO.Path]::GetFullPath($Root)).TrimEnd('\','/') + '\'
if (-not $full.ToLower().StartsWith($rootFull.ToLower())) {
  throw "Image '$full' is not under root '$rootFull'."
}

# Relative path for API
$rel = $full.Substring($rootFull.Length).TrimStart('\','/')

# Caption: $Root/image_info.txt (UTF-8)
$captionPath = [IO.Path]::Combine($rootFull, 'image_info.txt')
$caption = ""
if (Test-Path -LiteralPath $captionPath) {
  $caption = [System.IO.File]::ReadAllText($captionPath, [System.Text.Encoding]::UTF8)
}

# POST
$payload = @{ rel_path = $rel; caption = $caption } | ConvertTo-Json -Depth 3 -Compress
$headers = @{ "X-API-Key" = $ApiKey }

$r = Invoke-RestMethod -Method Post -Uri $Api `
     -Headers $headers -ContentType "application/json; charset=utf-8" -Body $payload

# Hand-off options
Set-Variable -Name discordLink -Value $r.jump_url -Scope Script
[IO.File]::WriteAllText(([IO.Path]::Combine($rootFull,'last_discord_link.txt')), $r.jump_url)
$r.jump_url

2) Add to your Streamer.bot action

  • Action trigger: your file watcher (pointing at the upload folder).
  • Sub-actions:
    1. Run Program — generate caption (your extract_info.py or .cmd) with Start In set to your upload root so it writes image_info.txt there.
    2. Run Program — call PowerShell to upload:
      • Program: powershell
      • Arguments:
        -NoProfile -ExecutionPolicy Bypass -File "X:/Your_working_dir/discord_push.ps1" "%{file.fullPath}%"
        
    3. Send Message (Twitch) — read and post the link from the file:
      • PowerShell sub-action example:
        $link = Get-Content "X:/Your_working_dir/last_discord_link.txt" -Raw
        # Use $link as the message text in your Twitch Send Message step
      • Or run a separate action that watches for last_discord_link.txt creation.

Why file hand-off? Some Streamer.bot builds don’t expose a “capture stdout” value from Run Program. Writing last_discord_link.txt makes the link available to any later step without extra wiring.


Troubleshooting

  • {"detail":"file not found: /shared/..."} — The container can’t see your file. Check compose volumes, drive sharing, and that PowerShell $Root matches the host path mapped to /shared.
  • 401 bad key — The header X-API-Key doesn’t match the container’s API_KEY.
  • Execution policy errors — Use -ExecutionPolicy Bypass with -File in Streamer.bot’s Run Program.
  • Weird symbols for • in the console — Console code page only; the API receives UTF‑8 correctly.
  • Discord “Request entity too large (40005)” — Image exceeded the server’s upload limit (rare if camera JPEGs are 2–8 MB).

Security Notes

  • Keep the service bound to 127.0.0.1 (as in the compose example) unless you need LAN access.
  • Always set a strong API_KEY. If it leaks, rotate it (change compose env + redeploy).
  • Treat the webhook URL as a secret.

License

MIT (or your preference).

About

This is a discord webhook docker container that allows you to easily and reliably upload .jpg images passed through 'run a program' on Streamerbot to a Discord Webhook.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages