Skip to content

Commit

Permalink
feat(intelligence): trigger by direct mention
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanccn committed Sep 29, 2024
1 parent 4caf546 commit fdef36f
Show file tree
Hide file tree
Showing 14 changed files with 124 additions and 73 deletions.
40 changes: 0 additions & 40 deletions src/commands/fun/intelligence.rs

This file was deleted.

1 change: 0 additions & 1 deletion src/commands/fun/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
pub mod autoreply;
pub mod intelligence;
pub mod owo;
pub mod shiggy;
1 change: 0 additions & 1 deletion src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ pub fn to_vec() -> Vec<
command!(moderation, kick),
command!(moderation, timeout),
command!(fun, autoreply),
command!(fun, intelligence, ask),
command!(fun, owo),
command!(fun, shiggy),
command!(utils, ping),
Expand Down
5 changes: 2 additions & 3 deletions src/commands/moderation/ban.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use color_eyre::eyre::Result;
use poise::serenity_prelude as serenity;

use super::LOGS_CHANNEL;
use crate::{utils::serenity::unique_username, Context};
use crate::Context;

/// Ban a member
#[poise::command(
Expand Down Expand Up @@ -70,8 +70,7 @@ pub async fn ban(

if let Some(logs_channel) = *LOGS_CHANNEL {
let server_embed = dm_embed.footer(
serenity::CreateEmbedFooter::new(unique_username(ctx.author()))
.icon_url(ctx.author().face()),
serenity::CreateEmbedFooter::new(ctx.author().tag()).icon_url(ctx.author().face()),
);

logs_channel
Expand Down
5 changes: 2 additions & 3 deletions src/commands/moderation/kick.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use color_eyre::eyre::Result;
use poise::serenity_prelude as serenity;

use super::LOGS_CHANNEL;
use crate::{utils::serenity::unique_username, Context};
use crate::Context;

/// Kick a member
#[poise::command(
Expand Down Expand Up @@ -52,8 +52,7 @@ pub async fn kick(

if let Some(logs_channel) = *LOGS_CHANNEL {
let server_embed = dm_embed.footer(
serenity::CreateEmbedFooter::new(unique_username(ctx.author()))
.icon_url(ctx.author().face()),
serenity::CreateEmbedFooter::new(ctx.author().tag()).icon_url(ctx.author().face()),
);

logs_channel
Expand Down
5 changes: 2 additions & 3 deletions src/commands/moderation/timeout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use color_eyre::eyre::Result;
use poise::serenity_prelude as serenity;

use super::LOGS_CHANNEL;
use crate::{utils::serenity::unique_username, Context};
use crate::Context;

/// Timeout a member
#[poise::command(
Expand Down Expand Up @@ -70,8 +70,7 @@ pub async fn timeout(

if let Some(logs_channel) = *LOGS_CHANNEL {
let server_embed = dm_embed.footer(
serenity::CreateEmbedFooter::new(unique_username(ctx.author()))
.icon_url(ctx.author().face()),
serenity::CreateEmbedFooter::new(ctx.author().tag()).icon_url(ctx.author().face()),
);

logs_channel
Expand Down
4 changes: 2 additions & 2 deletions src/commands/useful/self_timeout.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use color_eyre::eyre::{eyre, Result};
use poise::serenity_prelude as serenity;

use crate::{utils::serenity::unique_username, Context};
use crate::Context;

/// Time yourself out for a specific duration
#[poise::command(rename = "self-timeout", slash_command, guild_only)]
Expand Down Expand Up @@ -52,7 +52,7 @@ pub async fn self_timeout(
.unwrap_or(false)
{
let mut resp_embed = resp_embed.author(
serenity::CreateEmbedAuthor::new(unique_username(ctx.author()))
serenity::CreateEmbedAuthor::new(ctx.author().tag())
.icon_url(ctx.author().face()),
);

Expand Down
64 changes: 64 additions & 0 deletions src/handlers/intelligence.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use std::time::Duration;

use color_eyre::eyre::Result;
use poise::serenity_prelude as serenity;
use tokio::{task, time};

use crate::intelligence;

#[tracing::instrument(skip_all, fields(message_id = message.id.get()))]
pub async fn handle(message: &serenity::Message, ctx: &serenity::Context) -> Result<()> {
if message
.flags
.is_some_and(|flags| flags.contains(serenity::MessageFlags::SUPPRESS_NOTIFICATIONS))
{
return Ok(());
}

if let Some(query) = message
.content
.strip_prefix(&format!("<@{}>", ctx.cache.current_user().id))
.map(|s| s.trim())
{
if query.is_empty() {
return Ok(());
}

let typing_task = task::spawn({
let http = ctx.http.clone();
let channel = message.channel_id;

async move {
let mut interval = time::interval(Duration::from_secs(10));

loop {
interval.tick().await;
let _ = http.broadcast_typing(channel).await;
}
}
});

let username = message.author.tag();
let display_name = message.author.global_name.clone().map(|s| s.into_string());

let nick = message
.member
.as_ref()
.and_then(|m| m.nick.as_ref().map(|s| s.to_owned().into_string()));

let resp = intelligence::query(intelligence::Request {
query: query.to_owned(),
metadata: intelligence::RequestMetadata {
username,
display_name,
nick,
},
})
.await?;

message.reply_ping(&ctx.http, resp).await?;
typing_task.abort();
}

Ok(())
}
11 changes: 4 additions & 7 deletions src/handlers/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use poise::serenity_prelude::{self as serenity};
use color_eyre::eyre::Result;
use once_cell::sync::Lazy;

use crate::{storage::log::MessageLog, utils::serenity::unique_username, Data};
use crate::{storage::log::MessageLog, Data};

pub async fn handle_message(message: &serenity::Message, data: &Data) -> Result<()> {
if let Some(storage) = &data.storage {
Expand Down Expand Up @@ -194,11 +194,8 @@ pub async fn member_join(ctx: &serenity::Context, user: &serenity::User) -> Resu
serenity::CreateMessage::default().embed(
serenity::CreateEmbed::default()
.author(
serenity::CreateEmbedAuthor::new(format!(
"@{} joined",
unique_username(user)
))
.icon_url(user.face()),
serenity::CreateEmbedAuthor::new(format!("@{} joined", user.tag()))
.icon_url(user.face()),
)
.field("User", user.to_string(), false)
.field("ID", format!("`{}`", user.id), false)
Expand All @@ -220,7 +217,7 @@ pub async fn member_leave(
if let Some(logs_channel) = *MEMBER_LOGS_CHANNEL {
let mut embed = serenity::CreateEmbed::default()
.author(
serenity::CreateEmbedAuthor::new(format!("@{} left", unique_username(user)))
serenity::CreateEmbedAuthor::new(format!("@{} left", user.tag()))
.icon_url(user.face()),
)
.field("User", user.to_string(), false)
Expand Down
2 changes: 2 additions & 0 deletions src/handlers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use poise::serenity_prelude as serenity;
mod autoreply;
mod code_expansion;
mod error_handling;
mod intelligence;
pub mod log;

pub use error_handling::handle_error;
Expand All @@ -20,6 +21,7 @@ pub async fn handle_message(
code_expansion::handle(message, ctx),
autoreply::handle(message, ctx, data),
log::handle_message(message, data),
intelligence::handle(message, ctx),
)?;

Ok(())
Expand Down
44 changes: 44 additions & 0 deletions src/intelligence.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use std::env;

use color_eyre::eyre::{eyre, Result};
use serde::{Deserialize, Serialize};

use crate::reqwest_client::HTTP;

static API_URL: &str = "https://intelligence.valfisk.ryanccn.dev/v2";

#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RequestMetadata {
pub username: String,
pub display_name: Option<String>,
pub nick: Option<String>,
}

#[derive(Serialize)]
pub struct Request {
pub query: String,
pub metadata: RequestMetadata,
}

#[derive(Deserialize)]
pub struct Response {
pub response: String,
}

pub async fn query(request: Request) -> Result<String> {
let secret = env::var("INTELLIGENCE_SECRET")
.map_err(|_| eyre!("Valfisk Intelligence API secret is not set!"))?;

let resp: Response = HTTP
.post(API_URL)
.bearer_auth(secret)
.json(&request)
.send()
.await?
.error_for_status()?
.json()
.await?;

Ok(resp.response)
}
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub type Context<'a> = poise::Context<'a, Data, Report>;
mod api;
mod commands;
mod handlers;
mod intelligence;
mod reqwest_client;
mod starboard;
mod storage;
Expand Down
5 changes: 1 addition & 4 deletions src/starboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ use poise::serenity_prelude as serenity;
use color_eyre::eyre::{OptionExt, Result};
use tracing::debug;

use crate::utils::serenity::unique_username;

fn channel_from_env(key: &str) -> Option<serenity::ChannelId> {
env::var(key)
.ok()
Expand Down Expand Up @@ -107,8 +105,7 @@ fn make_message_embed<'a>(
content
})
.author(
serenity::CreateEmbedAuthor::new(unique_username(&message.author))
.icon_url(message.author.face()),
serenity::CreateEmbedAuthor::new(message.author.tag()).icon_url(message.author.face()),
)
.timestamp(message.timestamp);

Expand Down
9 changes: 0 additions & 9 deletions src/utils/serenity.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
use color_eyre::eyre::Result;
use poise::serenity_prelude as serenity;

pub fn unique_username(user: &serenity::User) -> String {
let mut ret = user.name.clone().into_string();
if let Some(discrim) = user.discriminator {
ret.push_str(&format!("#{discrim}"));
}

ret
}

#[tracing::instrument(skip(ctx))]
pub async fn suppress_embeds(ctx: &serenity::Context, message: &serenity::Message) -> Result<()> {
use poise::futures_util::StreamExt as _;
Expand Down

0 comments on commit fdef36f

Please sign in to comment.