Anten
Türkçe

Developers

Music bot

The ready-made music bot joins the voice room of whoever types /play and plays songs in turn. Its audio is end-to-end encrypted, like the talk in the room.

For
Those who run the server
Time
15 minutes
You need
Anten running with Docker Compose
You get
Encrypted music in voice rooms

The music bot joins the voice room of whoever types /play and plays the song asked for; later requests go into a queue. Its audio is end-to-end encrypted like everyone else’s, so nobody, the server included, can listen in.

What it does

  • Searches YouTube, or plays links from YouTube, SoundCloud, Bandcamp and Twitch (live streams included).
  • Runs the queue: adding, skipping, going back, shuffling, repeating, moving within a song.
  • Shows a now playing panel with buttons for every new song.
  • Optionally, only one group controls it and the others vote to skip a song.

The bot is an ordinary bot account written with the anten-bot library. It runs in its own container beside antend and reaches it over an internal network on the same machine, so its audio never leaves the machine on the way to antend.

Speed

The part that finds and fetches songs (anten-source) stays running. yt-dlp (the tool that finds a video’s audio) is loaded once and keeps its connections open. Searches are remembered. The first 20 seconds or so of the next song are fetched while the current one plays. A song is not downloaded first; it plays as it arrives. Since YouTube’s audio is already Opus, it is passed on without encoding (it is encoded when the volume is changed).

Measured times, from the command reaching the bot to the first sound: moving to the next song about 50 ms; the first song right after the bot starts about 1.5 seconds. The first join of a room adds setting up the voice connection and exchanging the encryption keys. The bot uses the server’s internet connection; the listeners’ connection speed does not affect how fast a song starts.

While playing, the whole bot uses about 110 MB of memory and about 2% of one processor core; idle, about 65 MB and almost no processor time.

Setup

These steps assume Anten running with Docker Compose as in the setup guide. The commands run on the server, in the deploy folder.

  1. Make the bot account. Under Server settings → Integrations → Bots, enter “Music” and press Make a bot, then copy the token shown. It is shown only once; this needs the Manage bots permission.

  2. Put the token in deploy/.env. Keep it in this file only; never in a repository or a chat.

    MUSIC_BOT_TOKEN=anten_bot_...
    
  3. In the same file, add the music bot to the end of the COMPOSE_FILE line. If there is no such line, or it starts with #, write this one. On an internet-facing server with the HTTPS addition:

    COMPOSE_FILE=docker-compose.yml:docker-compose.server.yml:docker-compose.music.yml
    

    If the server has its own reverse proxy, use docker-compose.nginx.yml instead of docker-compose.server.yml. On your own computer, COMPOSE_FILE=docker-compose.yml:docker-compose.music.yml is enough.

  4. Start the bot and follow its logs. The first build takes a few minutes. If the logs show no errors, the bot is connected.

    docker compose up -d --build
    docker compose logs -f music
    
  5. Decide with its groups where the bot may play. The bot joins every server in the default groups. In the rooms it plays in, its View power, Join power and Talk power must meet what the room needs, and it needs Send messages to reply.

  6. If needed, keep the bot out of the AFK move. If your server moves people who stay quiet into the AFK room, give the bot the Never moved to the AFK room permission.

  7. Try it. Join a voice room, then type /play and a song’s name in the message box.

Using it

Commands are typed like ordinary messages. Typing / in the message box lists the commands available in the room and their options. The bot plays in one voice room at a time: the one the person who typed the command is in.

Commands

The table shows the English names. When the bot runs in Turkish (the default, see Language), the names in the last column are used.

Command What it does Turkish
/play <song> Plays the song named or linked; adds it to the end of the queue if something is playing /çal
/search <song> Searches and shows the results in a menu; plays the one you pick /ara
/playnext <song> Adds the song to the front of the queue /sıradaki
/skip Skips to the next song /geç
/back Goes back to the previous song /önceki
/pause, /resume Pauses; carries on where it stopped /dur, /devam
/seek <time> Jumps to a point in the song (1:30 or 90) /sar
/forward [seconds], /rewind [seconds] Moves forward or back (10 seconds by default) /ileri, /geri
/replay Plays the song from the start /başa
/loop <mode> Repeats the song or the queue; off stops repeating /tekrar (şarkı, kuyruk, kapalı)
/shuffle Shuffles the queue /karıştır
/queue, /now, /history Shows the queue, the song playing, what played last /kuyruk, /şimdi, /geçmiş
/remove <position> Takes a song out of the queue /çıkar
/move <position> <to> Moves a song to another place in the queue /taşı
/clear Empties the queue /temizle
/autoplay <on/off> When the queue ends, plays songs like the last one (from YouTube’s mix) /otomatik (açık, kapalı)
/lyrics [song] Shows the lyrics of the song playing, or of the one given /söz
/volume <level> Sets the volume in percent (0–200) /ses
/stop Ends the music and leaves the room /bitir

