Skip to content

Discord bot written in TypeScript, focused on music playback with a React-based web frontend.

Notifications You must be signed in to change notification settings

ebma/daves-disco

Repository files navigation

Daves Disco

Dave is a Discord bot focused on music playback. The project consists of two different parts: a Node.js backend and a React-based web frontend.

Node.js Node.js

discord.js discord-akairo

Material-UI logo Redux Logo

Frontend application

You can find the source code in the web sub-directory.

Technologies

  • Material-UI is used as component library.
  • Global state is handled by redux.
  • This project uses the redux-toolkit package to simplify the setup process.

Preview

Login Dashboard Collection

Backend application

The node server runs the discord bot and offers a RESTful API for communication.

Technologies

  • The RESTful API is realised with the Express framework.
  • discord-akairo offers easier setup and some convenience methods regarding the discord bot programming.

Communication between frontend & backend application

The applications communicate on two different channels: a Socket.IO connection and http requests.

A websocket is used to notify on updates (e.g. volume changes, queue changes, play/pause state) where only small chunks of data are sent over the network.

For logging in, requesting the player-state, available tracks and playlists or accessing the youtube API http requests are used.

Login flow

  1. Select guild and user in web app
  2. Dave will send you a DM on Discord where you reply with yes
  3. You go back to the web app and can now access all pages for your guild (e.g. music and soundboard area)

During authentication a JWT token is created so that the application is able to communicate with the backend. Afterwards a Socket.io connection authenticated with that token is established (using socketio-jwt)and http requests to the REST API are secured by including the token in the Authorization header.

Deployment with AWS and Cloudflare

EC2

  1. Create a new EC2 instance
  2. Add ports 80 and 443 to the inbound rules of the security group of that instance
  3. Configure a new Elastic IP and assign it to the EC2 instance

Cloudflare

  1. Go to the DNS management of your target domain on Cloudflare
  2. Add a new 'A' record that points to the Elastic IP address of your EC2 instance
  3. Make sure that SSL/TLS encryption mode is set to "Full" in the "SSL/TLS" tab

LetsEncrypt

  1. Install the certbot on your EC2 instance

  2. Create a new WILDCARD certificate (*.example.com) with sudo certbot certonly --manual (because a DNS acme challenge is easier)

  3. Follow the instructions of certbot

  4. Run sudo chown $(whoami) /etc/letsencrypt/live/ -R and sudo chown $(whoami) /etc/letsencrypt/archive/ -R to make the directories accessible for the current user

  5. Add CERT_PATH and KEY_PATH to the .env file

Troubleshooting

Allow non-root node to use ports 80 and 443 with sudo setcap 'cap_net_bind_service=+ep' $(which node)

Beware that wildcard certificates need to be requested for every sublevel domain, i.e. *.example.com and *.abc.example.com would be necessary to protect both domains.

Fix permission error of Certbot certificates with

$ sudo chown $(whoami) /etc/letsencrypt/live/ -R
$ sudo chown $(whoami) /etc/letsencrypt/archive/ -R

If you encounter issues with SSL mismatch when using cloudflare make sure that "SSL/TLS encryption mode" is "full" and not "flexible".