npm install
for development
npm run dev
for production
npm run start
Set COMMAND_PREFIX in your environment if you do not want the default ! prefix.
Available commands:
!play <youtube url or search>!skip!stop!pause!resume!volume <0-200>!queue!nowplaying!commands!version
The bot joins the caller's voice channel, queues tracks per guild, and leaves automatically when the queue ends.
!version shows app version and, when available, deploy metadata (RELEASE_VERSION and GIT_SHA).
By default the per-guild volume set with !volume lives in memory only and resets when the
process restarts. On Fly the Machine is destroyed when scaled to zero (overnight) and rebuilt
on deploy, so in-memory state is lost on both — and a Fly volume would add storage cost.
To persist volume for free, point the bot at a free-tier Upstash Redis (serverless, accessed over HTTPS — no extra npm dependency). Set both REST credentials:
UPSTASH_REDIS_REST_URL=...
UPSTASH_REDIS_REST_TOKEN=...
On Fly, set them as secrets on each app:
flyctl secrets set UPSTASH_REDIS_REST_URL=... UPSTASH_REDIS_REST_TOKEN=... -a manibot
flyctl secrets set UPSTASH_REDIS_REST_URL=... UPSTASH_REDIS_REST_TOKEN=... -a manibot-dev
Keep dev and prod state separate. If manibot and manibot-dev share a Discord server
(same guild IDs) and the same Redis, they will overwrite each other's volume. Either give each
app its own Upstash database, or point them at different hash keys with MANIBOT_VOLUME_KEY
(e.g. manibot:volumes for prod, manibot-dev:volumes for dev).
When the variables are unset the bot keeps its previous in-memory behaviour, and any Redis
outage is logged and ignored — it never blocks the !volume command or startup.
CircleCI deploys main to Fly and sets runtime secrets used by !version.
Required CircleCI project env var:
FLY_API_TOKEN
You can run a separate development bot on Fly using fly.dev.toml.
Create the dev app once:
flyctl apps create manibot-dev
Set secrets for the dev app (use a separate Discord bot token):
flyctl secrets set BOT_TOKEN=... -a manibot-dev
flyctl secrets set COMMAND_PREFIX=! -a manibot-dev
Deploy dev:
npm run deploy:fly:dev
View dev logs:
npm run logs:fly:dev
GitHub Actions stop your production Machines overnight and start them again in the morning so you mostly avoid CPU/RAM charges while offline.
Current defaults (Turkey TRT, UTC+3, no DST):
- Stop: 01:00 Turkey →
0 22 * * *UTC (fly-schedule-stop.yml) - Start: 08:00 Turkey →
0 5 * * *UTC (fly-schedule-start.yml)
Edit those cron lines if you change hours (always convert local → UTC for the workflow).
Setup
-
In the GitHub repo: Settings → Secrets and variables → Actions → New repository secret
- Name:
FLY_API_TOKEN - Value: a Fly token with permission to manage the app (same idea as CircleCI deploy).
- Name:
-
Optionally adjust start time in
fly-schedule-start.yml(default wake 08:00 Turkey). -
Actions tab → run Fly — stop manibot / Fly — start manibot manually once to verify.
Notes
- Stopped Machines can still incur a small rootfs charge; running 24/7 is what costs most.
- A deploy from CircleCI may start or replace Machines depending on Fly behavior; after a deploy, check the schedule still matches what you want.
- For
manibot-dev, duplicate these workflows and changeFLY_APP(or we can add a matrix later).
If YouTube blocks playback on hosted IPs, set YTDLP_COOKIES as a secret.
- Use exported
youtube.comcookies in Netscapecookies.txtformat - Do not use a raw HTTP
Cookie:header string - Prefer a fresh export from an incognito/private YouTube session per yt-dlp wiki guidance