Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
52 changes: 34 additions & 18 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -------------------------------------------------------------------------
# Cyori Bot - .env Configuration Template
# CytechMusic - .env Configuration Template
# -------------------------------------------------------------------------

# [Bot Credentials]
Expand All @@ -9,8 +9,8 @@ OWNER_IDS=your_discord_user_id,another_owner_id
DEFAULT_PREFIX=cm!

# [Database]
MONGO_URI=mongodb+srv://user:pass@cluster.mongodb.net/?retryWrites=true&w=majority
DB_NAME=Cyori
MONGO_URI=mongodb://localhost:27017
DB_NAME=CytechMusic

# [Lavalink Connection]
LAVALINK_HOST=localhost
Expand All @@ -19,32 +19,48 @@ LAVALINK_PASS=youshallnotpass
LAVALINK_ID=MainNode

# [Spotify API]
SPOTIFY_CLIENT_ID=optional_spotify_id
SPOTIFY_CLIENT_SECRET=optional_spotify_secret
SPOTIFY_CLIENT_ID=
SPOTIFY_CLIENT_SECRET=

# [Lyrics API]
GENIUS_TOKEN=optional_lyrics_genius_token
GENIUS_TOKEN=

# [Stripe Payment (Premium)]
STRIPE_API_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
STRIPE_SUCCESS_URL=https://yourdomain.com/success
STRIPE_CANCEL_URL=https://yourdomain.com/premium
# [Optional Top.gg]
DBL_TOKEN=

# [Optional Stripe / Dashboard]
STRIPE_API_KEY=
STRIPE_WEBHOOK_SECRET=
STRIPE_PROXY_URL=
STRIPE_SUCCESS_URL=http://localhost:3000/success
STRIPE_CANCEL_URL=http://localhost:3000/premium
Comment on lines +35 to +36

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Point Stripe redirects at served routes

When Stripe is enabled with the copied template, successful and cancelled checkouts redirect to /success and /premium, but DashboardSystem.setup_routes only defines extensionless routes for /dashboard and /invite; the corresponding payment files are exposed by the static router as /success.html and /premium.html. Both configured checkout destinations therefore return 404 unless an external proxy happens to rewrite them, so these defaults should use the actual .html paths or the server should register matching routes.

Useful? React with 👍 / 👎.

DOMAIN_URL=http://localhost:3000
WEB_PORT=3000

# [UI & Branding]
EMBED_COLOR=0xFFD700
ERROR_COLOR=0xFF0000
SUCCESS_COLOR=0x00FF00
BANNER_URL=https://i.postimg.cc/5y5pk1bL/Cyori-Banner.png
SUPPORT_URL=https://discord.gg/your_support_server
BANNER_URL=
SUPPORT_URL=

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Omit empty URLs from link buttons

When .env.example is copied without optional branding customization, this assignment makes SUPPORT_URL an empty string, preventing the fallback in utils/config.py:160 from applying. HelpControl passes that value to a link-style button in cogs/info.py:101-106, so /help cannot produce a valid Discord component; the empty DONATE_URL and VOTE_URL entries similarly break premium and vote prompts. Either omit blank URL variables so defaults apply or conditionally omit their buttons.

Useful? React with 👍 / 👎.

DASHBOARD_URL=http://localhost:3000/dashboard
INVITE_URL=http://localhost:3000/invite
DONATE_URL=
VOTE_URL=

# [Logging]
ERROR_LOG_WEBHOOK=optional_webhook_url
LOG_CHANNEL_ID=optional_channel_id
ERROR_LOG_WEBHOOK=
LOG_WEBHOOK_URL=
LOG_CHANNEL_ID=0

# [Optional cross-server role sync]
# Leave both at 0 to disable unless you intentionally configure this feature.
SOURCE_GUILD_ID=0
SYNC_ROLE_ID=0
Comment on lines +58 to +59

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Short-circuit role sync when IDs are disabled

With the new default SOURCE_GUILD_ID=0, role synchronization is not actually disabled: every active-bot member join still reaches bot.py:1353-1372, calls fetch_guild(0), catches the resulting failure, and performs a premium database lookup, while the six-hour audit also requests guild 0. Default self-hosted deployments therefore generate needless Discord API failures and database work; the sync handlers and task should return immediately when either configured ID is zero.

Useful? React with 👍 / 👎.


# [Misc]
VERSION=1.0.0
VERSION=1.0.1-revival
DEV_MODE=false
SOURCE_GUILD_ID=1413525842490953891
SYNC_ROLE_ID=1413696208920117368
IMPERSONATE_MAIN=false
DEPRECATED_MODE=false
TEST_GUILD_ID=0
62 changes: 62 additions & 0 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Quality

on:
push:
branches:
- main
- "revival/**"
pull_request:

permissions:
contents: read

