use inbox::*; use itertools::Itertools; use lazy_static::lazy_static; use serenity::client::Client; use serenity::framework::standard::{ macros::{command, group}, CommandError, CommandResult, StandardFramework, }; use serenity::model::{ channel::Message, id::{ChannelId, GuildId}, prelude::User, }; use serenity::prelude::*; use std::fs::File; use std::io::{self, BufRead, BufReader}; use time::Duration; mod inbox; const APPLICATION_NAME: &str = "didgeridoo"; lazy_static! { static ref INBOX: Inbox = Inbox(redis::Client::open("redis://127.0.0.1/").unwrap()); } #[group] #[commands(name, message, question, inbox)] struct Fluff; struct Handler; impl EventHandler for Handler { fn guild_ban_addition(&self, ctx: Context, guild_id: GuildId, _: User) { if guild_id == 427456811973738498 { if let Err(e) = ChannelId(562731470423064587).say(&ctx, "Dies ist eine flauschige Diktatur!") { eprintln!("Couldn’t send message because {:?}", e); } } } } fn read_token() -> io::Result { let reader = BufReader::new(File::open("secret")?); reader.lines().next().unwrap() } fn main() { let mut client = Client::new(&read_token().expect("no secret file"), Handler) .expect("Error creating client"); client.with_framework( StandardFramework::new() .configure(|c| c.prefix("!")) .group(&FLUFF_GROUP), ); INBOX.count_messages("test"); // initialize the lazy static so we know if redis is unavailable if let Err(why) = client.start() { println!("An error occurred while running the client: {:?}", why); } } #[command] fn name(ctx: &mut Context, msg: &Message) -> CommandResult { if let Some((_, name)) = msg.content.split_once(' ') { let (name, adjustment) = name.split_once(" -").unwrap_or((name, "0")); let adjustment = adjustment.strip_suffix("h").unwrap_or(adjustment); msg.guild(&ctx) .unwrap() .read() .edit_member(&ctx, msg.author.id, |m| m.nickname(name))?; let now = time::OffsetDateTime::now_utc() - adjustment .parse::() .map(|a| (a * 3600.0) as i64) .map(Duration::seconds) .ok() .unwrap_or_else(Duration::zero); println!( "{},{},{},{},{}", now.format("%d.%m.%Y %H:%M"), name, now.format("%y%m"), msg.author.id, now.unix_timestamp() ); } else { return Err(CommandError(String::from("Please specify a new name."))); } Ok(()) } #[command] fn message(ctx: &mut Context, msg: &Message) -> CommandResult { InboxMessage::parse(&msg.content, msg.author.id) .ok_or_else(|| { String::from( "Nachricht konnte nicht gesendet werden. Bitte achte auf die richtige Formulierung: “!message : ”, z.B. “!message Lana: Hawwu!”", ) }) .and_then(|m| INBOX.queue_message(&m)) .map(|n| { if let Err(e) = msg.reply( &ctx, &format!("Deine Nachricht wurde erfolgreich an {} gesendet", n), ) { eprintln!("Could not reply because of {:?}", e); } }) .map_err(|e| { if let Err(e) = msg.reply(ctx, &e) { eprintln!("Could not reply because of {:?}", e); } CommandError(e) }) } #[command] fn inbox(ctx: &mut Context, msg: &Message) -> CommandResult { if let Some((_, name)) = msg.content.split_once(' ') { let messages = INBOX.fetch_messages(name); if messages.is_empty() { if let Err(e) = msg.reply(ctx, "Keine neuen Nachrichten für .") { eprintln!("Could not reply because of {:?}", e); } return Ok(()); } let output = messages.into_iter().join("\n"); if let Err(e) = msg.reply(ctx, output) { eprintln!("Could not reply because of {:?}", e); } } else { if let Err(e) = msg.reply(ctx, "Kein Name für die Abfrage.") { eprintln!("Could not reply because of {:?}", e); } } Ok(()) } // TODO: remove copy paste #[command] fn question(ctx: &mut Context, msg: &Message) -> CommandResult { InboxMessage::parse( &msg.content.replacen("!question", "!message Stream:", 1), msg.author.id, ) .ok_or_else(|| { String::from( "Nachricht konnte nicht gesendet werden. Bitte achte auf die richtige Formulierung: “!message : ”, z.B. “!message Lana: Hawwu!”", ) }) .and_then(|m| INBOX.queue_message(&m)) .map(|n| { if let Err(e) = msg.reply( &ctx, &format!("Deine Nachricht wurde erfolgreich an {} gesendet", n), ) { eprintln!("Could not reply because of {:?}", e); } }) .map_err(|e| { if let Err(e) = msg.reply(ctx, &e) { eprintln!("Could not reply because of {:?}", e); } CommandError(e) }) }