# mendia

WebSocket server for tracking a shared movie collection across a friend group. When a user adds new movies, everyone gets notified via Telegram and/or WhatsApp.

Part of the [mendia ecosystem](#ecosystem).

## Features

- WebSocket API for clients to log in, fetch movies, and push new entries
- Optional Telegram and/or WhatsApp notifications when new movies are added
- TMDb API key distribution to authenticated clients
- Web frontend via the [mendia npm package](https://www.npmjs.com/package/mendia)
- SQLite database (MySQL supported but deprecated)

## Installation

Download the latest binaries from the [GitLab releases page](https://gitlab.com/derfreak/mendia/-/releases), or install from crates.io:

```console
cargo install mendia
```

This installs two binaries: `mendia` (the server daemon) and `mendia-admin` (administrative CLI).

## Configuration

Both binaries take a `--config <file>` argument pointing to a YAML file.

```yaml
database:
  sqlite: /var/lib/mendia/mendia.db

websocket:
  host: '0.0.0.0'
  port: 8081

# Optional — omit to disable Telegram notifications entirely.
telegram:
  token: 'YOUR_BOT_TOKEN'
  chatid: 'YOUR_CHAT_ID'

# Optional — omit to disable WhatsApp notifications entirely.
# See "WhatsApp setup" below for first-run pairing instructions.
whatsapp:
  db_path: /var/lib/mendia/whatsapp.db
  jid: '15551234567@s.whatsapp.net' # or a group JID ending in @g.us

tmdb:
  api_key: 'YOUR_TMDB_API_KEY'
  language: 'en'

# Optional — controls which languages are highlighted in notification messages.
# Uses ISO 639-1 two-letter codes. If omitted or empty, all detected languages are listed.
notifications:
  main_languages:
    - de
    - en
```

> `mendia-admin` only reads the `database` key; the other sections are ignored.

## Setting up Telegram notifications

1. Open [@BotFather](https://t.me/BotFather) and create a new bot (`/newbot`). Copy the token.
2. Find your chat or channel ID (e.g. via [@userinfobot](https://t.me/userinfobot) or by adding the bot to a channel and checking the Telegram API). For channels, the ID must be prefixed with `-100`.
3. Set `telegram.token` and `telegram.chatid` in `config.yml`.

## Setting up WhatsApp notifications

WhatsApp requires a one-time pairing step using the WhatsApp app on your phone.

1. Add the `whatsapp` section to `config.yml` with `db_path` (where the session is persisted) and `jid` (the recipient — a phone number contact or a group).
2. Start the server. On first run it will print a QR code to the log at `INFO` level:
   ```
   INFO  mendia > WhatsApp QR code (scan with your phone):
   ██████████████ ...
   ```
3. Open WhatsApp on your phone → **Linked Devices** → **Link a Device** and scan the QR code.
4. The server logs `WhatsApp connected.` and the session is saved to `db_path`. Subsequent restarts reconnect automatically without another QR scan.

**JID format:**

- Individual contact: `15551234567@s.whatsapp.net` (E.164 number without `+`)
- Group: `1234567890-1234567890@g.us` (copy from the group's invite link or use a WhatsApp tool to look it up)

## Usage

### Start the server

```console
mendia --config config.yml
```

The server runs pending database migrations on startup, then listens for WebSocket connections.

### Create or update a user

```console
mendia-admin --config config.yml --create-user alice
```

Prompts for a password (min. 8 characters) and stores it as an Argon2 hash.

### Migrate from MySQL to SQLite

```console
mendia --config mysql-config.yml --migrate-to-sqlite /var/lib/mendia/mendia.db
```

Copies all movies and users from the configured MySQL database into a new SQLite file, then prints the updated config snippet. Update your config and restart.

## WebSocket API

All messages are JSON with a `"type"` discriminator field. See [mendia-api](https://crates.io/crates/mendia-api) for the full type definitions.

**Authentication flow:**

```
Client → { "type": "LoginCredentials", "username": "alice", "password": "secret" }
Server → { "type": "Session", "username": "alice", "api_key": "..." }
     or → { "type": "LoginFailed", "reason": "..." }
```

**Commands (after login):**

| Client sends                     | Server replies        |
| -------------------------------- | --------------------- |
| `GetMovies`                      | `Movies`              |
| `PushMovies` (with `api_key`)    | `PushMoviesResult`    |
| `GetTMDbApiKey` (with `api_key`) | `GetTMDbApiKeyResult` |

## Ecosystem

| Crate                                                     | Description                                                         |
| --------------------------------------------------------- | ------------------------------------------------------------------- |
| **mendia**                                                | This package — the WebSocket server                                 |
| [mendia-api](https://crates.io/crates/mendia-api)         | Shared WebSocket protocol types                                     |
| [mendia-scraper](https://crates.io/crates/mendia-scraper) | CLI client that scans local media files and publishes to the server |
| [mendia (npm)](https://www.npmjs.com/package/mendia)      | Web frontend                                                        |
