2025-01-26 20:45:24 +00:00
|
|
|
use std::collections::HashMap;
|
2024-10-06 12:02:24 +00:00
|
|
|
use std::future::Future;
|
|
|
|
use std::pin::Pin;
|
|
|
|
use std::sync::Arc;
|
|
|
|
use std::time::Duration;
|
|
|
|
use std::error;
|
|
|
|
use std::env;
|
|
|
|
|
2023-07-05 09:06:04 +00:00
|
|
|
use serenity::async_trait;
|
2025-01-26 20:45:24 +00:00
|
|
|
use serenity::futures::lock::Mutex;
|
2024-02-16 20:54:07 +00:00
|
|
|
use serenity::prelude::GatewayIntents;
|
2024-02-14 12:22:29 +00:00
|
|
|
use serenity::client::Context;
|
2024-02-16 20:54:07 +00:00
|
|
|
use serenity::model::gateway::Ready;
|
2024-10-06 14:54:08 +00:00
|
|
|
use serenity::all::{EventHandler, Message};
|
2024-02-16 20:54:07 +00:00
|
|
|
use serenity::Client;
|
2024-02-14 12:22:29 +00:00
|
|
|
|
2025-01-09 17:57:42 +00:00
|
|
|
use reqwest::Client as HttpClient;
|
|
|
|
|
2024-10-06 12:02:24 +00:00
|
|
|
use dotenv::dotenv;
|
|
|
|
|
2024-12-09 14:40:46 +00:00
|
|
|
use songbird::SerenityInit;
|
2024-02-16 20:54:07 +00:00
|
|
|
use tokio_cron_scheduler::{JobScheduler, Job};
|
2024-02-14 12:22:29 +00:00
|
|
|
|
2025-01-26 20:45:24 +00:00
|
|
|
use radiobrowser::RadioBrowserAPI;
|
|
|
|
|
2023-07-15 09:18:08 +00:00
|
|
|
mod message_handler;
|
|
|
|
use message_handler::handle;
|
|
|
|
|
|
|
|
mod commands;
|
2025-01-24 20:52:13 +00:00
|
|
|
mod utils;
|
2024-02-14 12:22:29 +00:00
|
|
|
|
2023-09-23 19:15:19 +00:00
|
|
|
mod other;
|
2024-02-14 12:22:29 +00:00
|
|
|
use other::notice;
|
2023-07-05 09:06:04 +00:00
|
|
|
|
2024-10-03 20:53:30 +00:00
|
|
|
mod types;
|
2025-01-09 17:57:42 +00:00
|
|
|
use types::{Data, Error};
|
2024-10-03 20:53:30 +00:00
|
|
|
|
2023-07-05 09:06:04 +00:00
|
|
|
struct Handler;
|
|
|
|
|
2025-01-09 17:57:42 +00:00
|
|
|
async fn on_error(error: poise::FrameworkError<'_, Data, Error>) {
|
2024-10-03 20:53:30 +00:00
|
|
|
match error {
|
|
|
|
poise::FrameworkError::Setup { error, .. } => panic!("Failed to start bot: {:?}", error),
|
|
|
|
poise::FrameworkError::Command { error, ctx, .. } => {
|
|
|
|
println!("Error in command `{}`: {:?}", ctx.command().name, error,);
|
|
|
|
}
|
|
|
|
error => {
|
|
|
|
if let Err(e) = poise::builtins::on_error(error).await {
|
|
|
|
println!("Error while handling error: {}", e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-05 09:06:04 +00:00
|
|
|
#[async_trait]
|
|
|
|
impl EventHandler for Handler {
|
|
|
|
async fn message(&self, ctx: Context, msg: Message) {
|
2023-07-15 09:18:08 +00:00
|
|
|
handle(ctx, msg).await;
|
2023-07-05 09:06:04 +00:00
|
|
|
}
|
|
|
|
|
2023-07-07 08:55:59 +00:00
|
|
|
async fn ready(&self, ctx: Context, ready: Ready) {
|
2025-01-13 17:14:41 +00:00
|
|
|
println!("{} v3.3.1 is connected!", ready.user.name);
|
2024-02-14 12:22:29 +00:00
|
|
|
|
2024-02-15 19:27:52 +00:00
|
|
|
#[cfg(feature="RELEASE")] {
|
2025-01-24 20:52:13 +00:00
|
|
|
use utils::debug::hello;
|
2024-12-17 14:28:52 +00:00
|
|
|
let _ = hello(ctx.http.clone()).await;
|
2024-02-15 19:27:52 +00:00
|
|
|
}
|
2024-02-18 11:14:02 +00:00
|
|
|
|
2024-02-16 20:54:07 +00:00
|
|
|
let sched = JobScheduler::new().await.unwrap();
|
|
|
|
|
|
|
|
let job_closure = move |_, _| -> Pin<Box<dyn Future<Output = ()> + Send>> {
|
|
|
|
let ctx_clone = ctx.clone();
|
|
|
|
Box::pin( async move {
|
|
|
|
notice::notice_wrapper(ctx_clone).await;
|
|
|
|
})
|
|
|
|
};
|
|
|
|
|
|
|
|
sched.add(Job::new_async("0 0 13 * * *", job_closure).expect("Cron job not set up correctly")).await.unwrap();
|
|
|
|
sched.start().await.unwrap();
|
2023-07-05 09:06:04 +00:00
|
|
|
}
|
|
|
|
}
|
2023-07-07 11:44:07 +00:00
|
|
|
|
2023-07-05 09:06:04 +00:00
|
|
|
#[tokio::main]
|
2023-07-07 10:16:25 +00:00
|
|
|
async fn main() -> anyhow::Result<()> {
|
|
|
|
use anyhow::Context;
|
2024-02-15 19:27:52 +00:00
|
|
|
|
2024-10-06 12:02:24 +00:00
|
|
|
dotenv().ok();
|
|
|
|
|
2024-10-03 20:53:30 +00:00
|
|
|
// create poise framework for registering commands
|
2025-01-09 17:57:42 +00:00
|
|
|
let options: poise::FrameworkOptions<Data, Box<dyn error::Error + Send + Sync>> = poise::FrameworkOptions {
|
2024-10-06 14:54:08 +00:00
|
|
|
commands: vec![
|
|
|
|
commands::say(),
|
2024-12-09 14:40:46 +00:00
|
|
|
commands::hug(),
|
2025-01-09 17:57:42 +00:00
|
|
|
// commands::player::play_local(),
|
|
|
|
commands::radio::radio(),
|
2025-01-24 20:52:13 +00:00
|
|
|
commands::general_player::play(),
|
|
|
|
commands::player_common::disconnect(),
|
2025-01-26 22:47:57 +00:00
|
|
|
commands::player_common::playing(),
|
|
|
|
commands::help(),
|
2024-10-06 14:54:08 +00:00
|
|
|
],
|
2024-10-03 20:53:30 +00:00
|
|
|
prefix_options: poise::PrefixFrameworkOptions {
|
|
|
|
prefix: Some("/".into()),
|
|
|
|
edit_tracker: Some(Arc::new(poise::EditTracker::for_timespan(
|
|
|
|
Duration::from_secs(3600),
|
|
|
|
))),
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
on_error: |err| Box::pin(on_error(err)),
|
|
|
|
command_check: Some(|ctx| {
|
|
|
|
Box::pin(async move {
|
|
|
|
return Ok(!ctx.author().bot)
|
|
|
|
})
|
|
|
|
}),
|
|
|
|
..Default::default()
|
|
|
|
};
|
|
|
|
|
2024-10-06 14:54:08 +00:00
|
|
|
|
2024-10-03 20:53:30 +00:00
|
|
|
let framework = poise::Framework::builder()
|
2024-10-06 14:54:08 +00:00
|
|
|
.setup(move |ctx, _ready, framework| {
|
|
|
|
Box::pin(async move {
|
2024-12-09 14:40:46 +00:00
|
|
|
|
2024-10-06 14:54:08 +00:00
|
|
|
#[cfg(feature="GUILD_COMMAND")] {
|
2024-12-09 14:40:46 +00:00
|
|
|
use poise::samples::register_in_guild;
|
|
|
|
use serenity::all::GuildId;
|
|
|
|
|
2024-10-06 14:54:08 +00:00
|
|
|
let debug_guild_id = env::var("DEBUG_GUILD_ID")
|
|
|
|
.context("DEBUG_GUILD_ID not found in env")?
|
|
|
|
.parse::<u64>().unwrap();
|
2024-12-09 14:40:46 +00:00
|
|
|
|
|
|
|
register_in_guild(ctx, &framework.options().commands, GuildId::new(debug_guild_id)).await?;
|
2024-10-06 14:54:08 +00:00
|
|
|
}
|
2024-12-17 14:28:52 +00:00
|
|
|
|
2024-10-06 14:54:08 +00:00
|
|
|
#[cfg(not(feature="GUILD_COMMAND"))] {
|
2024-12-09 14:40:46 +00:00
|
|
|
use poise::samples::register_globally;
|
2024-10-06 14:54:08 +00:00
|
|
|
register_globally(ctx, &framework.options().commands).await?;
|
|
|
|
}
|
2024-12-17 14:28:52 +00:00
|
|
|
|
2025-01-24 20:52:13 +00:00
|
|
|
|
2025-01-09 17:57:42 +00:00
|
|
|
Ok(Data {
|
2025-01-24 20:52:13 +00:00
|
|
|
http_client: HttpClient::new(),
|
2025-01-26 20:45:24 +00:00
|
|
|
radio_browser: RadioBrowserAPI::new().await?,
|
|
|
|
playing_info: Mutex::new(HashMap::new())
|
2025-01-09 17:57:42 +00:00
|
|
|
})
|
2024-10-03 20:53:30 +00:00
|
|
|
})
|
|
|
|
})
|
|
|
|
.options(options)
|
|
|
|
.build();
|
|
|
|
|
2024-02-14 12:22:29 +00:00
|
|
|
let token_str = "TOKEN";
|
2024-10-03 20:53:30 +00:00
|
|
|
|
2024-02-14 12:22:29 +00:00
|
|
|
#[cfg(feature="DEBUG")]
|
|
|
|
let token_str = "DEBUGTOKEN";
|
|
|
|
|
2024-10-06 12:02:24 +00:00
|
|
|
let token = env::var(token_str).context("TOKEN not found in env")?;
|
2024-02-14 12:22:29 +00:00
|
|
|
|
2024-12-17 14:28:52 +00:00
|
|
|
let intents = GatewayIntents::GUILDS
|
|
|
|
| GatewayIntents::GUILD_MESSAGES
|
2024-12-09 14:40:46 +00:00
|
|
|
| GatewayIntents::MESSAGE_CONTENT
|
|
|
|
| GatewayIntents::GUILD_VOICE_STATES
|
|
|
|
| GatewayIntents::GUILD_MESSAGE_REACTIONS
|
|
|
|
| GatewayIntents::GUILD_MESSAGE_TYPING;
|
2023-07-14 14:41:16 +00:00
|
|
|
|
2023-07-07 08:55:59 +00:00
|
|
|
let mut client = Client::builder(&token, intents)
|
2023-07-07 10:16:25 +00:00
|
|
|
.event_handler(Handler)
|
2024-10-03 20:53:30 +00:00
|
|
|
.framework(framework)
|
2024-12-09 14:40:46 +00:00
|
|
|
.register_songbird()
|
2023-07-07 10:16:25 +00:00
|
|
|
.await
|
|
|
|
.context("Failed to build client")?;
|
2023-07-14 14:41:16 +00:00
|
|
|
|
2023-07-07 10:16:25 +00:00
|
|
|
client.start().await?;
|
|
|
|
Ok(())
|
2023-07-05 09:06:04 +00:00
|
|
|
}
|