jobs:
quality:
name: Python ${{ matrix.python-version }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12"]

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: pip

- name: Upgrade packaging tools
run: python -m pip install --upgrade pip setuptools wheel

- name: Install dependencies
run: python -m pip install -r requirements.txt

- name: Verify dependency graph
run: python -m pip check

- name: Compile Python sources
run: python -m compileall -q bot.py main.py cogs core cytechlink utils web

security-audit:
name: Dependency audit
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip

- name: Install audit tooling
run: python -m pip install --upgrade pip pip-audit

- name: Audit dependencies
run: python -m pip_audit -r requirements.txt --desc
196 changes: 108 additions & 88 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,116 +1,136 @@
# 🎵 CytechMusic Bot (Legacy)

**Advanced Discord Music Bot (Open Source)** built with `discord.py` and `Lavalink`.
This is the **Legacy Version** of the bot, now open-sourced for the community to use, learn, and host.

> [!NOTE]
> **Project Status**: This repository is **ARCHIVED** and no longer actively maintained.
> For the latest, high-performance version, please check out our new project: **[Cyori (Private)](https://github.com/CytechNaRak/Cyori)**. Cyori is built on a completely new architecture with 70%+ improvement in speed and stability.

## ✨ Features

### 🎧 Music Playback
- **High Quality Audio**: Powered by Lavalink for lag-free performance.
- **Sources**: Supports YouTube, Spotify, SoundCloud, and more.
- **Controls**: Play, Pause, Skip, Stop, Seek, Volume, Loop (Track/Queue), Shuffle.
- **Queue System**: View queue with pagination, remove songs, swap order.

### 🎚️ Audio Filters
ENHANCE your listening experience with real-time audio effects:
- **Presets**: `Nightcore`, `Vaporwave`, `8D Audio`
- **Manual Adjustments**:
- `Speed`: Control playback speed.
- `Karaoke`: Remove vocals for singing along.
- `Tremolo` & `Vibrato`: Add pitch/volume oscillation effects.
- `Rotation`: 8D-like rotating audio effect.
- `Distortion`: Add grit to the sound.
- `Lowpass`: Muffled/Lo-Fi effect.
- `ChannelMix`: Custom left/right audio routing.

### ⚙️ Server Settings
Fully configurable per server via the dashboard-like commands:
- **Language**: Switch between **English (EN)** and **Thai (TH)**.
- **DJ System**:
- **DJ Role**: Assign a specific role for music controls.
- **DJ Mode**: Restrict strict controls (Skip/Stop/Vol) to DJs/Admins only.
- **Vote System**: Enable voting requirements for specific filters (forces users to vote for the bot).
- **24/7 Mode**: Keep the bot in the voice channel even when inactive.
- **Autoplay**: Automatically play related songs when the queue ends.
- **Setup Channel**: Create a dedicated channel (`#cytech-music`) with a permanent player controller.

### 📊 Info & Utilities
- **Status**: View detailed uptime, CPU/RAM usage, and Lavalink node stats.
- **Ping**: Color-coded latency check.
- **Help**: Dynamic help menu with dropdowns for categories.
# CytechMusic

---
Open-source Discord music bot powered by `discord.py`, Lavalink, MongoDB, and the bundled CytechLink audio client.

## 🛠️ Installation & Setup
> [!IMPORTANT]
> **Project status: Revived / Maintenance Mode**
>
> CytechMusic has been reopened to keep the public release installable, compatible, secure, and maintainable. The revival focuses on bug fixes, dependency updates, code quality, documentation, and compatibility patches. Major new features are not planned here.
>
> **Cyori remains the active next-generation project.** CytechMusic is the public community edition and maintenance line.

[![Quality](https://github.com/Cytech-Team/CytechMusic/actions/workflows/quality.yml/badge.svg)](https://github.com/Cytech-Team/CytechMusic/actions/workflows/quality.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![Python](https://img.shields.io/badge/Python-3.10%2B-blue.svg)](https://www.python.org/)

## Revival goals

- Keep the existing feature set working on supported Python and Discord/Lavalink stacks.
- Patch bugs, compatibility problems, and security issues.
- Clean technical debt where it can be done without changing expected behaviour.
- Improve automated checks and documentation.
- Keep self-hosting straightforward.
- Avoid feature creep and large rewrites; new product development belongs in Cyori.

## Features

### Music playback
- Lavalink-backed playback.
- YouTube, Spotify, SoundCloud, and other sources supported by the configured Lavalink node.
- Play, pause, skip, stop, seek, volume, loop, shuffle, and queue controls.
- Queue pagination, removal, and ordering tools.

### Audio filters
- Nightcore, Vaporwave, and 8D presets.
- Speed, karaoke, tremolo, vibrato, rotation, distortion, low-pass, and channel-mix controls.

### Server controls
- English and Thai language support.
- DJ role and DJ mode.
- Vote-gated features.
- 24/7 mode and autoplay.
- Dedicated music channel/controller setup.

### Dashboard and utilities
- Embedded web dashboard/API.
- Uptime, CPU/RAM, latency, and Lavalink status information.
- Dynamic help and bot information commands.

## Requirements

### Prerequisites
- Python 3.10+
- MongoDB Database
- Lavalink Server (v3 or v4)
- **FFmpeg**
- MongoDB
- Lavalink v3 or v4 compatible with the bundled CytechLink implementation
- FFmpeg where required by your deployment

## Installation

### 1. Clone the Repository
```bash
git clone https://github.com/CytechNaRak/CytechMusic.git
git clone https://github.com/Cytech-Team/CytechMusic.git
cd CytechMusic
python -m venv .venv
```

### 2. Install Dependencies
Activate the virtual environment and install dependencies:

```bash
pip install -r requirements.txt
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
```

### 3. Configuration (.env)
1. Copy the example environment file:
```bash
cp .env.example .env
```
2. Open `.env` and fill in your details (Bot Token, MongoDB URI, Lavalink, etc.).
Copy the environment template:

> [!IMPORTANT]
> **SECURITY NOTE**: Never commit your `.env` file to a public repository. It contains sensitive tokens that can be used to control your bot or access your database.
```bash
cp .env.example .env
```

Fill in at minimum your Discord bot token, MongoDB connection, and Lavalink connection details, then start the bot:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Document all required numeric placeholders

When a new operator follows this instruction literally and replaces only the token, MongoDB, and Lavalink values, OWNER_IDS remains your_discord_user_id,another_owner_id; utils/config.py:131-132 converts each entry with int(...), so python main.py fails during import before the bot starts. The setup must also require replacing or clearing OWNER_IDS (and replacing NEW_BOT_ID, which is likewise converted to an integer by event handlers), or the template must provide safe values.

Useful? React with 👍 / 👎.


### 4. Run the Bot
```bash
python main.py
```

---
> [!CAUTION]
> Never commit `.env`, bot tokens, API keys, database credentials, or webhook secrets. The provided `.gitignore` excludes common local environment files.

## 🛠️ Tech Stack
- **Library**: `discord.py`
- **Database**: `MongoDB` (Motor for async)
- **Audio Node**: `Lavalink` (v3 or v4)
- **Payment**: `Stripe` (Optional)
- **Platform**: Python 3.10+
## Configuration

---
The complete public configuration template is in [`.env.example`](.env.example). Optional integrations such as Spotify, Top.gg, Stripe, remote logging, and cross-server role synchronisation can be left unset when unused.

## 📝 Commands List
For cross-server role synchronisation, configure `SOURCE_GUILD_ID` and `SYNC_ROLE_ID` only if you intentionally use that feature. The public template leaves both disabled by default.

## Tech stack

- `discord.py`
- MongoDB / Motor / PyMongo
- Lavalink + bundled CytechLink
- `aiohttp` web API/dashboard
- Optional Stripe, Spotify, Top.gg, and lyrics integrations

## Commands

| Command | Description |
| :--- | :--- |
| **/play [query]** | Play a song or playlist from URL or search. |
| **/stop** | Stop playback and clear the queue. |
| **/skip** | Skip the current song. |
| **/pause** | Pause/Resume playback. |
| **/volume [1-200]** | Adjust volume (Premium needed for >100). |
| **/queue** | Show the current music queue. |
| **/loop** | Toggle loop (Track/Queue/Off). |
| **/seek [time]** | Seek to a timestamp (e.g., `1:30`). |
| **/nowplaying** | Show current song info and controller. |
| --- | --- |
| `/play [query]` | Play a song or playlist from a URL or search. |
| `/stop` | Stop playback and clear the queue. |
| `/skip` | Skip the current song. |
| `/pause` | Pause or resume playback. |
| `/volume [1-200]` | Adjust playback volume. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve the premium limit in the volume documentation

The revised command table advertises the full 1-200 range without qualification, but cogs/music.py:976-985 caps non-premium users at 100 and rejects larger values with a premium-required response. This misleads standard users about an advertised command capability; document the free 1-100 range and that 101-200 requires premium.

Useful? React with 👍 / 👎.

| `/queue` | Show the current queue. |
| `/loop` | Toggle track/queue looping. |
| `/seek [time]` | Seek to a timestamp such as `1:30`. |
| `/nowplaying` | Show current track information and controls. |

---
## Maintenance policy

Accepted changes are primarily:

## 👥 Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
- bug fixes;
- compatibility patches;
- dependency/security updates;
- reliability and performance fixes;
- tests, CI, documentation, and safe refactors.

## 📄 License
Distributed under the [MIT License](LICENSE). See `LICENSE` for more information.
Large new features should target Cyori instead of expanding CytechMusic's scope again.

## Contributing

Pull requests are welcome. Please keep changes focused and preserve existing behaviour unless the change fixes a documented bug or compatibility issue.

## License

Distributed under the [MIT License](LICENSE).

---
**CytechMusic** is a free project for the community. Developed with ❤️ by **Cytech Team**.

Developed and maintained by **Cytech Team Development**.
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ dnspython>=2.6.1
tldextract==3.2.1
validators==0.18.2
humanize==4.0.0
python-dotenv==0.20.0
python-dotenv>=1.2.2
beautifulsoup4==4.11.1
websockets==10.4
psutil==5.9.5
werkzeug==2.2.2
werkzeug>=3.1.6
gevent-websocket
py-cpuinfo
legacy-cgi
Expand Down
Loading