feat: started with basic commands, added dependencies, started working on lavalink impl
This commit is contained in:
parent
9dad9bbda3
commit
d6a2cb5c8b
13 changed files with 532 additions and 46 deletions
21
src/commands/info.rs
Normal file
21
src/commands/info.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
use chrono::Local;
|
||||
use serenity::all::{CommandInteraction, Context};
|
||||
use serenity::builder::{CreateCommand, CreateEmbed, CreateEmbedAuthor, CreateEmbedFooter};
|
||||
use serenity::model::application::ResolvedOption;
|
||||
|
||||
pub fn run(ctx: &Context, command: &CommandInteraction, _options: &[ResolvedOption]) -> CreateEmbed {
|
||||
let username = command.user.name.as_str();
|
||||
let current_time = Local::now().format("%Y-%m-%d @ %H:%M:%S");
|
||||
CreateEmbed::new()
|
||||
.author(CreateEmbedAuthor::new("Rustendo"))
|
||||
.description("Botendo v7\ndeveloped by [moonleay](https://moonleay.net)\n\nCheck out the repository: https://git.moonleay.net/DiscordBots/Rustendo")
|
||||
.footer(CreateEmbedFooter::new(format!(">{} | {}", current_time, username)))
|
||||
}
|
||||
|
||||
|
||||
pub fn register() -> CreateCommand {
|
||||
CreateCommand::new("info").description("Infos about the bot")
|
||||
}
|
||||
|
||||
// >18/02/2024 @ 19:01:59 - bartlo
|
||||
// >2024-02-19 17:58:39 | moonleay
|
|
@ -1 +1,3 @@
|
|||
pub mod ping;
|
||||
pub mod info;
|
||||
pub mod play;
|
||||
pub mod stop;
|
|
@ -1,10 +0,0 @@
|
|||
use serenity::builder::CreateCommand;
|
||||
use serenity::model::application::ResolvedOption;
|
||||
|
||||
pub fn run(_options: &[ResolvedOption]) -> String {
|
||||
"Hey, I'm alive!".to_string()
|
||||
}
|
||||
|
||||
pub fn register() -> CreateCommand {
|
||||
CreateCommand::new("ping").description("A ping command")
|
||||
}
|
38
src/commands/play.rs
Normal file
38
src/commands/play.rs
Normal file
|
@ -0,0 +1,38 @@
|
|||
|
||||
use chrono::Local;
|
||||
use serenity::all::{CommandInteraction, Context, ResolvedOption, ResolvedValue};
|
||||
use serenity::builder::{CreateCommand, CreateCommandOption, CreateEmbed, CreateEmbedAuthor, CreateEmbedFooter};
|
||||
use serenity::model::application::CommandOptionType;
|
||||
|
||||
pub fn run(ctx: &Context, command: &CommandInteraction, options: &[ResolvedOption]) -> CreateEmbed {
|
||||
let username = command.user.name.as_str();
|
||||
let current_time = Local::now().format("%Y-%m-%d @ %H:%M:%S");
|
||||
|
||||
let query = if let Some(ResolvedOption {
|
||||
value: ResolvedValue::String(query), ..
|
||||
}) = options.first()
|
||||
{
|
||||
query
|
||||
} else {
|
||||
return CreateEmbed::new()
|
||||
.author(CreateEmbedAuthor::new("Rustendo"))
|
||||
.title("Error 400")
|
||||
.description("There is no query provied.")
|
||||
.footer(CreateEmbedFooter::new(format!(">{} | {}", current_time, username)))
|
||||
};
|
||||
|
||||
CreateEmbed::new()
|
||||
.author(CreateEmbedAuthor::new("Rustendo"))
|
||||
.title(format!("Searching for {}", query))
|
||||
.footer(CreateEmbedFooter::new(format!(">{} | {}", current_time, username)))
|
||||
}
|
||||
|
||||
|
||||
pub fn register() -> CreateCommand {
|
||||
CreateCommand::new("play")
|
||||
.description("Play music")
|
||||
.add_option(
|
||||
CreateCommandOption::new(CommandOptionType::String, "query", "Link or search term")
|
||||
.required(true)
|
||||
)
|
||||
}
|
21
src/commands/stop.rs
Normal file
21
src/commands/stop.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
use chrono::Local;
|
||||
use serenity::all::{CommandInteraction, Context};
|
||||
use serenity::builder::{CreateCommand, CreateEmbed, CreateEmbedAuthor, CreateEmbedFooter};
|
||||
use serenity::model::application::ResolvedOption;
|
||||
|
||||
pub fn run(ctx: &Context, command: &CommandInteraction, _options: &[ResolvedOption]) -> CreateEmbed {
|
||||
let username = command.user.name.as_str();
|
||||
let current_time = Local::now().format("%Y-%m-%d @ %H:%M:%S");
|
||||
CreateEmbed::new()
|
||||
.author(CreateEmbedAuthor::new("Rustendo"))
|
||||
.title("I stopped and left\nJust like your girlfriend.")
|
||||
.footer(CreateEmbedFooter::new(format!(">{} | {}", current_time, username)))
|
||||
}
|
||||
|
||||
|
||||
pub fn register() -> CreateCommand {
|
||||
CreateCommand::new("stop").description("Stop playing and start leavin'")
|
||||
}
|
||||
|
||||
// >18/02/2024 @ 19:01:59 - bartlo
|
||||
// >2024-02-19 17:58:39 | moonleay
|
8
src/handler/lavalink_event_handler.rs
Normal file
8
src/handler/lavalink_event_handler.rs
Normal file
|
@ -0,0 +1,8 @@
|
|||
use lavalink_rs::{client::LavalinkClient, model::events};
|
||||
use serenity::all::standard::macros::hook;
|
||||
|
||||
#[hook]
|
||||
pub async fn ready_event(client: LavalinkClient, _session_id: String, event: &events::Ready) {
|
||||
client.delete_all_player_contexts().await.unwrap();
|
||||
println!("Lavalink is ready for Freddy:: {:?}", event);
|
||||
}
|
1
src/handler/mod.rs
Normal file
1
src/handler/mod.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub mod lavalink_event_handler;
|
63
src/main.rs
63
src/main.rs
|
@ -1,30 +1,47 @@
|
|||
mod commands;
|
||||
mod util;
|
||||
mod handler;
|
||||
|
||||
use std::error::Error;
|
||||
|
||||
use lavalink_rs::client::LavalinkClient;
|
||||
use lavalink_rs::model::events::Events;
|
||||
use lavalink_rs::model::UserId;
|
||||
use lavalink_rs::node::NodeBuilder;
|
||||
use serenity::all::OnlineStatus;
|
||||
use serenity::async_trait;
|
||||
use serenity::builder::{CreateInteractionResponse, CreateInteractionResponseMessage};
|
||||
use serenity::builder::{CreateEmbed, CreateEmbedAuthor, CreateEmbedFooter, CreateInteractionResponse, CreateInteractionResponseMessage};
|
||||
use serenity::gateway::ActivityData;
|
||||
use serenity::model::application::{Command, Interaction};
|
||||
use serenity::model::gateway::Ready;
|
||||
use serenity::prelude::*;
|
||||
use util::config;
|
||||
|
||||
use crate::handler::lavalink_event_handler;
|
||||
|
||||
|
||||
struct Handler;
|
||||
|
||||
pub struct Data {
|
||||
pub lavalink: LavalinkClient,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl EventHandler for Handler {
|
||||
async fn interaction_create(&self, ctx: Context, interaction: Interaction) {
|
||||
if let Interaction::Command(command) = interaction {
|
||||
println!("Received command interaction: {command:#?}");
|
||||
|
||||
let content = match command.data.name.as_str() {
|
||||
"ping" => Some(commands::ping::run(&command.data.options())),
|
||||
_ => Some("not implemented :(".to_string()),
|
||||
"info" => Some(commands::info::run(&ctx, &command, &command.data.options())),
|
||||
"play" => Some(commands::play::run(&ctx, &command, &command.data.options())),
|
||||
"stop" => Some(commands::stop::run(&ctx, &command, &command.data.options())),
|
||||
_ => Some(CreateEmbed::new()
|
||||
.author(CreateEmbedAuthor::new("Rustendo"))
|
||||
.description("Cannot find command")
|
||||
.footer(CreateEmbedFooter::new("Error during execution"))),
|
||||
};
|
||||
|
||||
if let Some(content) = content {
|
||||
let data = CreateInteractionResponseMessage::new().content(content);
|
||||
if let Some(embed) = content {
|
||||
let data = CreateInteractionResponseMessage::new().embed(embed);
|
||||
let builder = CreateInteractionResponse::Message(data);
|
||||
if let Err(why) = command.create_response(&ctx.http, builder).await {
|
||||
println!("Cannot respond to slash command: {why}");
|
||||
|
@ -36,9 +53,9 @@ impl EventHandler for Handler {
|
|||
async fn ready(&self, ctx: Context, ready: Ready) {
|
||||
println!("{} is connected!", ready.user.name);
|
||||
|
||||
let _guild_command =
|
||||
Command::create_global_command(&ctx.http, commands::ping::register())
|
||||
.await;
|
||||
let _command = Command::create_global_command(&ctx.http, commands::info::register()).await;
|
||||
let _command = Command::create_global_command(&ctx.http, commands::stop::register()).await;
|
||||
let _command = Command::create_global_command(&ctx.http, commands::play::register()).await;
|
||||
|
||||
println!("Created all public / commands");
|
||||
}
|
||||
|
@ -55,12 +72,32 @@ async fn main() {
|
|||
");
|
||||
|
||||
|
||||
|
||||
// Load config
|
||||
let config = config::load().unwrap();
|
||||
|
||||
// Set status
|
||||
let status = OnlineStatus::DoNotDisturb;
|
||||
let activity = ActivityData::streaming("music", "https://twitch.tv/moonleaytv").unwrap();
|
||||
// Build our client.
|
||||
|
||||
let node_builder = NodeBuilder {
|
||||
hostname: config.lavalink_address,
|
||||
password: config.lavalink_password,
|
||||
user_id: UserId(config.user_id),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// let event = Events::default();
|
||||
let event = Events {
|
||||
ready: Some(lavalink_event_handler::ready_event),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// Connect to lavalink
|
||||
let lavalink_client = LavalinkClient::new(event, vec![node_builder]);
|
||||
tokio::spawn(async move {
|
||||
lavalink_client.start().await;
|
||||
});
|
||||
|
||||
// Build the client
|
||||
let mut client = Client::builder(config.discord_token, GatewayIntents::empty())
|
||||
.event_handler(Handler)
|
||||
.status(status)
|
||||
|
|
|
@ -5,7 +5,10 @@ use std::error::Error;
|
|||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct Config {
|
||||
pub discord_token: String
|
||||
pub discord_token: String,
|
||||
pub lavalink_address: String,
|
||||
pub lavalink_password: String,
|
||||
pub user_id: u64
|
||||
}
|
||||
|
||||
const CONFIG_FILE: &str = "./data/config.json";
|
||||
|
@ -22,7 +25,10 @@ pub fn load() -> Result<Config, Box<dyn Error>> {
|
|||
|
||||
fn create_empty() -> fs::File{
|
||||
let example_config = Config {
|
||||
discord_token: "paste_your_config".to_string()
|
||||
discord_token: "paste_your_token".to_string(),
|
||||
lavalink_address: "paste_your_lavalink_address".to_string(),
|
||||
lavalink_password: "paste_your_lavalink_password".to_string(),
|
||||
user_id: 1
|
||||
};
|
||||
|
||||
let mut config_file = fs::File::create(CONFIG_FILE).unwrap();
|
||||
|
|
|
@ -1 +1 @@
|
|||
pub mod config;
|
||||
pub mod config;
|
Loading…
Add table
Add a link
Reference in a new issue