Run your own Linky

Self-hosting is optional for ordinary social links and translations, and required for Erome. To use the existing hosted bot, add Linky to your server and enable it with /setup enabled: true. No hosting or code is required for that option.

The public Linky repository contains the bot, tests, Docker setup and MIT license. Self-hosting gives you control of the bot token, allowed channels, translation settings, stored data and the supported Erome feature. You supply its hosting and API credentials. Only implemented platforms and supported media formats work; adding another website requires code and testing.

Before you start #

Create a Discord application and bot, enable Message Content Intent, and keep the token private. Invite your own bot with the permissions in the permission guide.

Follow the current repository setup instructions for Node.js or Docker. Mount persistent writable storage for server settings.

Configuration #

TRANSLATE_TWEETS makes English tweet translation available. REWRITE_PLATFORMS selects x, instagram, tiktok, youtube, bluesky, reddit, twitch, facebook, articles and erome; it can disable a platform during an outage. Erome requires ffmpeg and ffprobe on PATH, included in the Docker image. EROME_GUILD_IDS=none disables it everywhere; a comma-separated server-ID allowlist restricts it, and omitting the variable retains the self-hosted default. Server settings cannot override the operator limit. It defaults to age-restricted server channels; admins can allow ordinary channels with /settings erome_channels:all. Operator channel and server allowlists support restricted installations. Server admins use /setup to choose channels and /settings to choose Reply or Replace, YouTube display and available features.

Optional hosted delivery of compatible Erome originals up to 24 MiB requires a public HTTPS media endpoint, persistent media storage and authenticated regional workers. It preserves source video and audio, including native 1080p, while keeping smaller sources at their original resolution. JPEG/PNG album images up to 8 MiB use the same storage and publication controls. Attachment preparation remains the fallback for supported videos up to 64 MiB and five minutes. Original-media hosting defaults to disabled in self-hosted installations and is separate from website hosting.

Operators enabling hosted media must keep stored-file cleanup running and preserve message bindings across restarts. Follow the regional hosting guide for deployment settings and verification steps. Disabling this option also takes existing hosted video URLs offline; the files remain in persistent storage. See the Erome data-handling notes before enabling it.

YouTube video counts and comments require an operator-owned YOUTUBE_API_KEY from a Google Cloud project with YouTube Data API v3 enabled. Restrict the key to that API and your bot host's public IP addresses. Keep it on the bot host. Without a key, native video links stay unchanged; public community text/image cards still work. The public repository documents quotas, caching and cleanup.

Keep the data directory writable and persistent. It stores server preferences, a repost ownership journal and a YouTube cleanup queue. These files contain IDs, preferences and cleanup metadata, with character lengths for legacy YouTube messages. They do not contain comment text, counts or Discord message bodies. Cleanup must continue after YouTube processing is disabled so previously posted controls can expire.

Private Details adds a local history capped at seven days, 4,096 attempts and 4 MiB. Hosted reuse has a separate index capped at 1,024 entries and 2 MiB, with seven days since last use; the index contains keyed source digests and media descriptors, not raw source URLs. Neither cache lifetime replaces the hosted file's preview bindings. Back up and restore ownership with media storage. Album loading sessions are intentionally in memory and expire on restart; existing hosted items remain bound to their messages.

Keep the media scheduler and its temporary-storage limits together: it admits one job per server, at most eight pending jobs globally and two per server, and reserves up to 192 MiB of scratch space. Original preparation can overlap attachment encoding across servers. The supported container uses a 256 MiB temporary filesystem; raising concurrency without checking storage and decoder limits is not a supported tuning shortcut. These bounds do not promise a fixed delivery time.

To support personal commands, enable User Install with the applications.commands scope in your application's Installation settings. Guild Install also needs the bot scope and listed permissions. Use your own application ID in invite links; the website's invite adds the hosted Linky.

New installations need an administrator to run /setup enabled: true. Protect the host and token, update the bot after CI passes, and check permissions before testing.

Your instance's data handling depends on your deployment. The hosted Linky privacy policy does not automatically describe a self-hosted copy. Delivery measurements stay on the bot host rather than going to a third-party analytics service. A separate operator archive defaults to 30 days and 64 MiB, with DELIVERY_LOG_RETENTION_DAYS accepting 1–90 days. It excludes message text, captions, source URLs and Discord identities. After building, run npm run report:deliveries -- --days 7 on your host. The report shows data-loss and coverage limitations; it does not prove media played. Operator guide.

Updated