diff --git a/.gitignore b/.gitignore index a1a5734..cae2d8e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ +/result /target Secrets*.toml +/temp +.tmp diff --git a/Cargo.lock b/Cargo.lock index f990004..5c085ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1118,6 +1118,8 @@ version = "0.1.0" dependencies = [ "oscuro-core", "tokio", + "tracing", + "tracing-subscriber", ] [[package]] @@ -1125,6 +1127,7 @@ name = "oscuro-core" version = "0.1.0" dependencies = [ "poise", + "rand", "serde", "serde_json", "tokio", diff --git a/Cargo.toml b/Cargo.toml index 2e5c60a..504a491 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,8 @@ edition = "2021" [dependencies] oscuro-core = { version = "0.1.0", path = "crates/oscuro-core" } tokio = { version = "1.26.0", features = ["macros", "rt-multi-thread"] } +tracing = "0.1.40" +tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } [workspace] resolver = "2" diff --git a/README.md b/README.md index fab900d..c5333b7 100644 --- a/README.md +++ b/README.md @@ -2,5 +2,4 @@ # License - **oscuro** is licensed under the [MIT License](LICENSE). diff --git a/crates/oscuro-core/Cargo.toml b/crates/oscuro-core/Cargo.toml index cde9443..3374190 100644 --- a/crates/oscuro-core/Cargo.toml +++ b/crates/oscuro-core/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dependencies] poise = "0.6.1" +rand = "0.8.5" serde = { version = "1.0.198", features = ["derive"] } serde_json = "1.0.116" tokio = { version = "1.26.0", features = ["macros", "rt-multi-thread"] } diff --git a/crates/oscuro-core/src/commands.rs b/crates/oscuro-core/src/commands.rs index bbe2f1a..96a8488 100644 --- a/crates/oscuro-core/src/commands.rs +++ b/crates/oscuro-core/src/commands.rs @@ -1,4 +1,5 @@ use poise::serenity_prelude as serenity; +use rand::Rng; use super::errors::BoxedError; use super::Context; @@ -19,3 +20,21 @@ pub async fn age( ctx.say(response).await?; Ok(()) } + +#[poise::command(slash_command, prefix_command)] +pub async fn dice(ctx: Context<'_>) -> Result<(), BoxedError> { + let number = { + let mut rng = rand::thread_rng(); + rng.gen_range(1..21) + }; + + let response = format!("{} throws {}.", ctx.author(), number); + let response = match number { + 20 => format!("{} Critical success.", response), + 1 => format!("{} Critical failure.", response), + _ => response, + }; + + ctx.say(response).await?; + Ok(()) +} diff --git a/crates/oscuro-core/src/config.rs b/crates/oscuro-core/src/config.rs index 322acd3..10b3826 100644 --- a/crates/oscuro-core/src/config.rs +++ b/crates/oscuro-core/src/config.rs @@ -33,7 +33,7 @@ impl Config { impl Default for Config { fn default() -> Self { Self { - discord_token: String::from("Bot ###"), + discord_token: String::new(), } } } diff --git a/crates/oscuro-core/src/lib.rs b/crates/oscuro-core/src/lib.rs index 11c391b..2f11dc3 100644 --- a/crates/oscuro-core/src/lib.rs +++ b/crates/oscuro-core/src/lib.rs @@ -21,7 +21,7 @@ pub async fn client(state: AppState) -> Result { let state_copy = state.clone(); let framework = poise::Framework::builder() .options(poise::FrameworkOptions { - commands: vec![commands::register(), commands::age()], + commands: vec![commands::register(), commands::age(), commands::dice()], event_handler: |ctx, event, framework, data| { Box::pin(event_handler(ctx, event, framework, data)) }, diff --git a/flake.lock b/flake.lock index 9ff60ae..0911694 100644 --- a/flake.lock +++ b/flake.lock @@ -1,17 +1,92 @@ { "nodes": { + "blobs": { + "flake": false, + "locked": { + "lastModified": 1604995301, + "narHash": "sha256-wcLzgLec6SGJA8fx1OEN1yV/Py5b+U5iyYpksUY/yLw=", + "owner": "simple-nixos-mailserver", + "repo": "blobs", + "rev": "2cccdf1ca48316f2cfd1c9a0017e8de5a7156265", + "type": "gitlab" + }, + "original": { + "owner": "simple-nixos-mailserver", + "repo": "blobs", + "type": "gitlab" + } + }, + "bonfire": { + "inputs": { + "crane": "crane", + "devenv": "devenv", + "fenix": "fenix", + "home-manager": "home-manager", + "nixgl": "nixgl", + "nixos-mailserver": "nixos-mailserver", + "nixpkgs": "nixpkgs_2", + "sops-nix": "sops-nix" + }, + "locked": { + "lastModified": 1713950784, + "narHash": "sha256-E8KH9rUYRNEajvuUhQxaqVZEj4INxgux/HbQ7NzZZ68=", + "owner": "L-Nafaryus", + "repo": "bonfire", + "rev": "5217f6d2229e246f0df4d47c1b4046559160c14f", + "type": "github" + }, + "original": { + "owner": "L-Nafaryus", + "repo": "bonfire", + "type": "github" + } + }, + "cachix": { + "inputs": { + "devenv": "devenv_2", + "flake-compat": [ + "bonfire", + "devenv", + "flake-compat" + ], + "nixpkgs": [ + "bonfire", + "devenv", + "nixpkgs" + ], + "pre-commit-hooks": [ + "bonfire", + "devenv", + "pre-commit-hooks" + ] + }, + "locked": { + "lastModified": 1712055811, + "narHash": "sha256-7FcfMm5A/f02yyzuavJe06zLa9hcMHsagE28ADcmQvk=", + "owner": "cachix", + "repo": "cachix", + "rev": "02e38da89851ec7fec3356a5c04bc8349cae0e30", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "cachix", + "type": "github" + } + }, "crane": { "inputs": { "nixpkgs": [ + "bonfire", "nixpkgs" ] }, "locked": { - "lastModified": 1703439018, - "narHash": "sha256-VT+06ft/x3eMZ1MJxWzQP3zXFGcrxGo5VR2rB7t88hs=", + "lastModified": 1713738183, + "narHash": "sha256-qd/MuLm7OfKQKyd4FAMqV4H6zYyOfef5lLzRrmXwKJM=", "owner": "ipetkov", "repo": "crane", - "rev": "afdcd41180e3dfe4dac46b5ee396e3b12ccc967a", + "rev": "f6c6a2fb1b8bd9b65d65ca9342dd0eb180a63f11", "type": "github" }, "original": { @@ -20,19 +95,80 @@ "type": "github" } }, + "devenv": { + "inputs": { + "cachix": "cachix", + "flake-compat": "flake-compat_2", + "nix": "nix_2", + "nixpkgs": [ + "bonfire", + "nixpkgs" + ], + "pre-commit-hooks": "pre-commit-hooks" + }, + "locked": { + "lastModified": 1713860250, + "narHash": "sha256-FF/a1Isk7XrhAWjSS0687YCmmm6khaBHPk9Dbsessqk=", + "owner": "cachix", + "repo": "devenv", + "rev": "09549b3a55e12f43c9ce29356ba6762c8fbd84ec", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "devenv", + "type": "github" + } + }, + "devenv_2": { + "inputs": { + "flake-compat": [ + "bonfire", + "devenv", + "cachix", + "flake-compat" + ], + "nix": "nix", + "nixpkgs": "nixpkgs", + "poetry2nix": "poetry2nix", + "pre-commit-hooks": [ + "bonfire", + "devenv", + "cachix", + "pre-commit-hooks" + ] + }, + "locked": { + "lastModified": 1708704632, + "narHash": "sha256-w+dOIW60FKMaHI1q5714CSibk99JfYxm0CzTinYWr+Q=", + "owner": "cachix", + "repo": "devenv", + "rev": "2ee4450b0f4b95a1b90f2eb5ffea98b90e48c196", + "type": "github" + }, + "original": { + "owner": "cachix", + "ref": "python-rewrite", + "repo": "devenv", + "type": "github" + } + }, "fenix": { "inputs": { "nixpkgs": [ + "bonfire", "nixpkgs" ], - "rust-analyzer-src": [] + "rust-analyzer-src": [ + "bonfire" + ] }, "locked": { - "lastModified": 1703485398, - "narHash": "sha256-eJkxehEmQjSLD/UwPCXlHxH6g41R66fY7Hw9AOSsQA8=", + "lastModified": 1713853552, + "narHash": "sha256-OOXi+9cSbst7Crah6UVxHe33O6HK91WgD2yU/p5/dqs=", "owner": "nix-community", "repo": "fenix", - "rev": "57a533b99ebe646449b71718e43ca29b550bd254", + "rev": "d596927635ddd8db224bbff6e4ccb08e42649eb5", "type": "github" }, "original": { @@ -41,13 +177,283 @@ "type": "github" } }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_2": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_3": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1689068808, + "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_3": { + "locked": { + "lastModified": 1659877975, + "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "bonfire", + "devenv", + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "bonfire", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1713818326, + "narHash": "sha256-aw3xbVPJauLk/bbrlakIYxKpeuMWzA2feGrkIpIuXd8=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "67de98ae6eed5ad6f91b1142356d71a87ba97f21", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "nix": { + "inputs": { + "flake-compat": "flake-compat", + "nixpkgs": [ + "bonfire", + "devenv", + "cachix", + "devenv", + "nixpkgs" + ], + "nixpkgs-regression": "nixpkgs-regression" + }, + "locked": { + "lastModified": 1708577783, + "narHash": "sha256-92xq7eXlxIT5zFNccLpjiP7sdQqQI30Gyui2p/PfKZM=", + "owner": "domenkozar", + "repo": "nix", + "rev": "ecd0af0c1f56de32cbad14daa1d82a132bf298f8", + "type": "github" + }, + "original": { + "owner": "domenkozar", + "ref": "devenv-2.21", + "repo": "nix", + "type": "github" + } + }, + "nix-github-actions": { + "inputs": { + "nixpkgs": [ + "bonfire", + "devenv", + "cachix", + "devenv", + "poetry2nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1688870561, + "narHash": "sha256-4UYkifnPEw1nAzqqPOTL2MvWtm3sNGw1UTYTalkTcGY=", + "owner": "nix-community", + "repo": "nix-github-actions", + "rev": "165b1650b753316aa7f1787f3005a8d2da0f5301", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nix-github-actions", + "type": "github" + } + }, + "nix_2": { + "inputs": { + "flake-compat": [ + "bonfire", + "devenv", + "flake-compat" + ], + "nixpkgs": [ + "bonfire", + "devenv", + "nixpkgs" + ], + "nixpkgs-regression": "nixpkgs-regression_2" + }, + "locked": { + "lastModified": 1712911606, + "narHash": "sha256-BGvBhepCufsjcUkXnEEXhEVjwdJAwPglCC2+bInc794=", + "owner": "domenkozar", + "repo": "nix", + "rev": "b24a9318ea3f3600c1e24b4a00691ee912d4de12", + "type": "github" + }, + "original": { + "owner": "domenkozar", + "ref": "devenv-2.21", + "repo": "nix", + "type": "github" + } + }, + "nixgl": { + "inputs": { + "flake-utils": "flake-utils_3", + "nixpkgs": [ + "bonfire", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1713543440, + "narHash": "sha256-lnzZQYG0+EXl/6NkGpyIz+FEOc/DSEG57AP1VsdeNrM=", + "owner": "guibou", + "repo": "nixGL", + "rev": "310f8e49a149e4c9ea52f1adf70cdc768ec53f8a", + "type": "github" + }, + "original": { + "owner": "guibou", + "repo": "nixGL", + "type": "github" + } + }, + "nixos-mailserver": { + "inputs": { + "blobs": "blobs", + "flake-compat": "flake-compat_3", + "nixpkgs": [ + "bonfire", + "nixpkgs" + ], + "utils": "utils" + }, + "locked": { + "lastModified": 1713012165, + "narHash": "sha256-z/soXKDnz+w4Nw0LkRaM73YqolhSmIYy6cpg1F2ps8I=", + "owner": "simple-nixos-mailserver", + "repo": "nixos-mailserver", + "rev": "9f6635a0351c190179dc6904545f950108a23dd8", + "type": "gitlab" + }, + "original": { + "owner": "simple-nixos-mailserver", + "repo": "nixos-mailserver", + "type": "gitlab" + } + }, "nixpkgs": { "locked": { - "lastModified": 1703134684, - "narHash": "sha256-SQmng1EnBFLzS7WSRyPM9HgmZP2kLJcPAz+Ug/nug6o=", + "lastModified": 1692808169, + "narHash": "sha256-x9Opq06rIiwdwGeK2Ykj69dNc2IvUH1fY55Wm7atwrE=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "d6863cbcbbb80e71cecfc03356db1cda38919523", + "rev": "9201b5ff357e781bf014d0330d18555695df7ba8", "type": "github" }, "original": { @@ -57,11 +463,230 @@ "type": "github" } }, + "nixpkgs-regression": { + "locked": { + "lastModified": 1643052045, + "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + } + }, + "nixpkgs-regression_2": { + "locked": { + "lastModified": 1643052045, + "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1710695816, + "narHash": "sha256-3Eh7fhEID17pv9ZxrPwCLfqXnYP006RKzSs0JptsN84=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "614b4613980a522ba49f0d194531beddbb7220d3", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable_2": { + "locked": { + "lastModified": 1713638189, + "narHash": "sha256-q7APLfB6FmmSMI1Su5ihW9IwntBsk2hWNXh8XtSdSIk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "74574c38577914733b4f7a775dd77d24245081dd", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "release-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1713714899, + "narHash": "sha256-+z/XjO3QJs5rLE5UOf015gdVauVRQd2vZtsFkaXBq2Y=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "6143fc5eeb9c4f00163267708e26191d1e918932", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "poetry2nix": { + "inputs": { + "flake-utils": "flake-utils", + "nix-github-actions": "nix-github-actions", + "nixpkgs": [ + "bonfire", + "devenv", + "cachix", + "devenv", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1692876271, + "narHash": "sha256-IXfZEkI0Mal5y1jr6IRWMqK8GW2/f28xJenZIPQqkY0=", + "owner": "nix-community", + "repo": "poetry2nix", + "rev": "d5006be9c2c2417dafb2e2e5034d83fabd207ee3", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "poetry2nix", + "type": "github" + } + }, + "pre-commit-hooks": { + "inputs": { + "flake-compat": [ + "bonfire", + "devenv", + "flake-compat" + ], + "flake-utils": "flake-utils_2", + "gitignore": "gitignore", + "nixpkgs": [ + "bonfire", + "devenv", + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1712897695, + "narHash": "sha256-nMirxrGteNAl9sWiOhoN5tIHyjBbVi5e2tgZUgZlK3Y=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "40e6053ecb65fcbf12863338a6dcefb3f55f1bf8", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, "root": { "inputs": { - "crane": "crane", - "fenix": "fenix", - "nixpkgs": "nixpkgs" + "bonfire": "bonfire" + } + }, + "sops-nix": { + "inputs": { + "nixpkgs": [ + "bonfire", + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable_2" + }, + "locked": { + "lastModified": 1713775152, + "narHash": "sha256-xyP8h9jLQ0AmyPy40sIwL7/D03oVpXG9YHoYJ4ecYWA=", + "owner": "Mic92", + "repo": "sops-nix", + "rev": "4371a1301c4d36cc791069d90ae522613a3a335e", + "type": "github" + }, + "original": { + "owner": "Mic92", + "repo": "sops-nix", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_3": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "utils": { + "inputs": { + "systems": "systems_3" + }, + "locked": { + "lastModified": 1709126324, + "narHash": "sha256-q6EQdSeUZOG26WelxqkmR7kArjgWCdw5sfJVHPH/7j8=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "d465f4819400de7c8d874d50b982301f28a84605", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" } } }, diff --git a/flake.nix b/flake.nix index 904809f..a4c80e4 100644 --- a/flake.nix +++ b/flake.nix @@ -1,55 +1,169 @@ { - description = "Basic rust template"; + description = "Oscuro - a fancy discord bot"; - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; - crane = { url = "github:ipetkov/crane"; inputs.nixpkgs.follows = "nixpkgs"; }; - fenix = { url = "github:nix-community/fenix"; inputs.nixpkgs.follows = "nixpkgs"; inputs.rust-analyzer-src.follows = ""; }; - }; + nixConfig = { + extra-substituters = [ "https://bonfire.cachix.org" ]; + extra-trusted-public-keys = [ "bonfire.cachix.org-1:mzAGBy/Crdf8NhKail5ciK7ZrGRbPJJobW6TwFb7WYM=" ]; + }; - outputs = inputs @ { self, nixpkgs, crane, fenix, ... }: + inputs = { + bonfire = { + url = "github:L-Nafaryus/bonfire"; + }; + }; + + outputs = { self, bonfire, ... }: let - forAllSystems = nixpkgs.lib.genAttrs [ "x86_64-linux" ]; - nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system; }); + nixpkgs = bonfire.inputs.nixpkgs; + forAllSystems = nixpkgs.lib.genAttrs [ "x86_64-linux" ]; + nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system; }); in { - packages = forAllSystems (system: { - oscuro = - let + packages = forAllSystems (system: + let pkgs = nixpkgsFor.${system}; - cranelib = crane.lib.${system}; - in - cranelib.buildPackage { - src = cranelib.cleanCargoSource (cranelib.path ./.); - strictDeps = true; + crane-lib = bonfire.inputs.crane.lib.${system}; - buildInputs = [ ]; - }; + src = pkgs.lib.cleanSourceWith { + src = ./.; + filter = path: type: (crane-lib.filterCargoSources path type); + }; - default = self.packages.${system}.oscuro; - }); + common = { + inherit src; + pname = "oscuro"; + version = "0.1.0"; + strictDeps = true; + }; - checks = forAllSystems (system: { - inherit (self.packages.${system}.oscuro); + cargoArtifacts = crane-lib.buildDepsOnly common; + in { + oscuro = crane-lib.buildPackage (common // { inherit cargoArtifacts; }); - oscuro-fmt = let cranelib = crane.lib.${system}; in - cranelib.cargoFmt { - src = cranelib.cleanCargoSource (cranelib.path ./.); - }; - }); + default = self.packages.${system}.oscuro; + }); - apps = forAllSystems (system: { - default = { - type = "app"; - program = "${self.packages.${system}.oscuro}/bin/oscuro"; + devShells = forAllSystems (system: + let + pkgs = nixpkgsFor.${system}; + bonfire-pkgs = bonfire.packages.${system}; + fenix-pkgs = bonfire.inputs.fenix.packages.${system}; + crane-lib = bonfire.inputs.crane.lib.${system}; + in { + default = pkgs.mkShell { + buildInputs = [ + fenix-pkgs.complete.toolchain + bonfire-pkgs.cargo-shuttle + ]; + }; + }); + + nixosModules = { + oscuro = { config, lib, pkgs, ... }: + with lib; + let + cfg = config.services.oscuro; + opt = options.services.oscuro; + pkg = self.packages.${pkgs.system}.oscuro; + configFile = pkgs.writeText "config.toml" '' + discord_token = "#discord_token#" + ''; + in { + options.services.oscuro = { + enable = mkEnableOption "Enables the Oscuro bot"; + + package = mkPackageOption pkgs "oscuro" {}; + + dataDir = mkOption { + type = types.path; + default = "/var/lib/oscuro"; + description = lib.mdDoc "Directory to store Oscuro files"; + }; + + discordToken = mkOption { + type = types.nullOr types.str; + default = null; + example = "Bot TOKENTOKENTOKEN"; + }; + + discordTokenFile = mkOption { + type = types.nullOr types.str; + default = null; + example = "/var/lib/secrets/oscuro/discord_token"; + }; + }; + + config = mkIf cfg.enable { + assertions = [ + { + assertion = cfg.discordToken != null || cfg.discordTokenFile != null; + message = "Discord token must be set. Use `services.oscuro.discordToken` or `services.oscuro.discordTokenFile`."; + } + ]; + + users.users.oscuro = { + description = "Oscuro bot service user"; + home = cfg.dataDir; + createHome = true; + isSystemUser = true; + group = "oscuro"; + }; + users.groups.oscuro = {}; + + systemd.services.oscuro = { + description = "Oscuro"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + serviceConfig = { + Restart = "always"; + ExecStart = "${pkg}/bin/oscuro"; + User = "oscuro"; + WorkingDirectory = cfg.dataDir; + }; + + preStart = let + runConfig = "${cfg.dataDir}/config.toml"; + replaceSecret = "${pkgs.replace-secret}/bin/replace-secret"; + in '' + cp -f '${configFile}' '${runConfig}' + chmod u+w '${runConfig}' + + ${lib.optionalString (cfg.discordTokenFile != null) '' + ${replaceSecret} '#discord_token#' '${cfg.discordTokenFile}' '${runConfig}' + ''} + ${lib.optionalString (cfg.discordToken != null) '' + sed -i 's/#discord_token#/${cfg.discordToken}/g' '${runConfig}' + ''} + + ''; + }; + }; + }; + + default = self.nixosModules.oscuro; }; - }); - devShells = forAllSystems (system: { - default = let pkgs = nixpkgsFor.${system}; in pkgs.mkShell { - nativeBuildInputs = [ fenix.packages.${system}.complete.toolchain pkgs.cargo-shuttle ]; + nixosConfigurations.oscuro = nixpkgs.lib.nixosSystem { + description = "Oscuro"; + system = "x86_64-linux"; + modules = [ + self.nixosModules.oscuro + ({ pkgs, ... }: { + boot.isContainer = true; + + networking.hostName = "oscuro"; + networking.useDHCP = false; + + services.oscuro = { + enable = true; + discordToken = null; + }; + + system.stateVersion = "24.05"; + }) + ]; }; - }); }; } diff --git a/info.md b/info.md deleted file mode 100644 index 086084e..0000000 --- a/info.md +++ /dev/null @@ -1,16 +0,0 @@ -# Serenity Hello World Bot with Shuttle - -In this example we will deploy a Serenity bot with Shuttle that responds to the `!hello` command with `world!`. To run this bot we need a valid Discord Token. To get started log in to the [Discord developer portal](https://discord.com/developers/applications). - -1. Click the New Application button, name your application and click Create. -2. Navigate to the Bot tab in the lefthand menu, and add a new bot. -3. On the bot page click the Reset Token button to reveal your token. Put this token in your `Secrets.toml`. It's very important that you don't reveal your token to anyone, as it can be abused. Create a `.gitignore` file to omit your `Secrets.toml` from version control. -4. For the sake of this example, you also need to scroll down on the bot page to the Message Content Intent section and enable that option. - -To add the bot to a server we need to create an invite link. - -1. On your bot's application page, open the OAuth2 page via the lefthand panel. -2. Go to the URL Generator via the lefthand panel, and select the `bot` scope as well as the `Send Messages` permission in the Bot Permissions section. -3. Copy the URL, open it in your browser and select a Discord server you wish to invite the bot to. - -For more information please refer to the [Discord docs](https://discord.com/developers/docs/getting-started) as well as the [Serenity repo](https://github.com/serenity-rs/serenity) for more examples. diff --git a/src/main.rs b/src/main.rs index fddc926..6c9544b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,18 +2,33 @@ use oscuro_core::{client, config::Config, AppState}; use std::env; #[tokio::main] -async fn main() { - let token = env::var("DISCORD_TOKEN").expect("Variable 'DISCORD_TOKEN' must be set"); - let state = AppState { - config: Config { - discord_token: token, - }, +async fn main() -> Result<(), Box> { + tracing_subscriber::fmt() + .with_target(false) + .compact() + .init(); + + let mut config = match Config::open(Config::data_dir()?.join("config.toml").as_path()) { + Ok(config) => config, + Err(_) => Config::default(), }; + if let Ok(token) = env::var("DISCORD_TOKEN") { + config.discord_token = token; + }; + + if config.discord_token.is_empty() { + tracing::error!("Missing discord token"); + } + + let state = AppState { config }; + client(state) .await .expect("Failed to create client") .start() .await .expect("Failed to start client"); + + Ok(()) }