main commit

This commit is contained in:
2026-05-11 19:16:21 +02:00
commit fee9cf488f
9 changed files with 3662 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
/target
test-database.db
.env
Generated
+3474
View File
File diff suppressed because it is too large Load Diff
+12
View File
@@ -0,0 +1,12 @@
[package]
name = "late-worker"
version = "0.1.0"
edition = "2024"
[dependencies]
dotenvy = "0.15.7"
poise = "0.6.2"
serenity = { version = "0.12.5", features = ["cache"] }
sqlx = { version = "0.8.6", features = ["any", "mysql", "runtime-tokio", "sqlite"] }
tokio = { version = "1.52.3", features = ["macros", "rt-multi-thread"] }
tracing-subscriber = "0.3.23"
+5
View File
@@ -0,0 +1,5 @@
// generated by `sqlx migrate build-script`
fn main() {
// trigger recompilation when a new migration is added
println!("cargo:rerun-if-changed=migrations");
}
+29
View File
@@ -0,0 +1,29 @@
-- Add migration script here
create TABLE `Guild` (
`id` INT UNSIGNED NOT NULL PRIMARY KEY
);
create TABLE `User` (
`id` INT UNSIGNED NOT NULL PRIMARY KEY
);
create TABLE `Channel` (
`id` INT UNSIGNED NOT NULL PRIMARY KEY,
`guild_id` INT UNSIGNED NOT NULL
);
create TABLE `Logs` (
`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`guild_id` INT UNSIGNED NOT NULL,
`channel_id` INT UNSIGNED NOT NULL,
`message_create` BOOLEAN DEFAULT FALSE,
`message_update` BOOLEAN DEFAULT FALSE,
`message_delete` BOOLEAN DEFAULT FALSE,
`voice_join` BOOLEAN DEFAULT FALSE,
`voice_quit` BOOLEAN DEFAULT FALSE
);
create TABLE `Auto_Channel` (
`channel_id` INT UNSIGNED NOT NULL PRIMARY KEY,
`category_id` INT UNSIGNED
)
+20
View File
@@ -0,0 +1,20 @@
use crate::{Context, Error};
/// Show this help menu
#[poise::command(slash_command)]
pub async fn help(
ctx: Context<'_>,
#[description = "Specific command to show help about"]
#[autocomplete = "poise::builtins::autocomplete_command"]
command: Option<String>,
) -> Result<(), Error> {
poise::builtins::help(
ctx,
command.as_deref(),
poise::builtins::HelpConfiguration {
..Default::default()
},
)
.await?;
Ok(())
}
+27
View File
@@ -0,0 +1,27 @@
use std::env::var;
use sqlx::any::install_default_drivers;
use sqlx::migrate::Migrator;
use sqlx::sqlite::SqlitePoolOptions;
use sqlx::{Error, SqlitePool};
static MIGRATOR: Migrator = sqlx::migrate!();
pub struct DataBase {
pool: SqlitePool,
}
impl DataBase {
pub async fn setup_database() -> Result<Self, Error> {
install_default_drivers();
let url = var("DATABASE_URL")
.expect("Missing `DATABASE_URL` env var, see README for more information.");
let pool = SqlitePoolOptions::new().connect(&url).await?;
MIGRATOR.run(&pool).await?;
Ok(Self { pool: pool })
}
}
+18
View File
@@ -0,0 +1,18 @@
use poise::serenity_prelude as serenity;
use crate::{Data, Error};
async fn event_handler(
ctx: &serenity::Context,
event: &serenity::FullEvent,
_framework: poise::FrameworkContext<'_, Data, Error>,
data: &Data,
) -> Result<(), Error> {
match event {
serenity::FullEvent::Ready { data_about_bot, .. } => {
println!("Logged in as {}", data_about_bot.user.name);
}
_ => {}
}
Ok(())
}
+74
View File
@@ -0,0 +1,74 @@
mod commands;
mod database;
mod events;
use dotenvy::dotenv;
use poise::serenity_prelude as serenity;
use std::env::var;
// Types used by all command functions
type Error = Box<dyn std::error::Error + Send + Sync>;
type Context<'a> = poise::Context<'a, Data, Error>;
// Custom user data passed to all command functions
pub struct Data {}
async fn on_error(error: poise::FrameworkError<'_, Data, Error>) {
// This is our custom error handler
// They are many errors that can occur, so we only handle the ones we want to customize
// and forward the rest to the default handler
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)
}
}
}
}
#[tokio::main]
async fn main() {
tracing_subscriber::fmt::init();
dotenv().ok();
let database = database::DataBase::setup_database()
.await
.expect("Failed setup the database");
// FrameworkOptions contains all of poise's configuration option in one struct
// Every option can be omitted to use its default value
let options = poise::FrameworkOptions {
commands: vec![commands::help()],
// The global error handler for all error cases that may occur
on_error: |error| Box::pin(on_error(error)),
..Default::default()
};
let framework = poise::Framework::builder()
.setup(move |ctx, ready, framework| {
Box::pin(async move {
println!("Logged in as {}", ready.user.name);
poise::builtins::register_globally(ctx, &framework.options().commands).await?;
Ok(Data {})
})
})
.options(options)
.build();
let token = var("DISCORD_TOKEN")
.expect("Missing `DISCORD_TOKEN` env var, see README for more information.");
let intents =
serenity::GatewayIntents::non_privileged() | serenity::GatewayIntents::MESSAGE_CONTENT;
let client = serenity::ClientBuilder::new(token, intents)
.framework(framework)
.await;
client.unwrap().start().await.unwrap()
}