Newer
Older
use phf::phf_map;
use serenity::async_trait;
use serenity::model::channel::{Message, ReactionType};
use serenity::prelude::*;
use std::str::FromStr;
static EMOJI_MAP: phf::Map<&'static str, &'static str> = phf_map! {
"cat" => "🐈",
"chicken" => "🐔",
"spaghetti" => "🍝",
"dog" => "🐕",
"bot" => "🤖",
"mango" => "🥭",
"banana" => "🍌",
fn map_lookup(msg: &str) -> Option<&'static str> {
// We lose the O(1) benefits of the hashmap
// But whatever. It doesn't need to be fast
for (k, v) in EMOJI_MAP.entries() {
if msg.contains(k) {
return Some(v);
}
}
None
}
#[derive(Default)]
pub struct ReactHandler;
#[async_trait]
impl LineHandler for ReactHandler {
async fn message(&self, ctx: &Context, msg: &Message) {
// Kind of convoluted, but allows us to react in the correct order.
let groups = msg
.content
.chars()
.map(|c| match c {
'!' | '?' | ',' | '.' => ' ',
_ => c,
})
.group_by(|c| *c == ' ');
let reacts: Vec<_> = groups
.into_iter()
.filter_map(|(_, c)| map_lookup(&c.collect::<String>().to_lowercase()))
.unique()
.collect();
for r in reacts {
let reaction_type = match ReactionType::from_str(r) {
Ok(x) => x,
Err(x) => {
println!("Could not react: {}", x);
return;
};
if let Err(e) = msg.react(&ctx, reaction_type).await {
println!("Error reacting: {}", e);