Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3.4.0 #40

Merged
merged 24 commits into from
Aug 3, 2024
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
2 changes: 2 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ BOT_FFMPEG_LOGGING=false
BOT_COMMAND_PREFIX=//
BOT_LANGUAGE=en

BOT_MAX_SONGS_IN_QUEUE=500

BOT_DISCORD_TOKEN=undefined
BOT_DISCORD_CLIENT_ID=undefined
BOT_DISCORD_OVERPOWERED_ID=undefined
Expand Down
11 changes: 4 additions & 7 deletions .github/workflows/publish-docker-image.yaml
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
name: Publish Docker image

on:
push:
workflow_run:
workflows: [ "tests", "linters" ]
types: ['completed']
branches: ['master']
paths-ignore:
- '**/wiki/**'
- '/wiki/**'
- 'docker-compose.yml'
- '.env'
- '*.sh'

env:
IMAGE_TAG: alexincube/aicotest

jobs:
push_to_registry:
if: github.event.workflow_run.event == 'push'
name: Push Docker image to Docker Hub
runs-on: ubuntu-latest
steps:
Expand Down
36 changes: 36 additions & 0 deletions .github/workflows/quality.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Code Quality

on:
push:
branches: ['**']
pull_request:
branches: ['**']

jobs:
linters:
name: Run linters
runs-on: ubuntu-latest

steps:
- name: Check out Git repository
uses: actions/checkout@v4

- name: Setup PNPM
uses: pnpm/action-setup@v4
with:
version: 9

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22.x
cache: "pnpm"

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Run Prettier
run: pnpm run prettier:check

- name: Run ESLint
run: pnpm run eslint
55 changes: 55 additions & 0 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Tests

on:
push:
branches: ['**']
paths-ignore:
- '**/wiki/**'
- '/wiki/**'
- 'docker-compose.yml'
- '.env'
- '*.sh'
pull_request:
branches: ['**']
paths-ignore:
- '**/wiki/**'
- '/wiki/**'
- 'docker-compose.yml'
- '.env'
- '*.sh'

jobs:
tests:
runs-on: ubuntu-latest

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

- name: Setup PNPM
uses: pnpm/action-setup@v4
with:
version: 9

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22.x
cache: "pnpm"

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Make env file
run: |
pwd
touch .env.development
echo '${{ secrets.ENV_DEVELOPMENT }}' > .env.development

- name: Make yt-cookies.json
run: |
touch yt-cookies.json
echo '${{ secrets.YOUTUBE_COOKIES }}' > yt-cookies.json

