# @inner-dj/server

<img src="https://codeberg.org/sanin/inner-dj/raw/branch/master/packages/server/assets/images/svg/logo.svg" width="128" height="128" alt="inner-dj logo"/>

[![NPM](https://nodei.co/npm/@inner-dj/server.svg?data=n,v,u,d,s)](https://www.npmjs.com/package/@inner-dj/server)

This is the web server component for [inner-dj](https://codeberg.org/sanin/inner-dj).

## Requirements

- yt-dlp

## Deployment

The inner-dj server is available via [npm](https://www.npmjs.com/package/@inner-dj/server) and Docker ([Docker Hub](https://hub.docker.com/r/corysanin/inner-dj) and [Codeberg](https://codeberg.org/sanin/-/packages/container/inner-dj/latest)).

### Docker

```
docker run -v "${PWD}/config:/usr/src/app/config/:ro" codeberg.org/sanin/inner-dj
```

### npm

```
npx @inner-dj/server
```

### pnpm

```
pnpm dlx --allow-build=better-sqlite3 --allow-build=bufferutil --allow-build=utf-8-validate @inner-dj/server
```

## Configuration

By default, inner-dj server will attempt to load a configuration file at `config/config.yaml` (relative to the current working directory).
To use a custom config path, set environment variable `CONFIG`.

### Config Root

| YAML key      | Environment Var | Type                                            | Description                                                                                                                                                                      | Default          |
|---------------|-----------------|-------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------|
| port          | PORT            | number                                          | Port to run the web server on                                                                                                                                                    | 8080             |
| trustProxy    | TRUSTPROXY      | boolean\|number\|string                         | Whether or not the server is behind a proxy and to trust proxy headers. See [express behind proxies](https://expressjs.com/en/guide/behind-proxies/)                             | false            |
| secure        | SECURE          | boolean                                         | Whether or not to set the Set-Cookie header to Secure, requiring https traffic for cookies                                                                                       | true             |
| public        | PUBLIC          | boolean                                         | False requires a TOTP code to request songs. Navigate to `/?override=1` to log in as admin.                                                                                      | false            |
| sessionSecret | SESSIONSECRET   | string                                          | The session secret. Do not share.                                                                                                                                                | REQUIRED         |
| userOtp       | USEROTP         | string                                          | TOTP token for user access. Unused if server is public. If blank, one is generated at start up. Check logs.                                                                      | RANDOM           |
| adminOtp      | ADMINOTP        | string                                          | TOTP token for admin access. If blank, one is generated at start up. Check logs.                                                                                                 | RANDOM           |
| cookieTTL     | COOKIETTL       | number                                          | Cookie max age in ms                                                                                                                                                             | 2592000000 (30d) |
| jwtSecret     | JWTSECRET       | string                                          | Secret for communications between client and server. Only share with client.                                                                                                     | REQUIRED         |
| limiter       | -               | [LimiterOptions](https://github.com/express-rate-limit/express-rate-limit#configuration) | Rate limiter settings for authentication endpoint | see [setDefaultLimits()](https://codeberg.org/sanin/inner-dj/src/branch/master/packages/server/src/config.ts) |
| cookies       | COOKIES         | string                                          | Optional path to Netscape-formatted file to read cookies from. See [how do I pass cookies to yt-dlp?](https://github.com/yt-dlp/yt-dlp/wiki/FAQ#how-do-i-pass-cookies-to-yt-dlp) | null             |
| db            |                 | [DBConfig](#dbconfig)                           |                                                                                                                                                                                  |                  |
| discord       |                 | [DiscordReceiverConfig](#discordreceiverconfig) |                                                                                                                                                                                  |                  |
| twilio        |                 | [TwilioReceiverConfig](#twilioreceiverconfig)   |                                                                                                                                                                                  |                  |

### DBConfig

| YAML key | Environment Var | Type   | Description                        | Default                         |
|----------|-----------------|--------|------------------------------------|---------------------------------|
| path     | DBPATH          | string | Path to SQLite DB for session data | sessions.db next to config file |

### DiscordReceiverConfig

| YAML key | Environment Var | Type            | Description                                                                                                     | Default  |
|----------|-----------------|-----------------|-----------------------------------------------------------------------------------------------------------------|----------|
| enabled  | DISCORDENABLED  | boolean         | Whether or not to use Discord for receiving song requests.                                                      | false    |
| token    | DISCORDTOKEN    | string          | Discord bot token. Required if Discord integration is enabled.                                                  | REQUIRED |
| route    | DISCORDROUTE    | string          | If set, creates a redirect to the Discord application's authentication URL                                      | null     |
| activity |                 | ActivityOptions | See [interface ActivityOptions](https://discord.js.org/docs/packages/discord.js/main/ActivityOptions:Interface) | null     |

### TwilioReceiverConfig

| YAML key      | Environment Var     | Type    | Description                                                                                      | Default         |
|---------------|---------------------|---------|--------------------------------------------------------------------------------------------------|-----------------|
| enabled       | TWILIOENABLED       | boolean | Whether or not to use Twilio for receiving song requests via SMS.                                | false           |
| authToken     | TWILIOAUTHTOKEN     | string  | Twilio auth token. Required if Twilio integration is enabled.                                    | REQUIRED        |
| route         | TWILIOROUTE         | string  | Webhook endpoint route                                                                           | /webhook/twilio |
| url           | TWILIOURL           | string  | Full URL to webhook endpoint. By default, inner-dj will guess this based on the request headers. |                 |
| response      | TWILIORESPONSE      | string  | SMS response to send in reply to received requests. Empty string results in no reply.            | EMPTY STRING    |
| errorResponse | TWILIOERRORRESPONSE | string  | SMS response to send if something went wrong . Empty string results in no reply.                 | EMPTY STRING    |
| phone         | TWILIOPHONE         | string  | Human-readable phone number to display in the user instructions.                                 | REQUIRED        |

## Usage

Important pages:

- `/landing`: The page for users to request songs
- `/admin`: Kiosk-like page with instructions for guests
- `/admin/controls`: Admin control panel for skipping the current song

Load the `/admin` page on a device or screen that guests can see. The page has instructions that guests can follow. Skip tracks with `/admin/controls` when necessary.

Make sure the device displaying `/admin` has its system time set correctly. Otherwise the QR codes it generates will not work.

## Screenshot

![Screenshot of the inner-dj server interface](../../.github/assets/server-screenshot.png "Server interface")
