Removed hardcoded URL in /join
parent
1201e44313
commit
b5999fe718
|
@ -8,6 +8,7 @@ In this section of the change log all current changes that have been made since
|
||||||
* Added aarch64 support
|
* Added aarch64 support
|
||||||
* Added cross compilation to Github Actions
|
* Added cross compilation to Github Actions
|
||||||
* Added `dev` branch to Github Actions
|
* Added `dev` branch to Github Actions
|
||||||
|
* Removed hardcoded URL in the /join command
|
||||||
|
|
||||||
## 2.1.1 | September 23rd 2023
|
## 2.1.1 | September 23rd 2023
|
||||||
Reduced the amount of CPU that the bot uses from ~15%-25% per user to 1%-2% per user (percentage per core, benched on an AMD Ryzen 9 5950X).
|
Reduced the amount of CPU that the bot uses from ~15%-25% per user to 1%-2% per user (percentage per core, benched on an AMD Ryzen 9 5950X).
|
||||||
|
|
|
@ -2269,6 +2269,7 @@ dependencies = [
|
||||||
"dotenv",
|
"dotenv",
|
||||||
"env_logger 0.10.0",
|
"env_logger 0.10.0",
|
||||||
"hex",
|
"hex",
|
||||||
|
"lazy_static",
|
||||||
"librespot",
|
"librespot",
|
||||||
"log",
|
"log",
|
||||||
"protobuf",
|
"protobuf",
|
||||||
|
@ -2280,7 +2281,6 @@ dependencies = [
|
||||||
"serenity",
|
"serenity",
|
||||||
"songbird",
|
"songbird",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"time",
|
|
||||||
"tokio",
|
"tokio",
|
||||||
"zerocopy 0.7.5",
|
"zerocopy 0.7.5",
|
||||||
]
|
]
|
||||||
|
|
|
@ -16,6 +16,7 @@ anyhow = "1.0.75"
|
||||||
dotenv = "0.15.0"
|
dotenv = "0.15.0"
|
||||||
env_logger = "0.10.0"
|
env_logger = "0.10.0"
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
|
lazy_static = "1.4.0"
|
||||||
librespot = { version = "0.4.2", default-features = false }
|
librespot = { version = "0.4.2", default-features = false }
|
||||||
log = "0.4.20"
|
log = "0.4.20"
|
||||||
protobuf = "2.28.0"
|
protobuf = "2.28.0"
|
||||||
|
@ -27,7 +28,6 @@ serde_json = "1.0.107"
|
||||||
serenity = { version = "0.11.6", features = ["framework", "cache", "standard_framework"], default-features = false }
|
serenity = { version = "0.11.6", features = ["framework", "cache", "standard_framework"], default-features = false }
|
||||||
songbird = "0.3.2"
|
songbird = "0.3.2"
|
||||||
thiserror = "1.0.48"
|
thiserror = "1.0.48"
|
||||||
time = "0.3.28"
|
|
||||||
tokio = { version = "1.32.0", features = ["rt", "full"] }
|
tokio = { version = "1.32.0", features = ["rt", "full"] }
|
||||||
zerocopy = "0.7.5"
|
zerocopy = "0.7.5"
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ use serenity::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bot::commands::{respond_message, CommandOutput},
|
bot::commands::{respond_message, CommandOutput},
|
||||||
|
consts::SPOTICORD_ACCOUNTS_URL,
|
||||||
database::{Database, DatabaseError},
|
database::{Database, DatabaseError},
|
||||||
utils::embed::{EmbedBuilder, Status},
|
utils::embed::{EmbedBuilder, Status},
|
||||||
};
|
};
|
||||||
|
@ -39,8 +40,11 @@ pub fn command(ctx: Context, command: ApplicationCommandInteraction) -> CommandO
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(request) = database.get_user_request(command.user.id.to_string()).await {
|
if let Ok(request) = database.get_user_request(command.user.id.to_string()).await {
|
||||||
let base = std::env::var("SPOTICORD_ACCOUNTS_URL").expect("to be present");
|
let link = format!(
|
||||||
let link = format!("{}/spotify/{}", base, request.token);
|
"{}/spotify/{}",
|
||||||
|
SPOTICORD_ACCOUNTS_URL.as_str(),
|
||||||
|
request.token
|
||||||
|
);
|
||||||
|
|
||||||
respond_message(
|
respond_message(
|
||||||
&ctx,
|
&ctx,
|
||||||
|
@ -106,8 +110,11 @@ pub fn command(ctx: Context, command: ApplicationCommandInteraction) -> CommandO
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(request) => {
|
Ok(request) => {
|
||||||
let base = std::env::var("SPOTICORD_ACCOUNTS_URL").expect("to be present");
|
let link = format!(
|
||||||
let link = format!("{}/spotify/{}", base, request.token);
|
"{}/spotify/{}",
|
||||||
|
SPOTICORD_ACCOUNTS_URL.as_str(),
|
||||||
|
request.token
|
||||||
|
);
|
||||||
|
|
||||||
respond_message(
|
respond_message(
|
||||||
&ctx,
|
&ctx,
|
||||||
|
|
|
@ -7,6 +7,7 @@ use serenity::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bot::commands::{defer_message, respond_message, update_message, CommandOutput},
|
bot::commands::{defer_message, respond_message, update_message, CommandOutput},
|
||||||
|
consts::SPOTICORD_ACCOUNTS_URL,
|
||||||
session::manager::{SessionCreateError, SessionManager},
|
session::manager::{SessionCreateError, SessionManager},
|
||||||
utils::embed::{EmbedBuilder, Status},
|
utils::embed::{EmbedBuilder, Status},
|
||||||
};
|
};
|
||||||
|
@ -241,7 +242,7 @@ pub fn command(ctx: Context, command: ApplicationCommandInteraction) -> CommandO
|
||||||
&command,
|
&command,
|
||||||
EmbedBuilder::new()
|
EmbedBuilder::new()
|
||||||
.title("Cannot join voice channel")
|
.title("Cannot join voice channel")
|
||||||
.description("You need to link your Spotify account. Use </link:1036714850367320136> or go to [the accounts website](https://account.spoticord.com/) to get started.")
|
.description(format!("You need to link your Spotify account. Use </link:1036714850367320136> or go to [the accounts website]({}) to get started.", SPOTICORD_ACCOUNTS_URL.as_str()))
|
||||||
.status(Status::Error)
|
.status(Status::Error)
|
||||||
.build(),
|
.build(),
|
||||||
)
|
)
|
||||||
|
@ -255,7 +256,7 @@ pub fn command(ctx: Context, command: ApplicationCommandInteraction) -> CommandO
|
||||||
&command,
|
&command,
|
||||||
EmbedBuilder::new()
|
EmbedBuilder::new()
|
||||||
.title("Cannot join voice channel")
|
.title("Cannot join voice channel")
|
||||||
.description("Spoticord no longer has access to your Spotify account. Use </link:1036714850367320136> or go to [the accounts website](https://account.spoticord.com/) to relink your Spotify account.")
|
.description(format!("Spoticord no longer has access to your Spotify account. Use </link:1036714850367320136> or go to [the accounts website]({}) to relink your Spotify account.", SPOTICORD_ACCOUNTS_URL.as_str()))
|
||||||
.status(Status::Error)
|
.status(Status::Error)
|
||||||
.build(),
|
.build(),
|
||||||
).await;
|
).await;
|
||||||
|
|
|
@ -30,20 +30,22 @@ pub const NAME: &str = "playing";
|
||||||
|
|
||||||
pub fn command(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutput {
|
pub fn command(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutput {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let not_playing = async {
|
macro_rules! not_playing {
|
||||||
respond_message(
|
() => {
|
||||||
&ctx,
|
respond_message(
|
||||||
&command,
|
&ctx,
|
||||||
EmbedBuilder::new()
|
&command,
|
||||||
.title("Cannot get track info")
|
EmbedBuilder::new()
|
||||||
.icon_url("https://spoticord.com/forbidden.png")
|
.title("Cannot get track info")
|
||||||
.description("I'm currently not playing any music in this server")
|
.icon_url("https://spoticord.com/forbidden.png")
|
||||||
.status(Status::Error)
|
.description("I'm currently not playing any music in this server")
|
||||||
.build(),
|
.status(Status::Error)
|
||||||
true,
|
.build(),
|
||||||
)
|
true,
|
||||||
.await;
|
)
|
||||||
};
|
.await;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
let data = ctx.data.read().await;
|
let data = ctx.data.read().await;
|
||||||
let session_manager = data
|
let session_manager = data
|
||||||
|
@ -51,62 +53,50 @@ pub fn command(ctx: Context, command: ApplicationCommandInteraction) -> CommandO
|
||||||
.expect("to contain a value")
|
.expect("to contain a value")
|
||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
let session = match session_manager
|
let Some(session) = session_manager
|
||||||
.get_session(command.guild_id.expect("to contain a value"))
|
.get_session(command.guild_id.expect("to contain a value"))
|
||||||
.await
|
.await
|
||||||
{
|
else {
|
||||||
Some(session) => session,
|
not_playing!();
|
||||||
None => {
|
|
||||||
not_playing.await;
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let owner = match session.owner().await {
|
let Some(owner) = session.owner().await else {
|
||||||
Some(owner) => owner,
|
not_playing!();
|
||||||
None => {
|
|
||||||
not_playing.await;
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get Playback Info from session
|
// Get Playback Info from session
|
||||||
let pbi = match session.playback_info().await {
|
let Some(pbi) = session.playback_info().await else {
|
||||||
Some(pbi) => pbi,
|
not_playing!();
|
||||||
None => {
|
|
||||||
not_playing.await;
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get owner of session
|
// Get owner of session
|
||||||
let owner = match utils::discord::get_user(&ctx, owner).await {
|
let Some(owner) = utils::discord::get_user(&ctx, owner).await else {
|
||||||
Some(user) => user,
|
// This shouldn't happen
|
||||||
None => {
|
|
||||||
// This shouldn't happen
|
|
||||||
|
|
||||||
error!("Could not find user with ID: {owner}");
|
error!("Could not find user with ID: {owner}");
|
||||||
|
|
||||||
respond_message(
|
respond_message(
|
||||||
&ctx,
|
&ctx,
|
||||||
&command,
|
&command,
|
||||||
EmbedBuilder::new()
|
EmbedBuilder::new()
|
||||||
.title("[INTERNAL ERROR] Cannot get track info")
|
.title("[INTERNAL ERROR] Cannot get track info")
|
||||||
.description(format!(
|
.description(format!(
|
||||||
"Could not find user with ID `{}`\nThis is an issue with the bot!",
|
"Could not find user with ID `{}`\nThis is an issue with the bot!",
|
||||||
owner
|
owner
|
||||||
))
|
))
|
||||||
.status(Status::Error)
|
.status(Status::Error)
|
||||||
.build(),
|
.build(),
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get metadata
|
// Get metadata
|
||||||
|
@ -188,48 +178,39 @@ pub fn component(ctx: Context, mut interaction: MessageComponentInteraction) ->
|
||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
// Check if session still exists
|
// Check if session still exists
|
||||||
let mut session = match session_manager
|
let Some(mut session) = session_manager
|
||||||
.get_session(interaction.guild_id.expect("to contain a value"))
|
.get_session(interaction.guild_id.expect("to contain a value"))
|
||||||
.await
|
.await
|
||||||
{
|
else {
|
||||||
Some(session) => session,
|
error_edit(
|
||||||
None => {
|
"Cannot perform action",
|
||||||
error_edit(
|
"I'm currently not playing any music in this server",
|
||||||
"Cannot perform action",
|
)
|
||||||
"I'm currently not playing any music in this server",
|
.await;
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check if the session contains an owner
|
// Check if the session contains an owner
|
||||||
let owner = match session.owner().await {
|
let Some(owner) = session.owner().await else {
|
||||||
Some(owner) => owner,
|
error_edit(
|
||||||
None => {
|
"Cannot change playback state",
|
||||||
error_edit(
|
"I'm currently not playing any music in this server",
|
||||||
"Cannot change playback state",
|
)
|
||||||
"I'm currently not playing any music in this server",
|
.await;
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get Playback Info from session
|
// Get Playback Info from session
|
||||||
let pbi = match session.playback_info().await {
|
let Some(pbi) = session.playback_info().await else {
|
||||||
Some(pbi) => pbi,
|
error_edit(
|
||||||
None => {
|
"Cannot change playback state",
|
||||||
error_edit(
|
"I'm currently not playing any music in this server",
|
||||||
"Cannot change playback state",
|
)
|
||||||
"I'm currently not playing any music in this server",
|
.await;
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check if the user is the owner of the session
|
// Check if the user is the owner of the session
|
||||||
|
@ -244,30 +225,27 @@ pub fn component(ctx: Context, mut interaction: MessageComponentInteraction) ->
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get owner of session
|
// Get owner of session
|
||||||
let owner = match utils::discord::get_user(&ctx, owner).await {
|
let Some(owner) = utils::discord::get_user(&ctx, owner).await else {
|
||||||
Some(user) => user,
|
// This shouldn't happen
|
||||||
None => {
|
|
||||||
// This shouldn't happen
|
|
||||||
|
|
||||||
error!("Could not find user with ID: {owner}");
|
error!("Could not find user with ID: {owner}");
|
||||||
|
|
||||||
respond_component_message(
|
respond_component_message(
|
||||||
&ctx,
|
&ctx,
|
||||||
&interaction,
|
&interaction,
|
||||||
EmbedBuilder::new()
|
EmbedBuilder::new()
|
||||||
.title("[INTERNAL ERROR] Cannot get track info")
|
.title("[INTERNAL ERROR] Cannot get track info")
|
||||||
.description(format!(
|
.description(format!(
|
||||||
"Could not find user with ID `{}`\nThis is an issue with the bot!",
|
"Could not find user with ID `{}`\nThis is an issue with the bot!",
|
||||||
owner
|
owner
|
||||||
))
|
))
|
||||||
.status(Status::Error)
|
.status(Status::Error)
|
||||||
.build(),
|
.build(),
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Send the desired command to the session
|
// Send the desired command to the session
|
||||||
|
@ -370,34 +348,28 @@ async fn update_embed(interaction: &mut MessageComponentInteraction, ctx: &Conte
|
||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
// Check if session still exists
|
// Check if session still exists
|
||||||
let session = match session_manager
|
let Some(session) = session_manager
|
||||||
.get_session(interaction.guild_id.expect("to contain a value"))
|
.get_session(interaction.guild_id.expect("to contain a value"))
|
||||||
.await
|
.await
|
||||||
{
|
else {
|
||||||
Some(session) => session,
|
error_edit(
|
||||||
None => {
|
"Cannot perform action",
|
||||||
error_edit(
|
"I'm currently not playing any music in this server",
|
||||||
"Cannot perform action",
|
)
|
||||||
"I'm currently not playing any music in this server",
|
.await;
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get Playback Info from session
|
// Get Playback Info from session
|
||||||
let pbi = match session.playback_info().await {
|
let Some(pbi) = session.playback_info().await else {
|
||||||
Some(pbi) => pbi,
|
error_edit(
|
||||||
None => {
|
"Cannot change playback state",
|
||||||
error_edit(
|
"I'm currently not playing any music in this server",
|
||||||
"Cannot change playback state",
|
)
|
||||||
"I'm currently not playing any music in this server",
|
.await;
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let (title, description, thumbnail) = get_metadata(&pbi);
|
let (title, description, thumbnail) = get_metadata(&pbi);
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
#[cfg(not(debug_assertions))]
|
#[cfg(not(debug_assertions))]
|
||||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
|
@ -8,3 +10,18 @@ pub const MOTD: &str = "some good 'ol music";
|
||||||
|
|
||||||
/// The time it takes for Spoticord to disconnect when no music is being played
|
/// The time it takes for Spoticord to disconnect when no music is being played
|
||||||
pub const DISCONNECT_TIME: u64 = 5 * 60;
|
pub const DISCONNECT_TIME: u64 = 5 * 60;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref DISCORD_TOKEN: String =
|
||||||
|
std::env::var("DISCORD_TOKEN").expect("missing DISCORD_TOKEN environment variable");
|
||||||
|
pub static ref DATABASE_URL: String =
|
||||||
|
std::env::var("DATABASE_URL").expect("missing DATABASE_URL environment variable");
|
||||||
|
pub static ref SPOTICORD_ACCOUNTS_URL: String = std::env::var("SPOTICORD_ACCOUNTS_URL")
|
||||||
|
.expect("missing SPOTICORD_ACCOUNTS_URL environment variable");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stats")]
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref KV_URL: String =
|
||||||
|
std::env::var("KV_URL").expect("missing KV_URL environment variable");
|
||||||
|
}
|
||||||
|
|
25
src/main.rs
25
src/main.rs
|
@ -1,10 +1,18 @@
|
||||||
use dotenv::dotenv;
|
use dotenv::dotenv;
|
||||||
|
|
||||||
use crate::{bot::commands::CommandManager, database::Database, session::manager::SessionManager};
|
#[cfg(feature = "stats")]
|
||||||
|
use crate::consts::KV_URL;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
bot::commands::CommandManager,
|
||||||
|
consts::{DATABASE_URL, DISCORD_TOKEN, MOTD},
|
||||||
|
database::Database,
|
||||||
|
session::manager::SessionManager,
|
||||||
|
};
|
||||||
use log::*;
|
use log::*;
|
||||||
use serenity::{framework::StandardFramework, prelude::GatewayIntents, Client};
|
use serenity::{framework::StandardFramework, prelude::GatewayIntents, Client};
|
||||||
use songbird::SerenityInit;
|
use songbird::SerenityInit;
|
||||||
use std::{any::Any, env, process::exit};
|
use std::{any::Any, process::exit};
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use tokio::signal::unix::SignalKind;
|
use tokio::signal::unix::SignalKind;
|
||||||
|
@ -41,7 +49,7 @@ async fn main() {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
|
||||||
info!("It's a good day");
|
info!("It's a good day");
|
||||||
info!(" - Spoticord {}", time::OffsetDateTime::now_utc().year());
|
info!(" - Spoticord, {}", MOTD);
|
||||||
|
|
||||||
let result = dotenv();
|
let result = dotenv();
|
||||||
|
|
||||||
|
@ -54,19 +62,14 @@ async fn main() {
|
||||||
warn!("No .env file found, expecting all necessary environment variables");
|
warn!("No .env file found, expecting all necessary environment variables");
|
||||||
}
|
}
|
||||||
|
|
||||||
let token = env::var("DISCORD_TOKEN").expect("a token in the environment");
|
|
||||||
let db_url = env::var("DATABASE_URL").expect("a database URL in the environment");
|
|
||||||
|
|
||||||
#[cfg(feature = "stats")]
|
#[cfg(feature = "stats")]
|
||||||
let stats_manager =
|
let stats_manager = StatsManager::new(KV_URL.as_str()).expect("Failed to connect to redis");
|
||||||
StatsManager::new(env::var("KV_URL").expect("a redis URL in the environment"))
|
|
||||||
.expect("Failed to connect to redis");
|
|
||||||
|
|
||||||
let session_manager = SessionManager::new();
|
let session_manager = SessionManager::new();
|
||||||
|
|
||||||
// Create client
|
// Create client
|
||||||
let mut client = Client::builder(
|
let mut client = Client::builder(
|
||||||
token,
|
DISCORD_TOKEN.as_str(),
|
||||||
GatewayIntents::GUILDS | GatewayIntents::GUILD_VOICE_STATES,
|
GatewayIntents::GUILDS | GatewayIntents::GUILD_VOICE_STATES,
|
||||||
)
|
)
|
||||||
.event_handler(crate::bot::events::Handler)
|
.event_handler(crate::bot::events::Handler)
|
||||||
|
@ -78,7 +81,7 @@ async fn main() {
|
||||||
{
|
{
|
||||||
let mut data = client.data.write().await;
|
let mut data = client.data.write().await;
|
||||||
|
|
||||||
data.insert::<Database>(Database::new(db_url, None));
|
data.insert::<Database>(Database::new(DATABASE_URL.as_str(), None));
|
||||||
data.insert::<CommandManager>(CommandManager::new());
|
data.insert::<CommandManager>(CommandManager::new());
|
||||||
data.insert::<SessionManager>(session_manager.clone());
|
data.insert::<SessionManager>(session_manager.clone());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue