Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
9c34447
Add configuration for asdf
zastrixarundell Jan 10, 2024
74dce9c
Rewrite play file
zastrixarundell Jan 10, 2024
71a296b
Update dependencies to newest versions
zastrixarundell Jan 10, 2024
e355282
Remove porcelain
zastrixarundell Jan 10, 2024
1d93c75
Update children
zastrixarundell Jan 10, 2024
8f6e12e
Remove inspect code
zastrixarundell Jan 10, 2024
fd3c939
Rewrite SoundCloud client_id token acquisition
zastrixarundell Jan 10, 2024
753381f
Add start for interactions
zastrixarundell Jan 10, 2024
53d9f28
Put old value back
zastrixarundell Jan 10, 2024
6d6ad7c
Disappearing help command
zastrixarundell Jan 10, 2024
9befcf5
Working forward and backward commands
zastrixarundell Jan 10, 2024
0182e52
Change nostrum version to git
zastrixarundell Jan 10, 2024
1dc9f38
Barely functioning play command
zastrixarundell Jan 10, 2024
5df066b
Optimizations and syntax fixes
zastrixarundell Jan 11, 2024
60027b1
Better error handling
zastrixarundell Jan 11, 2024
b61cad5
Add OCI support
zastrixarundell Jan 11, 2024
80071d4
Remove accidental comments
zastrixarundell Jan 11, 2024
8abf2cf
Update the docker-compose.yml file
zastrixarundell Jan 11, 2024
6922631
Add name for container
zastrixarundell Jan 11, 2024
e8219da
Fix specs
zastrixarundell Jan 11, 2024
c2e23c6
Fully remove permission checks
zastrixarundell Jan 11, 2024
96318b1
Fix warning on sound_cloud_token.ex
zastrixarundell Jan 11, 2024
7caa59b
Handle voice state of the bot correctly
zastrixarundell Jan 12, 2024
f64cdd9
Better logging and error handling
zastrixarundell Jan 12, 2024
4ca448f
Fixed play_manager and voice specs/namings
zastrixarundell Jan 12, 2024
98086cb
Using import Config
zastrixarundell Jan 12, 2024
d0e2f15
More specific builder/runtime for Dockerfile
zastrixarundell Jan 12, 2024
fa9ef04
Rely of youtube-dl
zastrixarundell Jan 12, 2024
d6a1d6d
Remove unused dependencies
zastrixarundell Jan 12, 2024
c688230
Minimize help function
zastrixarundell Jan 12, 2024
c65219c
Allow longer durations of messages
zastrixarundell Jan 15, 2024
0d72380
So-so working playlist controls
zastrixarundell Jan 15, 2024
c4d9db6
Add restart=always policy
zastrixarundell Jan 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,6 @@ cassian-*.tar
/.elixir_ls

# For certificates
/priv
/priv

.asdf-vars
2 changes: 2 additions & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
elixir 1.16.0
erlang 26.2.1
78 changes: 78 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Stage to build the correct version of dependecies:

# * Elixir
# * Erlang

FROM alpine:3.19.0 AS builder

RUN apk update && \
apk upgrade && \
apk add curl git unzip \
gcc autoconf automake ncurses-dev \
bash make g++ openssl-dev

RUN adduser -gD builder --disabled-password

# Building Erlang/Elixir

WORKDIR /build

COPY .tool-versions .

RUN chown -R builder:builder /build

USER builder

RUN git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.13.1;

RUN /bin/bash -c 'echo -e "\n\n## Configure ASDF \n. $HOME/.asdf/asdf.sh" >> ~/.bashrc'

RUN /bin/bash -c 'echo -e "\n\n## ASDF Bash Completion: \n. $HOME/.asdf/completions/asdf.bash" >> ~/.bashrc';

ENV PATH="$PATH:/home/builder/.asdf/bin:/home/builder/.asdf/shims"

RUN asdf plugin add elixir

RUN asdf plugin add erlang

RUN asdf install

# Building the application

RUN mix local.hex --force

COPY mix.exs .

COPY mix.lock .

COPY config ./config

COPY lib ./lib

COPY .formatter.exs .

RUN mix deps.get

RUN mix deps.compile

RUN mix release

# Actual app stage

FROM alpine:3.19.0 AS runtime

RUN adduser -D runner --disabled-password

RUN apk update

RUN apk upgrade

