Elnu 6 months ago
parent 547e15acd5
commit 54de45b58b

@ -0,0 +1,2 @@
DISCORD_TOKEN=
PREFIX="-e "

1
.gitignore vendored

@ -1,3 +1,4 @@
/target
.direnv
result
.env

2827
Cargo.lock generated

File diff suppressed because it is too large Load Diff

@ -6,3 +6,9 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
dotenv = "0.15.0"
lazy_static = "1.4.0"
poise = "0.5.7"
regex = "1.10.2"
tokio = { version = "1.33.0", features = ["macros", "signal", "rt-multi-thread"] }
tts_rust = "0.3.5"

@ -1,3 +1,112 @@
fn main() {
println!("Hello, world!");
use std::{env, sync::{Mutex}};
use poise::{serenity_prelude::{self as serenity, GatewayIntents}, Event, command};
use regex::Regex;
use tts_rust::{ tts::GTTSClient, languages::Languages };
use lazy_static::lazy_static;
type Error = Box<dyn std::error::Error + Send + Sync>;
type Context<'a> = poise::Context<'a, Data, Error>;
// type PrefixContext<'a> = poise::PrefixContext<'a, Data, Error>;
// User data, which is stored and accessible in all command invocations
pub struct Data {
dnd: Mutex<bool>,
}
lazy_static! {
static ref NARRATOR: GTTSClient = GTTSClient {
volume: 1.0,
language: Languages::English,
tld: "com",
};
}
async fn event_handler(
ctx: &serenity::Context,
event: &Event<'_>,
_framework: poise::FrameworkContext<'_, Data, Error>,
data: &Data,
) -> Result<(), Error> {
match event {
Event::Ready { data_about_bot } => {
println!("Logged in as {}", data_about_bot.user.name);
}
Event::Message { new_message } => {
const PREFIX: &str = "tell elnu";
lazy_static! {
static ref RE: Regex = Regex::new(r"<a?:([^:]+):\d+>").unwrap();
};
if new_message.content.to_lowercase().starts_with(PREFIX) {
if *data.dnd.lock().unwrap() {
new_message.react(&ctx.http, '💤').await?;
} else {
println!("{}: {}", new_message.author.name, new_message.content);
new_message.react(&ctx.http, '✅').await?;
NARRATOR.speak(&format!("{} says {}", new_message.author.name, RE.replace_all(&new_message.content[PREFIX.len()..], "$1"))).unwrap();
}
}
}
_ => {}
}
Ok(())
}
#[poise::command(prefix_command)]
async fn register(ctx: Context<'_>) -> Result<(), Error> {
poise::builtins::register_application_commands_buttons(ctx).await?;
Ok(())
}
#[command(slash_command, owners_only)]
async fn toggle_dnd(ctx: Context<'_>) -> Result<(), Error> {
let dnd = {
// Put into closure so Mutex isn't locked across an await point
let mut dnd = ctx.data().dnd.lock().unwrap();
*dnd = !*dnd;
*dnd
};
ctx.reply(if dnd {
"TTS status set to away. 💤"
} else {
"TTS status set to active. ✅"
}).await?;
Ok(())
}
#[tokio::main]
async fn main() {
// This will load the environment variables located at `./.env`, relative to
// the CWD. See `./.env.example` for an example on how to structure this.
dotenv::dotenv().expect("Failed to load .env file");
// Initialize the logger to use environment variables.
//
// In this case, a good default is setting the environment variable
// `RUST_LOG` to `debug`.
let framework = poise::Framework::builder()
.options(poise::FrameworkOptions {
commands: vec![
register(),
toggle_dnd(),
],
event_handler: |_ctx, event, _framework, _data| {
Box::pin(event_handler(_ctx, event, _framework, _data))
},
prefix_options: poise::PrefixFrameworkOptions {
prefix: Some(env::var("PREFIX").expect("Expected a prefix in the environment")),
..Default::default()
},
..Default::default()
})
.token(std::env::var("DISCORD_TOKEN").expect("Expected a token in the environment"))
.intents(
GatewayIntents::GUILD_MESSAGES
| GatewayIntents::DIRECT_MESSAGES
| GatewayIntents::MESSAGE_CONTENT
| GatewayIntents::GUILDS,
)
.setup(move |_ctx, _ready, _framework| Box::pin(async move { Result::<Data, Error>::Ok(Data { dnd: Mutex::new(false) }) }));
framework.run().await.unwrap();
}

@ -34,8 +34,8 @@ Some utility commands:
};
rustSettings = with pkgs; {
src = ./.;
#nativeBuildInputs = [ pkg-config ];
#buildInputs = [ openssl ];
nativeBuildInputs = [ pkg-config ];
buildInputs = [ openssl alsa-lib ];
cargoHash = nixpkgs.lib.fakeHash;
};
meta = with nixpkgs.lib; {

Loading…
Cancel
Save