diff options
| author | Nathan Perry <np@nathanperry.dev> | 2019-11-17 21:31:28 -0500 |
|---|---|---|
| committer | Nathan Perry <np@nathanperry.dev> | 2019-11-17 21:31:28 -0500 |
| commit | 2a38c282dd57c2051a568549d62c80d6036e8920 (patch) | |
| tree | ec25f84dda5cdb100ae093b0a690ef349636b4dc /src/commands/meme | |
| parent | 479bb8d584b138054acc6567b72cb3076832e79c (diff) | |
most restructuring done
Diffstat (limited to 'src/commands/meme')
| -rw-r--r-- | src/commands/meme/create.rs | 42 | ||||
| -rw-r--r-- | src/commands/meme/delete.rs | 13 | ||||
| -rw-r--r-- | src/commands/meme/history.rs | 82 | ||||
| -rw-r--r-- | src/commands/meme/invoke.rs | 33 | ||||
| -rw-r--r-- | src/commands/meme/mod.rs | 11 |
5 files changed, 102 insertions, 79 deletions
diff --git a/src/commands/meme/create.rs b/src/commands/meme/create.rs index 245f067..0851961 100644 --- a/src/commands/meme/create.rs +++ b/src/commands/meme/create.rs @@ -8,7 +8,7 @@ use std::{ use diesel::result::Error as DieselError; use serenity::{ - framework::standard::Args, + framework::standard::{Args, Delimiter}, model::channel::Message, prelude::*, }; @@ -19,7 +19,6 @@ use crate::{ parse_times, ytdl_url, }, - commands::send, db::{ Audio, connection, @@ -27,10 +26,16 @@ use crate::{ NewMeme, }, Result, + util::CtxExt, }; -pub fn addmeme(_: &mut Context, msg: &Message, args: Args) -> Result<()> { - let mut args = Args::new(args.rest(), &[" ".to_owned(), "\n".to_owned(), "\t".to_owned()]); +lazy_static! { + static ref delims: Vec<Delimiter> = vec![' '.into(), '\n'.into(), '\t'.into()]; +} + +#[command] +pub fn addmeme(ctx: &mut Context, msg: &Message, args: Args) -> Result<()> { + let mut args = Args::new(args.rest(), delims.as_ref()); let title = args.single_quoted::<String>()?; let text = args.rest().to_owned(); @@ -40,7 +45,7 @@ pub fn addmeme(_: &mut Context, msg: &Message, args: Args) -> Result<()> { let conn = connection()?; let image = msg.attachments.first() - .ok_or(::failure::err_msg("no attachment")) + .ok_or(anyhow!("no attachment")) .and_then(|att| { let data = att.download()?; Image::create(&conn, &att.filename, data, msg.author.id.0) @@ -49,7 +54,7 @@ pub fn addmeme(_: &mut Context, msg: &Message, args: Args) -> Result<()> { if image.is_none() && text.is_none() { warn!("tried to create non-audio meme with no image or text"); - return send(msg.channel_id, "hahAA it's empty xdddd", msg.tts); + return ctx.send(msg.channel_id, "hahAA it's empty xdddd", msg.tts); } let save_result = NewMeme { @@ -62,12 +67,12 @@ pub fn addmeme(_: &mut Context, msg: &Message, args: Args) -> Result<()> { use diesel::result::DatabaseErrorKind; match save_result { - Ok(_) => msg.react("👌"), + Ok(_) => msg.react(ctx, "👌"), Err(e) => { if let Some(DieselError::DatabaseError(DatabaseErrorKind::UniqueViolation, _)) = e.downcast_ref::<DieselError>() { error!("tried to create meme that already exists"); - msg.react("❌")?; - return send(msg.channel_id, "that meme already exists", msg.tts); + msg.react(ctx, "❌")?; + return ctx.send(msg.channel_id, "that meme already exists", msg.tts); } return Err(e); @@ -75,8 +80,9 @@ pub fn addmeme(_: &mut Context, msg: &Message, args: Args) -> Result<()> { } } -pub fn addaudiomeme(_: &mut Context, msg: &Message, args: Args) -> Result<()> { - let mut args = Args::new(args.rest(), &[" ".to_owned(), "\n".to_owned(), "\t".to_owned()]); +#[command] +pub fn addaudiomeme(ctx: &mut Context, msg: &Message, args: Args) -> Result<()> { + let mut args = Args::new(args.rest(), delims.as_ref()); let title = args.single_quoted::<String>()?; let audio_str = args.single_quoted::<String>()?; @@ -84,8 +90,8 @@ pub fn addaudiomeme(_: &mut Context, msg: &Message, args: Args) -> Result<()> { let elems = audio_str.split_whitespace().collect::<Vec<_>>(); if elems.len() == 0 { - send(msg.channel_id, "are you stupid", msg.tts)?; - return Err(::failure::err_msg("no audio link was provided")) + ctx.send(msg.channel_id, "are you stupid", msg.tts)?; + return Err(anyhow!("no audio link was provided")) } let audio_link = Url::parse(elems[0])?; @@ -133,7 +139,7 @@ pub fn addaudiomeme(_: &mut Context, msg: &Message, args: Args) -> Result<()> { let conn = connection()?; let image = msg.attachments.first() - .ok_or(::failure::err_msg("no attachment")) + .ok_or(anyhow!("no attachment")) .and_then(|att| { let data = att.download()?; Image::create(&conn, &att.filename, data, msg.author.id.0) @@ -145,7 +151,7 @@ pub fn addaudiomeme(_: &mut Context, msg: &Message, args: Args) -> Result<()> { if bytes == 0 { debug!("read 0 bytes from audio reader"); - return send(msg.channel_id, "🔇🔇🔇🔕🔕🔕🔕🔕🔇🔕🔕🔇🔕🔕📣📢📣📢📣", msg.tts); + return ctx.send(msg.channel_id, "🔇🔇🔇🔕🔕🔕🔕🔕🔇🔕🔕🔇🔕🔕📣📢📣📢📣", msg.tts); } let audio_id = Audio::create(&conn, audio_data, msg.author.id.0)?; @@ -160,12 +166,12 @@ pub fn addaudiomeme(_: &mut Context, msg: &Message, args: Args) -> Result<()> { use diesel::result::DatabaseErrorKind; match save_result { - Ok(_) => msg.react("👌"), + Ok(_) => msg.react(ctx, "👌"), Err(e) => { if let Some(DieselError::DatabaseError(DatabaseErrorKind::UniqueViolation, _)) = e.downcast_ref::<DieselError>() { error!("tried to create meme that already exists"); - msg.react("❌")?; - return send(msg.channel_id, "that meme already exists", msg.tts); + msg.react(ctx, "❌")?; + return ctx.send(msg.channel_id, "that meme already exists", msg.tts); } return Err(e); diff --git a/src/commands/meme/delete.rs b/src/commands/meme/delete.rs index 5c6eb13..72226e5 100644 --- a/src/commands/meme/delete.rs +++ b/src/commands/meme/delete.rs @@ -9,25 +9,28 @@ use serenity::{ }; use crate::{ - commands::send, db::{ connection, delete_meme, }, Result, + util::CtxExt, }; -pub fn delmeme(_: &mut Context, msg: &Message, mut args: Args) -> Result<()> { +#[command] +#[aliases("delmem")] +pub fn delmeme(ctx: &mut Context, msg: &Message, mut args: Args) -> Result<()> { let title = args.single_quoted::<String>()?; let conn = connection()?; + match delete_meme(&conn, &title, msg.author.id.0) { - Ok(_) => msg.react("💀"), + Ok(_) => msg.react(ctx, "💀"), Err(e) => { if let Some(NotFound) = e.downcast_ref::<DieselError>() { - msg.react("❓")?; + msg.react(ctx, "❓")?; info!("attempted to delete nonexistent meme: '{}'", title); - send(msg.channel_id, "nice try", msg.tts)?; + ctx.send(msg.channel_id, "nice try", msg.tts)?; return Ok(()); } diff --git a/src/commands/meme/history.rs b/src/commands/meme/history.rs index e5f15f5..6c03bef 100644 --- a/src/commands/meme/history.rs +++ b/src/commands/meme/history.rs @@ -13,7 +13,6 @@ use timeago::{ }; use crate::{ - commands::send, db::{ connection, InvocationRecord, @@ -22,6 +21,7 @@ use crate::{ }, must_env_lookup, Result, + util::CtxExt, }; lazy_static! { @@ -36,7 +36,9 @@ lazy_static! { static CLEAN_DATE_FORMAT: &'static str = "%b %-e %Y"; -pub fn wat(_: &mut Context, msg: &Message, _: Args) -> Result<()> { +#[command] +#[aliases("what")] +pub fn wat(ctx: &mut Context, msg: &Message, _: Args) -> Result<()> { let conn = connection()?; let record = match InvocationRecord::last(&conn) { @@ -44,10 +46,10 @@ pub fn wat(_: &mut Context, msg: &Message, _: Args) -> Result<()> { Err(e) => { if let Some(NotFound) = e.downcast_ref::<DieselError>() { info!("found no memes in history"); - return send(msg.channel_id, "no one has ever memed before", msg.tts); + return ctx.send(msg.channel_id, "no one has ever memed before", msg.tts); } - send(msg.channel_id, "BAD MEME BAD MEME", msg.tts)?; + ctx.send(msg.channel_id, "BAD MEME BAD MEME", msg.tts)?; return Err(e); }, }; @@ -57,19 +59,19 @@ pub fn wat(_: &mut Context, msg: &Message, _: Args) -> Result<()> { match meme { Ok(ref meme) => { let metadata = Metadata::find(&conn, meme.metadata_id)?; - let author = crate::TARGET_GUILD_ID.member(metadata.created_by as u64)?; + let author = crate::TARGET_GUILD_ID.member(ctx, metadata.created_by as u64)?; - send(msg.channel_id, + ctx.send(msg.channel_id, &format!("that was \"{}\" by {} ({})", meme.title, author.mention(), metadata.created.date().format(CLEAN_DATE_FORMAT)), msg.tts)? }, Err(e) => { if let Some(NotFound) = e.downcast_ref::<DieselError>() { info!("last meme not found in database"); - return send(msg.channel_id, "heuueueeeeh?", msg.tts); + return ctx.send(msg.channel_id, "heuueueeeeh?", msg.tts); } - send(msg.channel_id, "do i look like i know what a jpeg is", msg.tts)?; + ctx.send(msg.channel_id, "do i look like i know what a jpeg is", msg.tts)?; return Err(e); }, }; @@ -77,7 +79,8 @@ pub fn wat(_: &mut Context, msg: &Message, _: Args) -> Result<()> { meme.map(|_| {}) } -pub fn history(_: &mut Context, msg: &Message, mut args: Args) -> Result<()> { +#[command] +pub fn history(ctx: &mut Context, msg: &Message, mut args: Args) -> Result<()> { use itertools::Itertools; lazy_static! { @@ -91,7 +94,7 @@ pub fn history(_: &mut Context, msg: &Message, mut args: Args) -> Result<()> { if n > *MAX_HIST { debug!("user requested more than MAX_HIST ({}) items from history", *MAX_HIST); - send(msg.channel_id, "YER PUSHIN ME OVER THE FUCKIN LINE", true)?; + ctx.send(msg.channel_id, "YER PUSHIN ME OVER THE FUCKIN LINE", true)?; } let n = n.min(*MAX_HIST); @@ -100,7 +103,7 @@ pub fn history(_: &mut Context, msg: &Message, mut args: Args) -> Result<()> { if records.len() == 0 { info!("no memes in history"); - return send(msg.channel_id, "i don't remember anything :(", msg.tts); + return ctx.send(msg.channel_id, "i don't remember anything :(", msg.tts); } info!("reporting meme history (len {})", n); @@ -118,8 +121,8 @@ pub fn history(_: &mut Context, msg: &Message, mut args: Args) -> Result<()> { Metadata::find(&conn, meme.metadata_id).map(|metadata| (metadata, meme)) }) .map(|(metadata, meme)| { - let author_name = crate::TARGET_GUILD_ID.member(metadata.created_by as u64).map(|m| m.display_name().into_owned()).unwrap_or("???".to_owned()); - let invoker_name = crate::TARGET_GUILD_ID.member(rec.user_id as u64).map(|m| m.display_name().into_owned()).unwrap_or("???".to_owned()); + let author_name = crate::TARGET_GUILD_ID.member(ctx, metadata.created_by as u64).map(|m| m.display_name().into_owned()).unwrap_or("???".to_owned()); + let invoker_name = crate::TARGET_GUILD_ID.member(ctx, rec.user_id as u64).map(|m| m.display_name().into_owned()).unwrap_or("???".to_owned()); format!("{}. [{}{}] \"{}\" by {} ({}). invoked by {}.", i + 1, rand, ago, meme.title, author_name, metadata.created.date().format(CLEAN_DATE_FORMAT), invoker_name) }) .unwrap_or_else(|e| { @@ -129,16 +132,18 @@ pub fn history(_: &mut Context, msg: &Message, mut args: Args) -> Result<()> { } } - let invoker_name = crate::TARGET_GUILD_ID.member(rec.user_id as u64).map(|m| m.display_name().into_owned()).unwrap_or("???".to_owned()); + let invoker_name = crate::TARGET_GUILD_ID.member(ctx, rec.user_id as u64).map(|m| m.display_name().into_owned()).unwrap_or("???".to_owned()); format!("{}. [{}{}] not found. invoked by {}.", i + 1, rand, ago, invoker_name) }) }) .join("\n"); - send(msg.channel_id, &resp, false) + ctx.send(msg.channel_id, &resp, false) } -pub fn stats(_: &mut Context, msg: &Message, _: Args) -> Result<()> { +#[command] +#[aliases("stat")] +pub fn stats(ctx: &mut Context, msg: &Message, _: Args) -> Result<()> { use db; use serenity::model::{ id::UserId, @@ -151,11 +156,11 @@ pub fn stats(_: &mut Context, msg: &Message, _: Args) -> Result<()> { debug!("reporting stats"); - let rand_user: User = UserId(stats.most_random_meme_user).to_user()?; - let direct_user: User = UserId(stats.most_directly_named_meme_user).to_user()?; + let rand_user: User = UserId(stats.most_random_meme_user).to_user(ctx)?; + let direct_user: User = UserId(stats.most_directly_named_meme_user).to_user(ctx)?; - let rand_user = rand_user.nick_in(*TARGET_GUILD_ID).unwrap_or(rand_user.name); - let direct_user = direct_user.nick_in(*TARGET_GUILD_ID).unwrap_or(direct_user.name); + let rand_user = rand_user.nick_in(ctx, *TARGET_GUILD_ID).unwrap_or(rand_user.name); + let direct_user = direct_user.nick_in(ctx, *TARGET_GUILD_ID).unwrap_or(direct_user.name); let s = format!( r#" @@ -197,10 +202,11 @@ and *{}* was the most-memed overall ({})"#, stats.most_popular_random_meme, stats.most_popular_random_meme_count, stats.most_popular_meme_overall, stats.most_popular_meme_overall_count, ); - send(msg.channel_id, s, msg.tts) + ctx.send(msg.channel_id, s, msg.tts) } -pub fn memers(_: &mut Context, msg: &Message, _args: Args) -> Result<()> { +#[command] +pub fn memers(ctx: &mut Context, msg: &Message, _args: Args) -> Result<()> { use db; use itertools::Itertools; use serenity::model::{ @@ -211,8 +217,8 @@ pub fn memers(_: &mut Context, msg: &Message, _args: Args) -> Result<()> { let s = db::memers()? .into_iter() .map(|info| { - let user = UserId(info.user_id).to_user()?; - let username = user.nick_in(*TARGET_GUILD_ID).unwrap_or(user.name); + let user = UserId(info.user_id).to_user(ctx)?; + let username = user.nick_in(ctx, *TARGET_GUILD_ID).unwrap_or(user.name); let res = format!( "**{}**: {} total, {} random, {} specific. favorite meme: *{}* ({})", @@ -230,15 +236,15 @@ pub fn memers(_: &mut Context, msg: &Message, _args: Args) -> Result<()> { .into_iter() .join("\n"); - send(msg.channel_id, &s, msg.tts) + ctx.send(msg.channel_id, &s, msg.tts) } -pub fn query(_: &mut Context, msg: &Message, mut args: Args) -> Result<()> { +#[command] +pub fn query(ctx: &mut Context, msg: &Message, mut args: Args) -> Result<()> { use std::borrow::Borrow; use itertools::Itertools; use regex::Regex; - use failure::err_msg; use serenity::model::id::UserId; use crate::{ @@ -252,19 +258,19 @@ pub fn query(_: &mut Context, msg: &Message, mut args: Args) -> Result<()> { static ref AGE_REGEX: Regex = Regex::new(r"(?i)(?:age|order)=(.*)").unwrap(); } - let guild = msg.channel_id.to_channel()? + let guild = msg.channel_id.to_channel(ctx)? .guild() - .ok_or(err_msg("couldn't find guild"))?; + .ok_or(anyhow!("couldn't find guild"))?; let guild = guild.read() - .guild() - .ok_or(err_msg("couldn't find guild"))?; + .guild(ctx) + .ok_or(anyhow!("couldn't find guild"))?; let guild = guild .read(); let creator: Option<u64> = { - let creator = args.current_quoted().map(|s| CREATOR_REGEX.is_match(s)).unwrap_or(false); + let creator = args.quoted().current().map(|s| CREATOR_REGEX.is_match(s)).unwrap_or(false); if creator { args.single_quoted::<String>() .ok() @@ -276,12 +282,12 @@ pub fn query(_: &mut Context, msg: &Message, mut args: Args) -> Result<()> { }; let order = { - let order = args.current_quoted().map(|s| AGE_REGEX.is_match(s)).unwrap_or(false); + let order = args.quoted().current().map(|s| AGE_REGEX.is_match(s)).unwrap_or(false); if order { args.single_quoted::<String>().ok() .and_then(|s| AGE_REGEX.captures(&s).and_then(|c| c.get(1)).map(|x| x.as_str().to_owned())) - .map(|s| s.contains("new")) + .map(|s: String| s.contains("new")) .unwrap_or(true) } else { true @@ -291,8 +297,8 @@ pub fn query(_: &mut Context, msg: &Message, mut args: Args) -> Result<()> { let result = db::query_meme(args.rest(), creator, order)? .into_iter() .map(|(meme, metadata)| { - let user = UserId(metadata.created_by as u64).to_user()?; - let username = user.nick_in(*TARGET_GUILD_ID).unwrap_or(user.name); + let user = UserId(metadata.created_by as u64).to_user(ctx)?; + let username = user.nick_in(ctx, *TARGET_GUILD_ID).unwrap_or(user.name); Ok(format!("*{}* by **{}** ({}). text length: **{}**, image: **{}**, audio: **{}**", meme.title, @@ -318,8 +324,8 @@ pub fn query(_: &mut Context, msg: &Message, mut args: Args) -> Result<()> { if result.len() == 0 { info!("no memes matched query"); - return send(msg.channel_id, "no match".to_owned(), msg.tts); + return ctx.send(msg.channel_id, "no match".to_owned(), msg.tts); } - send(msg.channel_id, &result, msg.tts) + ctx.send(msg.channel_id, &result, msg.tts) }
\ No newline at end of file diff --git a/src/commands/meme/invoke.rs b/src/commands/meme/invoke.rs index 0f992c2..89ca999 100644 --- a/src/commands/meme/invoke.rs +++ b/src/commands/meme/invoke.rs @@ -2,7 +2,7 @@ use diesel::{ NotFound, result::Error as DieselError, }; -use failure::Error; +use itertools::Itertools; use serenity::{ framework::standard::Args, model::channel::Message, @@ -10,11 +10,7 @@ use serenity::{ }; use crate::{ - audio::CtxExt, - commands::{ - meme::send_meme, - send, - }, + commands::meme::send_meme, db::{ self, connection, @@ -22,18 +18,25 @@ use crate::{ InvocationRecord, }, Result, + util::CtxExt, }; +#[command] +#[aliases("mem")] #[inline] pub fn meme(ctx: &mut Context, msg: &Message, args: Args) -> Result<()> { _meme(ctx, msg, args, AudioPlayback::Optional) } +#[command] +#[aliases("audiomeme", "audiomem")] #[inline] pub fn audio_meme(ctx: &mut Context, msg: &Message, args: Args) -> Result<()> { _meme(ctx, msg, args, AudioPlayback::Required) } +#[command] +#[aliases("silentmeme", "silentmem")] #[inline] pub fn silent_meme(ctx: &mut Context, msg: &Message, args: Args) -> Result<()> { _meme(ctx, msg, args, AudioPlayback::Prohibited) @@ -51,7 +54,7 @@ fn _meme(ctx: &mut Context, msg: &Message, args: Args, audio_playback: AudioPlay return rand_meme(ctx, msg, audio_playback); } - let search = args.full(); + let search = args.raw().join(" "); let conn = connection()?; let mem = match find_meme(&conn, search) { @@ -63,9 +66,9 @@ fn _meme(ctx: &mut Context, msg: &Message, args: Args, audio_playback: AudioPlay Err(e) => { return if let Some(NotFound) = e.downcast_ref::<DieselError>() { info!("requested meme not found in database"); - send(msg.channel_id, "c'mon baby, guesstimate", msg.tts) + ctx.send(msg.channel_id, "c'mon baby, guesstimate", msg.tts) } else { - send(msg.channel_id, "what in ryan's name", msg.tts)?; + ctx.send(msg.channel_id, "what in ryan's name", msg.tts)?; Err(e) }; }, @@ -74,6 +77,8 @@ fn _meme(ctx: &mut Context, msg: &Message, args: Args, audio_playback: AudioPlay send_meme(ctx, &mem, &conn, msg) } +#[command] +#[aliases("rarememe", "raremem")] fn rand_meme(ctx: &Context, message: &Message, audio_playback: AudioPlayback) -> Result<()> { let conn = connection()?; @@ -94,17 +99,19 @@ fn rand_meme(ctx: &Context, message: &Message, audio_playback: AudioPlayback) -> match e.downcast_ref::<DieselError>() { Some(NotFound) => { info!("random meme not found"); - return send(message.channel_id, "i don't know any :(", message.tts) + return ctx.send(message.channel_id, "i don't know any :(", message.tts) }, _ => {}, } - send(message.channel_id, "HELP", message.tts)?; + ctx.send(message.channel_id, "HELP", message.tts)?; return Err(e); }, } } +#[command] +#[aliases("rarememe", "raremem")] pub fn rare_meme(ctx: &mut Context, msg: &Message, _args: Args) -> Result<()> { let should_audio = ctx.users_listening()?; @@ -120,12 +127,12 @@ pub fn rare_meme(ctx: &mut Context, msg: &Message, _args: Args) -> Result<()> { match e.downcast_ref::<DieselError>() { Some(NotFound) => { info!("rare meme not found"); - return send(msg.channel_id, "i don't know any :(", msg.tts) + return ctx.send(msg.channel_id, "i don't know any :(", msg.tts) }, _ => {}, } - send(msg.channel_id, "THE MEME MARKET IS IN FREEFALL", msg.tts)?; + ctx.send(msg.channel_id, "THE MEME MARKET IS IN FREEFALL", msg.tts)?; Err(e) }, diff --git a/src/commands/meme/mod.rs b/src/commands/meme/mod.rs index 3738eab..e5244aa 100644 --- a/src/commands/meme/mod.rs +++ b/src/commands/meme/mod.rs @@ -37,7 +37,7 @@ fn send_meme(ctx: &Context, t: &Meme, conn: &PgConnection, msg: &Message) -> Res let image = t.image(conn); let audio = t.audio(conn); - let create_msg = |m: CreateMessage| { + let create_msg = |m: &mut CreateMessage| { let ret = m.tts(should_tts); match t.content { @@ -49,10 +49,11 @@ fn send_meme(ctx: &Context, t: &Meme, conn: &PgConnection, msg: &Message) -> Res match image { Some(image) => { let image = image?; - msg.channel_id.send_files(vec!(AttachmentType::Bytes((&image.data, &image.filename))), create_msg)?; + msg.channel_id.send_files(ctx, vec!(AttachmentType::Bytes((&image.data, &image.filename))), create_msg)?; }, + None => match t.content { - Some(_) => { msg.channel_id.send_message(create_msg)?; }, + Some(_) => { msg.channel_id.send_message(ctx, create_msg)?; }, None => {}, }, }; @@ -64,7 +65,7 @@ fn send_meme(ctx: &Context, t: &Meme, conn: &PgConnection, msg: &Message) -> Res let audio = audio?; { - let queue_lock = ctx.data.lock().get::<PlayQueue>().cloned().unwrap(); + let queue_lock = ctx.data.write().get::<PlayQueue>().cloned().unwrap(); let mut play_queue = queue_lock.write().unwrap(); play_queue.meme_queue.push_back(PlayArgs{ @@ -76,7 +77,7 @@ fn send_meme(ctx: &Context, t: &Meme, conn: &PgConnection, msg: &Message) -> Res }); } - msg.react("📣")?; + msg.react(ctx, "📣")?; } Ok(()) |
