Compare commits

..

1 Commits

Author SHA1 Message Date
bluepython508
99e5a44e40 Add tool to remove embeds for clocktower.live links 2025-12-28 23:12:30 +00:00
6 changed files with 752 additions and 1365 deletions

4
.envrc
View File

@@ -1,4 +1,4 @@
use flake use flake
export DISCORD_TOKEN_FILE=./token export DISCORD_TOKEN_FILE=./token-prod
export DB_FILE=db.sqlite export DB_FILE=db-prod.sqlite

1985
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -10,8 +10,8 @@ color-eyre = "0.6.3"
eyre = "0.6.12" eyre = "0.6.12"
futures = "0.3.31" futures = "0.3.31"
poise = "0.6.1" poise = "0.6.1"
rand = "0.10.0" rand = "0.8.5"
rusqlite = { version = "0.38.0", features = ["rusqlite-macros"] } rusqlite = { version = "0.32.1", features = ["rusqlite-macros"] }
serenity = "0.12.2" serenity = "0.12.2"
tokio = { version = "1.41.0", features = ["rt", "net"] } tokio = { version = "1.41.0", features = ["rt", "net"] }
tracing = "0.1.41" tracing = "0.1.41"

78
flake.lock generated
View File

@@ -1,12 +1,15 @@
{ {
"nodes": { "nodes": {
"crane": { "crane": {
"inputs": {
"nixpkgs": "nixpkgs"
},
"locked": { "locked": {
"lastModified": 1771438068, "lastModified": 1714864355,
"narHash": "sha256-nGBbXvEZVe/egCPVPFcu89RFtd8Rf6J+4RFoVCFec0A=", "narHash": "sha256-uXNW6bapWFfkYIkK1EagydSrFMqycOYEDSq75GmUpjk=",
"owner": "ipetkov", "owner": "ipetkov",
"repo": "crane", "repo": "crane",
"rev": "b5090e53e9d68c523a4bb9ad42b4737ee6747597", "rev": "442a7a6152f49b907e73206dc8e1f46a61e8e873",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -23,11 +26,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1771493599, "lastModified": 1715269385,
"narHash": "sha256-kwfV7N65lx07pSTnLtK5PqxkrqauhYHswePAgHd2J1M=", "narHash": "sha256-97UnOLbYWqBP2RY6GtMf49SoVrYiYd3EEm6phWBjKv8=",
"owner": "bluepython508", "owner": "bluepython508",
"repo": "crane-flake-parts", "repo": "crane-flake-parts",
"rev": "260ca5837e562c25b0a1ba0504fcfe953dc5b680", "rev": "abd7ab48488e81617740eeb4eeefc3be2e4a6b7f",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -41,11 +44,11 @@
"nixpkgs-lib": "nixpkgs-lib" "nixpkgs-lib": "nixpkgs-lib"
}, },
"locked": { "locked": {
"lastModified": 1769996383, "lastModified": 1730504689,
"narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=", "narHash": "sha256-hgmguH29K2fvs9szpq2r3pz2/8cJd2LPS+b4tfNFCwE=",
"owner": "hercules-ci", "owner": "hercules-ci",
"repo": "flake-parts", "repo": "flake-parts",
"rev": "57928607ea566b5db3ad13af0e57e921e6b12381", "rev": "506278e768c2a08bec68eb62932193e341f55c90",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -56,11 +59,39 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1771369470, "lastModified": 1714656196,
"narHash": "sha256-0NBlEBKkN3lufyvFegY4TYv5mCNHbi5OmBDrzihbBMQ=", "narHash": "sha256-kjQkA98lMcsom6Gbhw8SYzmwrSo+2nruiTcTZp5jK7o=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "0182a361324364ae3f436a63005877674cf45efb", "rev": "94035b482d181af0a0f8f77823a790b256b7c3cc",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1730504152,
"narHash": "sha256-lXvH/vOfb4aGYyvFmZK/HlsNsr/0CVWlwYvo2rxJk3s=",
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/cc2f28000298e1269cea6612cd06ec9979dd5d7f.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/cc2f28000298e1269cea6612cd06ec9979dd5d7f.tar.gz"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1730200266,
"narHash": "sha256-l253w0XMT8nWHGXuXqyiIC/bMvh1VRszGXgdpQlfhvU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "807e9154dcb16384b1b765ebe9cd2bba2ac287fd",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -70,26 +101,11 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs-lib": {
"locked": {
"lastModified": 1769909678,
"narHash": "sha256-cBEymOf4/o3FD5AZnzC3J9hLbiZ+QDT/KDuyHXVJOpM=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "72716169fe93074c333e8d0173151350670b824c",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github"
}
},
"root": { "root": {
"inputs": { "inputs": {
"crane-flake-parts": "crane-flake-parts", "crane-flake-parts": "crane-flake-parts",
"flake-parts": "flake-parts", "flake-parts": "flake-parts",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs_2",
"rust-overlay": "rust-overlay" "rust-overlay": "rust-overlay"
} }
}, },
@@ -100,11 +116,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1771470520, "lastModified": 1730514457,
"narHash": "sha256-PvytHcaYN5cPUll7FB70mXv1rRsIBRmu47fFfq3haxA=", "narHash": "sha256-cjFX208s9pyaOfMvF9xI6WyafyXINqdhMF7b1bMQpLI=",
"owner": "oxalica", "owner": "oxalica",
"repo": "rust-overlay", "repo": "rust-overlay",
"rev": "a1d4cc1f264c45d3745af0d2ca5e59d460e58777", "rev": "1ff38ca26eb31858e4dfe7fe738b6b3ce5d74922",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@@ -37,7 +37,7 @@
config, config,
... ...
}: let }: let
pkg = self.packages.${pkgs.stdenv.hostPlatform.system}.default; pkg = self.packages.${pkgs.system}.default;
cfg = config.bluepython508.botc-mover; cfg = config.bluepython508.botc-mover;
in { in {
options.bluepython508.botc-mover = with lib; { options.bluepython508.botc-mover = with lib; {

View File

@@ -1,4 +1,4 @@
use std::{io, mem, path::Path, time::Duration}; use std::{io, path::Path};
use ::serenity::all::{ChannelId, EditMessage, GuildId, Mentionable, UserId}; use ::serenity::all::{ChannelId, EditMessage, GuildId, Mentionable, UserId};
use eyre::{Context as _, Error, OptionExt, Result}; use eyre::{Context as _, Error, OptionExt, Result};
@@ -143,13 +143,11 @@ async fn spread(
.ok_or_eyre("This bot only works in servers")?; .ok_or_eyre("This bot only works in servers")?;
let mut to = channel_children(&ctx, to).await?; let mut to = channel_children(&ctx, to).await?;
let mut users = from.members(ctx)?; let mut users = from.members(ctx)?;
{ users.shuffle(&mut rand::thread_rng());
let mut rng = rand::rng();
users.shuffle(&mut rng); to.retain(|x| x.members(ctx).is_ok_and(|x| x.is_empty()));
to.shuffle(&mut rand::thread_rng());
to.retain(|x| x.members(ctx).is_ok_and(|x| x.is_empty()));
to.shuffle(&mut rng);
}
move_users( move_users(
ctx, ctx,
guild, guild,
@@ -394,17 +392,12 @@ async fn register_commands(
} }
#[tracing::instrument(skip(ctx))] #[tracing::instrument(skip(ctx))]
async fn handle_message( async fn handle_message(ctx: impl AsRef<serenity::Http>, message: &serenity::Message) -> Result<()> {
ctx: impl AsRef<serenity::Http>, for embed in &message.embeds {
message: &serenity::Message, if embed.url.as_ref().is_some_and(|url| url.contains("https://clocktower.live")) {
) -> Result<()> { let mut message = message.clone();
tracing::info!("Got message: {}", message.content); message.edit(&ctx.as_ref(), EditMessage::new().suppress_embeds(true)).await?;
if message.content.contains("https://clocktower.live") { }
let mut message = message.clone();
tokio::time::sleep(Duration::from_secs(2)).await;
message
.edit(&ctx.as_ref(), EditMessage::new().suppress_embeds(true))
.await?;
} }
Ok(()) Ok(())
} }
@@ -416,13 +409,8 @@ async fn on_event(
_: &Data, _: &Data,
) -> Result<()> { ) -> Result<()> {
match event { match event {
serenity::FullEvent::GuildCreate { guild, is_new: _ } => { serenity::FullEvent::GuildCreate { guild, is_new: _ } => register_commands(ctx, framework.options, guild.id).await?,
register_commands(ctx, framework.options, guild.id).await? serenity::FullEvent::Message { new_message: msg } | serenity::FullEvent::MessageUpdate { new: Some(msg), .. } => handle_message(ctx, msg).await?,
}
serenity::FullEvent::Message { new_message: msg }
| serenity::FullEvent::MessageUpdate { new: Some(msg), .. } => {
handle_message(ctx, msg).await?
}
_ => {} _ => {}
} }
Ok(()) Ok(())
@@ -448,10 +436,8 @@ async fn main() -> Result<()> {
) )
.wrap_err("A Discord token is required")?; .wrap_err("A Discord token is required")?;
let dbfile = std::env::var_os("DB_FILE").ok_or_eyre("A database file is required")?; let dbfile = std::env::var_os("DB_FILE").ok_or_eyre("A database file is required")?;
let intents = serenity::GatewayIntents::non_privileged() let intents =
| serenity::GatewayIntents::GUILD_MEMBERS serenity::GatewayIntents::non_privileged() | serenity::GatewayIntents::GUILD_MEMBERS | serenity::GatewayIntents::GUILD_MESSAGES;
| serenity::GatewayIntents::GUILD_MESSAGES
| serenity::GatewayIntents::MESSAGE_CONTENT;
let framework = poise::Framework::builder() let framework = poise::Framework::builder()
.options(poise::FrameworkOptions { .options(poise::FrameworkOptions {