Only people in the same voice room as the bot can use the commands that change what plays.

The now playing panel

For every new song the bot posts a message with the song’s title, length, who asked for it and how many songs are queued; the previous panel is removed. Its buttons: previous, pause/resume, next, stop, queue, Repeat, Shuffle and Lyrics. The buttons follow the same rules as the commands; only the person who pressed sees the reply. The bot also shows the song next to its name as Listening to.

/search shows the first five results in a menu, with channel and length. Only the person who searched can pick from it; Cancel closes it. The results can be picked for 10 minutes.

Sources

  • Any text that is not a link is a YouTube search.
  • Links from YouTube, SoundCloud, Bandcamp and Twitch play directly. Links to other sites are refused.
  • From Spotify and Apple Music, only single song links work: the bot reads the song’s title and artist from the page and searches YouTube. Those sites do not provide the audio; playlist and album links are not supported.
  • Lyrics come from lrclib.net. The service needs no key; only the song’s title is sent there.

Settings

The bot’s settings go in deploy/.env. After a change, restart the bot with docker compose up -d. Every variable is listed in Settings reference.

Language

Commands and replies follow the installation’s language (ANTEN_LANGUAGE), or Turkish if that is not set. Choose the bot’s language on its own with MUSIC_LANG=tr or MUSIC_LANG=en.

When it leaves

The bot leaves by itself 2 minutes after nobody is left listening, and 5 minutes after nothing is left to play. MUSIC_ALONE_MINUTES and MUSIC_IDLE_MINUTES change these times; with 0 the bot never leaves.

DJ group

If MUSIC_DJ_GROUP is the name of a server group, only its members can use the commands that change what plays. Asking for songs (/play, /search) stays open to everyone.

  • Others vote when they type /skip. The song is skipped once more than half of the room asks.
  • Whoever asked for a song can always skip it.
  • Someone alone in the room with the bot can use every command.

When it is not set, everyone can use every command.

Panel, lyrics and logs

MUSIC_PANEL=0 turns the now playing panel off. MUSIC_LYRICS=0 removes lyrics and the /lyrics command. MUSIC_DEBUG=1 writes to the logs how many milliseconds each command took to start the music.

If YouTube blocks the server

YouTube often takes servers in data centres for bots and will not give the song. The bot then says so in the chat, and the logs (docker compose logs music) show Sign in to confirm you're not a bot. The same bot may work on a home connection; the problem is the server’s address, not the code.

There are three ways around it. Try them in order and add the next one if needed; they also work together. When it starts, the bot writes which ones are set up in a log line beginning with against the bot check:.

1. A PO token provider

It needs no account; try this first. A helper that produces YouTube’s “not a bot” token (PO token) runs beside the bot in a container of its own. It holds no keys, and only the bot reaches it. It uses about 100–200 MB of memory. It is enough on most servers, but there is no guarantee.

  1. Add the helper to the end of the COMPOSE_FILE line.

    COMPOSE_FILE=...:docker-compose.music.yml:docker-compose.music-pot.yml
    
  2. Restart the bot.

    docker compose up -d --build
    

2. A cookies file

This is the surest way: the bot connects to YouTube as if signed in with a Google account.

  1. On your computer, open a private browser window and sign in to YouTube with the spare account.

  2. In the same tab, open https://www.youtube.com/robots.txt and export the cookies in the Netscape cookies.txt format. A browser extension can do this; choose one whose source code is open.

  3. Close the private window right away. If it stays open, YouTube renews the cookies and those in the file stop working.

  4. Save the file on the server as deploy/youtube-cookies.txt and make it readable by the bot only.

    sudo chown 1000:1000 youtube-cookies.txt && sudo chmod 600 youtube-cookies.txt
    
  5. Add :docker-compose.music-cookies.yml to the end of the COMPOSE_FILE line and restart the bot.

    docker compose up -d --build
    