RUN apk add ffmpeg youtube-dl

USER runner

WORKDIR /app

COPY --from=builder /build/_build/dev/rel/cassian /app/cassian

CMD ["/app/cassian/bin/cassian", "start"]
21 changes: 7 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ A Discord bot for music written in Elixir.
## Table of contents

- [About](#about)
- [Note regarding Nostrum](#note-regarding-nostrum)
- [Note regarding the web part](#note-regarding-the-web-part)
- [System requirements](#system-requirements)
- [Configuration](#configuration)
Expand All @@ -23,10 +22,6 @@ The bot is written in Elixir, a functional programming language based upon Erlan

The Discord library is [Nostrum](https://github.com/Kraigie/nostrum), written in Elixir and supporting everything from events to voice channels.

## Note regarding Nostrum

As of now the Hex release of Nostrum `v0.4.6` is a bit buggy so the current version of this bot uses the nightly version of Nostrum.

## Note regarding the web part

This is deprecated. It will be removed once a web app has been created because I don't want to add web functionality to the bot.
Expand All @@ -39,18 +34,20 @@ This bot needs `youtube-dl` and `ffmpeg` in order to play music. The path of the

### General bot requirements

Of course as this is written in Elixir, you will need Elixir installed. This can be easily done on Debian-based distros:
Of course as this is written in Elixir, you will need Elixir installed. This can be easily done with [asdf](https://asdf-vm.com/). After following the asdf [instructions](https://asdf-vm.com/guide/getting-started.html) one can start adding the required plugins for the runtimes:

```bash
sudo apt-get install elixir
asdf plugin add elixir
asdf plugin add erlang
asdf install
```

After installing Elixir you should be able to see the version:
After that you should be able to run `elixir -v`

```bash
Erlang/OTP 23 [erts-11.1.7] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]
Erlang/OTP 26 [erts-14.2.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit:ns]

Elixir 1.11.2 (compiled with Erlang/OTP 23)
Elixir 1.16.0 (compiled with Erlang/OTP 24)
```

Try to keep the Elixir version `1.11.2` and up.
Expand All @@ -62,10 +59,6 @@ To set the bot up-and-running you will need to set a couple of variables.
Here's the basic configuration:

```elixir
use Mix.Config
config :porcelain,
driver: Porcelain.Driver.Basic

config :nostrum,
ffmpeg: System.get_env("FFMPEG_PATH") || "/usr/bin/ffmpeg",
youtubedl: System.get_env("YTDL_PATH") || "/usr/bin/youtube-dl",
Expand Down
7 changes: 1 addition & 6 deletions config/config.exs
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
use Mix.Config

config :porcelain,
driver: Porcelain.Driver.Basic
import Config

config :nostrum,
ffmpeg: System.get_env("FFMPEG_PATH") || "/usr/bin/ffmpeg",
youtubedl: System.get_env("YTDL_PATH") || "/usr/bin/youtube-dl",
token: System.get_env("DISCORD_BOT_TOKEN"),
num_shards: :auto

Expand Down
10 changes: 10 additions & 0 deletions config/runtime.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import Config

config :nostrum,
token: System.fetch_env!("DISCORD_BOT_TOKEN"),
num_shards: :auto

config :cassian,
web_enabled: System.fetch_env!("WEB_ENABLED"),
port: "4000",
force_ssl: System.fetch_env!("FORCE_SSL")
14 changes: 14 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
version: '3.0'

services:
bot:
build:
context: .
dockerfile: Dockerfile
name: cassian-bot
restart: always
environment:
DISCORD_BOT_TOKEN: $DISCORD_BOT_TOKEN
WEB_ENABLED: false
FORCE_SSL: false

14 changes: 0 additions & 14 deletions lib/cassian.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,13 @@ defmodule Cassian do

alias Nostrum.Cache.Me

@default_command_prefix Application.get_env(:cassian, :prefix)

@doc """
Get the avatar of the bot itself.
"""
@spec get_own_avatar() :: String.t()
def get_own_avatar,
do: Cassian.Utils.user_avatar(Me.get())

@doc """
Get the command prefix of the bot from a server. if no server
is specific then the default prefix is taken.

Currently this works only with the preset one as database has not yet
been added.
"""
@spec command_prefix!(server_id :: Nostrum.Struct.Guild.id() | nil) :: binary
def command_prefix!(_server_id \\ nil) do
@default_command_prefix
end

@doc """
Get the user name of bot account.
"""
Expand Down
8 changes: 1 addition & 7 deletions lib/cassian/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,9 @@ defmodule Cassian.Application do

@doc false
def add_children() do
alias Cassian.Consumer

children =
[
%{
id: Consumer,
start: {Consumer, :start_link, []}
},
Cassian.Servers.SoundCloudToken
Cassian.Consumer,
] ++ web_child!()

children
Expand Down
10 changes: 8 additions & 2 deletions lib/cassian/behaviours/command.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,18 @@ defmodule Cassian.Behaviours.Command do
@doc """
The function which is called that does all of the stuff needed in the command.
"""
@callback execute(message :: Nostrum.Struct.Message.t(), args :: List.t()) :: :ok
@callback execute(interaction :: Nostrum.Struct.Interaction.t()) :: map()

@doc """
The definition as a Discord application command.
"""
@callback application_command_definition() :: map()

defmacro __using__(_) do
quote do
defmacro handle_command(message, args), do: execute(message, args)
@behaviour Cassian.Behaviours.Command
import Bitwise
alias Cassian.Utils.Embed, as: EmbedUtils
end
end
end
17 changes: 17 additions & 0 deletions lib/cassian/behaviours/source_service.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
defmodule Cassian.Behaviours.SourceService do
@moduledoc """
The general service for a source of audio.
"""

@doc """
Try to get metadata for a specific song if it's supported.
"""
@callback song_metadata(url :: String.t()) :: {:ok, %Cassian.Structs.Metadata{}} | {:error, :not_found}

defmacro __using__(_) do
quote do
@behaviour Cassian.Behaviours.SourceService
alias Cassian.Structs.Metadata
end
end
end
23 changes: 11 additions & 12 deletions lib/cassian/commands/bot/help.ex
Original file line number Diff line number Diff line change
@@ -1,31 +1,30 @@
defmodule Cassian.Commands.Bot.Help do
use Cassian.Behaviours.Command

alias Cassian.Managers.MessageManager

@moduledoc """
The help command. Shows a menu of commands.
"""

def application_command_definition() do
%{
name: "help",
description: "Get the list of all commands from Cassian"
}
end

@doc false
def execute(message, _args) do
generate_help_embed!()
|> MessageManager.send_embed(message.channel_id)

:ok
def execute(_interaction) do
%{type: 4, data: %{embeds: [generate_help_embed!()], flags: 1 <<< 6}}
end

import Cassian.Utils.Embed
alias Nostrum.Struct.Embed

def generate_help_embed!() do
defp generate_help_embed!() do
create_empty_embed!()
|> Embed.put_title("Yo! Thanks for adding me to the server!")
|> Embed.put_description(
"I currently don't have a propper help command as I'm a WIP. Though once it has been created it will be linked here so " <>
"you can see all of my commands. Although you can start playing music with `#{
Cassian.command_prefix!()
}play`."
"you can see all of my commands. Although you can start playing music with `/play`."
)
|> Embed.put_thumbnail(Cassian.get_own_avatar())
end
Expand Down
38 changes: 0 additions & 38 deletions lib/cassian/commands/bot/ping.ex

This file was deleted.

13 changes: 11 additions & 2 deletions lib/cassian/commands/playback/backward.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,17 @@ defmodule Cassian.Commands.Playback.Backward do
@doc """
Play the playlist backwards.
"""

def application_command_definition() do
%{
name: "backward",
description: "Play the playlist backwards."
}
end

def execute(message, _args) do
PlayManager.change_direction_with_notification(message, true)
def execute(interaction) do
{embed, flags} = PlayManager.change_direction_with_notification(interaction, true)

%{type: 4, data: %{embeds: [embed], flags: flags}}
end
end
13 changes: 11 additions & 2 deletions lib/cassian/commands/playback/forward.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,17 @@ defmodule Cassian.Commands.Playback.Forward do
@doc """
Play the playlist forward.
"""

def application_command_definition() do
%{
name: "forward",
description: "Play the playlist forward."
}
end

def execute(message, _args) do
PlayManager.change_direction_with_notification(message, false)
def execute(interaction) do
{embed, flags} = PlayManager.change_direction_with_notification(interaction, false)

%{type: 4, data: %{embeds: [embed], flags: flags}}
end
end
Loading