- name: Run tests
run: pnpm run test
11 changes: 6 additions & 5 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ export default tseslint.config(eslint.configs.recommended, ...tseslint.configs.r
plugins: {
'typescript-eslint': ParserTypeScript,
prettier: prettierPlugin
}, ignores: ['build', 'node_modules', 'coverage', 'eslint.config.js'],
},
ignores: ['build', 'node_modules', 'coverage', 'eslint.config.js'],
languageOptions: {
globals: {
...globals.node,
Expand All @@ -20,12 +21,12 @@ export default tseslint.config(eslint.configs.recommended, ...tseslint.configs.r
}
},
rules: {
...prettierPlugin.configs.recommended.rules,
...eslintConfigPrettier.rules,
...prettierPlugin.configs.recommended.rules,
...eslintConfigPrettier.rules,
'@typescript-eslint/no-var-requires': 0,
'@typescript-eslint/no-non-null-assertion': 0,
'@typescript-eslint/no-explicit-any': "warn",
'@typescript-eslint/no-explicit-any': 'warn',
'prettier/prettier': ['error', { endOfLine: 'auto' }],
'no-constant-binary-expression': "off"
'no-constant-binary-expression': 'off'
}
});
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
{
"name": "aicbot",
"version": "3.3.1",
"version": "3.4.0",
"description": "Discord Bot for playing music",
"main": "build/main.js",
"scripts": {
"build": "tsc",
"development": "tsc&& cross-env NODE_ENV=development node build/main.js",
"production": "cross-env NODE_ENV=production node build/main.js",
"cookies_grabbing": "cross-env NODE_ENV=development node build/Script_getCookie.js"
"cookies_grabbing": "cross-env NODE_ENV=development node build/Script_getCookie.js",
"test": "tsc&& cross-env NODE_ENV=development node --test",
"eslint": "eslint \"src/**/*.{ts,js}\"",
"prettier:format": "prettier --write \"**/*.{ts,js}\"",
"prettier:check": "prettier --check \"**/*.{ts,js}\""
},
"type": "module",
"keywords": [],
Expand Down
13 changes: 13 additions & 0 deletions src/ClientIntents.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { GatewayIntentBits } from 'discord.js';

export const clientIntents: Array<GatewayIntentBits> = [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildPresences,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.GuildVoiceStates,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
GatewayIntentBits.DirectMessages,
GatewayIntentBits.DirectMessageTyping,
GatewayIntentBits.GuildModeration
];
1 change: 0 additions & 1 deletion src/CookiesAutomation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export async function getYoutubeCookie() {

const browser = await puppeteer.launch({
headless: true,
slowMo: 2000,
args: ['--remote-debugging-port=9222', '--remote-debugging-address=0.0.0.0', '--no-sandbox']
});
const page = await browser.newPage();
Expand Down
25 changes: 22 additions & 3 deletions src/EnvironmentVariables.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
import { z } from 'zod';
import * as dotenv from 'dotenv';
import { loggerSend } from './utilities/logger.js';
import path from 'path';
import fs from 'fs';

const loggerPrefixEnv = 'ENV';

dotenv.config({ path: `.env.${process.env.NODE_ENV}` });
const envPath = path.resolve(process.cwd(), `.env.${process.env.NODE_ENV}`);

loggerSend(`Checking environment variables in ${envPath}`, loggerPrefixEnv);
if (fs.existsSync(envPath)) {
dotenv.config({ path: envPath });
loggerSend(`Environment variables is found in ${envPath}`, loggerPrefixEnv);
} else {
loggerSend(
`Environment variables are not found in ${envPath}, trying to load variables from OS environment variables`,
loggerPrefixEnv
);
}

const envVariables = z.object({
NODE_ENV: z.enum(['development', 'production']),
NODE_ENV: z.enum(['development', 'production']).default('development'),

BOT_VERBOSE_LOGGING: z
.preprocess(
Expand Down Expand Up @@ -37,6 +50,8 @@ const envVariables = z.object({
BOT_LANGUAGE: z.enum(['en', 'ru']).optional().default('en'),
BOT_COMMAND_PREFIX: z.string().min(1),

BOT_MAX_SONGS_IN_QUEUE: z.coerce.number().positive().min(1).optional().default(500),

MONGO_URI: z.string(),
MONGO_DATABASE_NAME: z.string(),

Expand All @@ -61,4 +76,8 @@ const envVariables = z.object({

export const ENV = envVariables.parse(process.env);

loggerSend(`Loaded .env.${process.env.NODE_ENV}`, loggerPrefixEnv);
if (fs.existsSync(envPath)) {
loggerSend(`Environment variables is loaded from ${envPath}`, loggerPrefixEnv);
} else {
loggerSend(`Environment variables is loaded from OS environment variables`, loggerPrefixEnv);
}
30 changes: 19 additions & 11 deletions src/audioplayer/AudioPlayerCore.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { DisTube, PlayOptions, Queue, RepeatMode, Song, Events as DistubeEvents, Playlist } from 'distube';
import {
DisTube,
PlayOptions,
Queue,
RepeatMode,
Song,
Events as DistubeEvents,
Playlist
} from 'distube';
import { AudioPlayersManager } from './AudioPlayersManager.js';
import { pagination } from '../utilities/pagination/pagination.js';
import { ButtonStyles, ButtonTypes } from '../utilities/pagination/paginationTypes.js';
Expand All @@ -25,8 +33,6 @@ import { joinVoiceChannel } from '@discordjs/voice';
import { generateWarningEmbed } from '../utilities/generateWarningEmbed.js';
import { generateLyricsEmbed } from './Lyrics.js';

export const queueSongsLimit = 500;

export const loggerPrefixAudioplayer = `Audioplayer`;

const plugins = await LoadPlugins();
Expand Down Expand Up @@ -58,7 +64,7 @@ export class AudioPlayerCore {
options?: PlayOptions
) {
try {
const playableThing: Song | Playlist = await this.distube.handler.resolve(song)
const playableThing: Song | Playlist = await this.distube.handler.resolve(song);

// I am need manual connect user to a voice channel, because when I am using only Distube "play"
// method, getVoiceConnection in @discordjs/voice is not working
Expand All @@ -72,13 +78,15 @@ export class AudioPlayerCore {
} catch (e) {
if (ENV.BOT_VERBOSE_LOGGING) loggerError(e);
await textChannel.send({
embeds: [generateErrorEmbed(`${song}\n${e.message}`, i18next.t('audioplayer:play_error') as string)]
embeds: [
generateErrorEmbed(`${song}\n${e.message}`, i18next.t('audioplayer:play_error') as string)
]
});

const queue = this.distube.getQueue(voiceChannel.guildId)
const queue = this.distube.getQueue(voiceChannel.guildId);

if (!queue) return
if (queue.songs.length === 0) await this.stop(voiceChannel.guild)
if (!queue) return;
if (queue.songs.length === 0) await this.stop(voiceChannel.guild);
}
}

Expand Down Expand Up @@ -362,17 +370,17 @@ export class AudioPlayerCore {
if (!queue.textChannel) return;

await queue.textChannel.send({ embeds: [generateAddedPlaylistMessage(playlist)] });
if (queue.songs.length >= queueSongsLimit) {
if (queue.songs.length >= ENV.BOT_MAX_SONGS_IN_QUEUE) {
await queue.textChannel.send({
embeds: [
generateWarningEmbed(
i18next.t('audioplayer:event_add_list_limit', {
queueLimit: queueSongsLimit
queueLimit: ENV.BOT_MAX_SONGS_IN_QUEUE
}) as string
)
]
});
queue.songs.length = queueSongsLimit;
queue.songs.length = ENV.BOT_MAX_SONGS_IN_QUEUE;
}

const player = this.playersManager.get(queue.id);
Expand Down
Loading
Loading