If the file is elsewhere, put MUSIC_COOKIES_FILE=/path/file.txt in .env. The bot only reads the file and keeps its own copy in /tmp; it never writes to the file itself. Cookies expire over time: if the bot says it is blocked again, repeat the steps.

3. A proxy

The bot reaches YouTube from another address instead of the server’s; for example a home connection or a proxy service. Put its address in deploy/.env:

MUSIC_PROXY=http://user:password@proxy.example.org:3128

Only http:// proxies are supported, because ffmpeg fetches live streams itself and cannot use SOCKS. https sites still pass through the proxy encrypted. Songs, searches and live streams all go through this address. The encryption of the audio in the room is not affected: the proxy sees only the conversation with YouTube.

Age-restricted videos

YouTube serves some videos only to signed-in adult accounts; the logs show Sign in to confirm your age. This is not a bot block but specific to that video. If the first result of a search is such a video, the bot tries the next results and plays an unrestricted upload of the same song, leaving altered versions to the end. If none works, or a link to such a video was given directly, the bot says so. Playing such a video needs a cookies file (option 2).

Privacy and security

Audio and connections

  • The bot’s audio is end-to-end encrypted. Without a key it sends no sound at all; unencrypted audio never leaves the bot.
  • The bot connects to YouTube and the allowed sites from your server; those sites see the server’s address. Anten itself connects to no outside address; you choose these connections by installing the music bot.
  • For lyrics, only the song’s title is sent to lrclib.net. If you do not want this, set MUSIC_LYRICS=0.

Where typed text goes

  • Typed text never reaches a shell or a program option. It becomes either a YouTube search or a link to an allowed site. This way nobody can make the bot send requests to addresses in the server’s own network.
  • YouTube requires the JavaScript on its page to run. That code runs in Deno, with no access to files, the network or environment variables. It never runs in the Node process, which could reach the bot’s keys.

What anten-source can do

  • anten-source receives only searches and links the bot has already checked; it never runs what it is given.
  • It never gets the bot’s token: the bot removes it from the environment before starting it.
  • It serves audio only inside the machine (127.0.0.1), under a random secret address; it cannot be reached from outside.
  • It is the part that uses the cookies file and the proxy address, which is why the cookies file must stay readable by the bot only.

The container

The container is read-only, has no extra privileges (cap_drop: ALL, no-new-privileges) and runs as a non-root user. It writes only to its key volume and to /tmp. The versions of yt-dlp and Deno are pinned.

Copyright in what is played and the sites’ terms of use are the responsibility of whoever runs the server.

Maintenance

If YouTube stops working

YouTube changes from time to time, and yt-dlp then needs an update. Raise the YTDLP version (and YTDLP_EJS if needed) in bots/music/Dockerfile to yt-dlp’s latest release and rebuild the bot:

docker compose up -d --build music

Your own voice bot

The music bot is written with the voice support of the anten-bot library (bots/music/src/main.js). VoiceHelper starts the voice helper (bots/voice), bot.joinVoice(guild, room, helper) joins the room, and the encryption keys are agreed by themselves the way browsers do it. helper.play(...) plays a file, a stream address or a downloader’s output. The details are in the voice rooms section of the bots guide.

Settings reference

Variable Default Meaning
MUSIC_BOT_TOKEN The bot’s token (required)
MUSIC_LANG ANTEN_LANGUAGE, else tr Language of commands and replies: tr or en
MUSIC_SITES youtube.com,youtu.be,music.youtube.com,soundcloud.com,bandcamp.com,twitch.tv The sites links may point to (subdomains included)
MUSIC_MAX_MINUTES 180 The longest song, in minutes
MUSIC_QUEUE 100 The most songs in the queue
MUSIC_VOLUME 100 Starting volume, in percent (0–200)
MUSIC_IDLE_MINUTES 5 Minutes until it leaves once nothing is left to play; 0: never
MUSIC_ALONE_MINUTES 2 Minutes until it leaves once nobody is listening; 0: never
MUSIC_DJ_GROUP Only this server group changes what plays; others skip by vote
MUSIC_PANEL 1 0: no now playing panel
MUSIC_LYRICS 1 0: no lyrics and no /lyrics
MUSIC_DEBUG 1: the time from command to music in the logs
MUSIC_PROXY An http:// proxy to use if YouTube blocks the server
MUSIC_COOKIES_FILE ./youtube-cookies.txt Where the cookies file is (with docker-compose.music-cookies.yml)