Refactor system listeners to be a config item
This commit is contained in:
parent
dbae599c43
commit
bb6a961c22
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1403,7 +1403,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fren"
|
name = "fren"
|
||||||
version = "2.9.0"
|
version = "2.10.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"axum 0.8.1",
|
"axum 0.8.1",
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "fren"
|
name = "fren"
|
||||||
version = "2.9.0"
|
version = "2.10.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|||||||
@ -1,16 +1,16 @@
|
|||||||
use std::sync::Arc;
|
|
||||||
use crate::config::GlobalData;
|
use crate::config::GlobalData;
|
||||||
use crate::discord::voices::speak;
|
use crate::discord::voices::speak;
|
||||||
use crate::models::api_key::Apikey;
|
use crate::models::api_key::Apikey;
|
||||||
use axum::extract::State;
|
use axum::extract::State;
|
||||||
use axum::{http::StatusCode, response::IntoResponse, routing::post, Json, Router};
|
use axum::{Json, Router, http::StatusCode, response::IntoResponse, routing::post};
|
||||||
use log::info;
|
use log::info;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct ApiContext {
|
struct ApiContext {
|
||||||
data: Arc<GlobalData>,
|
data: Arc<GlobalData>,
|
||||||
ctx: poise::serenity_prelude::Context
|
ctx: poise::serenity_prelude::Context,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn web_server(data: Arc<GlobalData>, ctx: poise::serenity_prelude::Context) {
|
pub async fn web_server(data: Arc<GlobalData>, ctx: poise::serenity_prelude::Context) {
|
||||||
@ -18,10 +18,7 @@ pub async fn web_server(data: Arc<GlobalData>, ctx: poise::serenity_prelude::Con
|
|||||||
|
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.route("/play", post(play_sound))
|
.route("/play", post(play_sound))
|
||||||
.with_state(ApiContext {
|
.with_state(ApiContext { data, ctx });
|
||||||
data,
|
|
||||||
ctx
|
|
||||||
});
|
|
||||||
|
|
||||||
info!("Serving bot api on: {}", addr);
|
info!("Serving bot api on: {}", addr);
|
||||||
let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
|
let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
|
||||||
@ -39,21 +36,21 @@ async fn play_sound(
|
|||||||
State(ctx): State<ApiContext>,
|
State(ctx): State<ApiContext>,
|
||||||
Json(payload): Json<SoundPayload>,
|
Json(payload): Json<SoundPayload>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
|
|
||||||
if let Some(api_key) = Apikey::find_key_from_secret(&ctx.data.db, &payload.api_key).unwrap()
|
if let Some(api_key) = Apikey::find_key_from_secret(&ctx.data.db, &payload.api_key).unwrap()
|
||||||
&& let Some(user_id) = api_key.user_id {
|
&& let Some(user_id) = api_key.user_id
|
||||||
info!("Playing audio for {user_id}");
|
{
|
||||||
speak(
|
info!("Playing audio for {user_id}");
|
||||||
&ctx.ctx,
|
speak(
|
||||||
&ctx.data,
|
&ctx.ctx,
|
||||||
ctx.data.cfg.guild_id,
|
&ctx.data,
|
||||||
user_id,
|
ctx.data.cfg.guild_id,
|
||||||
&payload.voice,
|
user_id,
|
||||||
&payload.phrase,
|
&payload.voice,
|
||||||
)
|
&payload.phrase,
|
||||||
.await
|
)
|
||||||
.unwrap();
|
.await
|
||||||
}
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
StatusCode::ACCEPTED
|
StatusCode::ACCEPTED
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use crate::album_manager::AlbumManager;
|
use crate::album_manager::AlbumManager;
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::event_listener::{Action, Expiration, Listener, TriggerType};
|
use crate::event_listener::Listener;
|
||||||
use crate::migrations::{CURRENT_DB_VERSION, do_migration};
|
use crate::migrations::{CURRENT_DB_VERSION, do_migration};
|
||||||
use config::{Config, File};
|
use config::{Config, File};
|
||||||
use cta_api::CTAClient;
|
use cta_api::CTAClient;
|
||||||
@ -30,6 +30,11 @@ pub struct PicOxConfig {
|
|||||||
token: String,
|
token: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
|
pub struct SystemListeners {
|
||||||
|
pub listeners: Vec<Listener>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
pub struct BotConfig {
|
pub struct BotConfig {
|
||||||
pub bot_token: String,
|
pub bot_token: String,
|
||||||
@ -51,6 +56,7 @@ pub struct BotConfig {
|
|||||||
pub music_streaming_site_urls: Vec<String>,
|
pub music_streaming_site_urls: Vec<String>,
|
||||||
pub music_streaming_sites: Vec<String>,
|
pub music_streaming_sites: Vec<String>,
|
||||||
pub picox: PicOxConfig,
|
pub picox: PicOxConfig,
|
||||||
|
pub listeners_cfg: SystemListeners,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BotConfig {
|
impl BotConfig {
|
||||||
@ -93,43 +99,17 @@ pub struct GlobalData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl GlobalData {
|
impl GlobalData {
|
||||||
fn setup_system_listeners(db: &Database) -> Result<(), Error> {
|
fn setup_system_listeners(db: &Database, cfg: &BotConfig) -> Result<(), Error> {
|
||||||
db.filter(|_, listener: &Listener| listener.system_listener)?
|
db.filter(|_, listener: &Listener| listener.system_listener)?
|
||||||
.for_each(|listener: Listener| {
|
.for_each(|listener: Listener| {
|
||||||
let _ = db.remove::<Listener>(listener.id().unwrap()).is_ok();
|
let _ = db.remove::<Listener>(listener.id().unwrap()).is_ok();
|
||||||
});
|
});
|
||||||
|
|
||||||
info!("Adding system listeners...");
|
info!("Adding system listeners...");
|
||||||
Listener::add_listener(
|
|
||||||
db,
|
for listener in &cfg.listeners_cfg.listeners {
|
||||||
Listener::new(
|
Listener::add_listener(db, listener.clone())?;
|
||||||
TriggerType::OnMessage {
|
}
|
||||||
channel_id: None,
|
|
||||||
content: Some("bad bot".to_string()),
|
|
||||||
},
|
|
||||||
vec![Action::React {
|
|
||||||
emoji: "😭".to_string(),
|
|
||||||
}],
|
|
||||||
1.0,
|
|
||||||
Expiration::Never,
|
|
||||||
true,
|
|
||||||
),
|
|
||||||
)?;
|
|
||||||
Listener::add_listener(
|
|
||||||
db,
|
|
||||||
Listener::new(
|
|
||||||
TriggerType::OnMessage {
|
|
||||||
channel_id: None,
|
|
||||||
content: None,
|
|
||||||
},
|
|
||||||
vec![Action::UpdateFrenCoins {
|
|
||||||
fren_coin_diff: 100,
|
|
||||||
}],
|
|
||||||
0.05,
|
|
||||||
Expiration::Never,
|
|
||||||
true,
|
|
||||||
),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -148,7 +128,7 @@ impl GlobalData {
|
|||||||
|
|
||||||
do_migration(&db);
|
do_migration(&db);
|
||||||
|
|
||||||
Self::setup_system_listeners(&db)?;
|
Self::setup_system_listeners(&db, &cfg)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
args,
|
args,
|
||||||
|
|||||||
@ -350,7 +350,21 @@ pub async fn list_social_credit_phrases(ctx: Context<'_>) -> Result<(), Error> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.reply(list.build()).await?;
|
let msg = list.build();
|
||||||
|
|
||||||
|
if msg.len() < MESSAGE_CODE_LIMIT {
|
||||||
|
ctx.reply(msg).await?;
|
||||||
|
} else {
|
||||||
|
ctx.send(
|
||||||
|
CreateReply::default()
|
||||||
|
.reply(true)
|
||||||
|
.attachment(CreateAttachment::bytes(
|
||||||
|
msg.as_bytes(),
|
||||||
|
"social_credit_phrases.md",
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,6 +19,7 @@ mod stonks;
|
|||||||
mod transit;
|
mod transit;
|
||||||
pub(crate) mod voices;
|
pub(crate) mod voices;
|
||||||
|
|
||||||
|
use crate::api::web_server;
|
||||||
use crate::config::GlobalData;
|
use crate::config::GlobalData;
|
||||||
use crate::discord::fren_coin::give_coin;
|
use crate::discord::fren_coin::give_coin;
|
||||||
use crate::discord::joke::random;
|
use crate::discord::joke::random;
|
||||||
@ -39,7 +40,6 @@ use songbird::SerenityInit;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use crate::api::web_server;
|
|
||||||
|
|
||||||
pub type Context<'a> = poise::Context<'a, Arc<GlobalData>, Error>;
|
pub type Context<'a> = poise::Context<'a, Arc<GlobalData>, Error>;
|
||||||
|
|
||||||
@ -69,10 +69,7 @@ async fn event_handler(
|
|||||||
let ctx_web = ctx.clone();
|
let ctx_web = ctx.clone();
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
web_server(
|
web_server(data_web, ctx_web).await;
|
||||||
data_web,
|
|
||||||
ctx_web
|
|
||||||
).await;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
use crate::config::GlobalData;
|
||||||
use crate::discord::Context;
|
use crate::discord::Context;
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use poise::async_trait;
|
use poise::async_trait;
|
||||||
@ -14,7 +15,6 @@ use std::collections::HashMap;
|
|||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use crate::config::GlobalData;
|
|
||||||
|
|
||||||
async fn get_voice_dictionary(path: &Path) -> Result<HashMap<String, PathBuf>, tokio::io::Error> {
|
async fn get_voice_dictionary(path: &Path) -> Result<HashMap<String, PathBuf>, tokio::io::Error> {
|
||||||
let mut dir = tokio::fs::read_dir(path).await?;
|
let mut dir = tokio::fs::read_dir(path).await?;
|
||||||
@ -146,7 +146,7 @@ pub async fn speak(
|
|||||||
let word = word.to_lowercase();
|
let word = word.to_lowercase();
|
||||||
|
|
||||||
if word.is_empty() || word == " " {
|
if word.is_empty() || word == " " {
|
||||||
continue
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut add_period = false;
|
let mut add_period = false;
|
||||||
@ -245,7 +245,16 @@ pub async fn say(
|
|||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let guild_id = ctx.guild_id().unwrap();
|
let guild_id = ctx.guild_id().unwrap();
|
||||||
|
|
||||||
if let Err(err) = speak(ctx.serenity_context(), ctx.data(), guild_id, ctx.author().id, &voice, &phrase).await {
|
if let Err(err) = speak(
|
||||||
|
ctx.serenity_context(),
|
||||||
|
ctx.data(),
|
||||||
|
guild_id,
|
||||||
|
ctx.author().id,
|
||||||
|
&voice,
|
||||||
|
&phrase,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
match err {
|
match err {
|
||||||
VoiceError::VoiceNotFound(_)
|
VoiceError::VoiceNotFound(_)
|
||||||
| VoiceError::WordNotFound(_)
|
| VoiceError::WordNotFound(_)
|
||||||
|
|||||||
@ -136,6 +136,7 @@ pub struct Listener {
|
|||||||
pub trigger_chance: f64,
|
pub trigger_chance: f64,
|
||||||
pub expiration: Expiration,
|
pub expiration: Expiration,
|
||||||
pub system_listener: bool,
|
pub system_listener: bool,
|
||||||
|
#[serde(default)]
|
||||||
pub trigger_count: u64,
|
pub trigger_count: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
mod album_manager;
|
mod album_manager;
|
||||||
|
mod api;
|
||||||
mod config;
|
mod config;
|
||||||
mod discord;
|
mod discord;
|
||||||
mod error;
|
mod error;
|
||||||
@ -9,14 +10,13 @@ mod migrations;
|
|||||||
mod models;
|
mod models;
|
||||||
mod music;
|
mod music;
|
||||||
mod user;
|
mod user;
|
||||||
mod api;
|
|
||||||
|
|
||||||
use crate::config::{Args, BotConfig, GlobalData};
|
use crate::config::{Args, BotConfig, GlobalData};
|
||||||
use crate::discord::run_bot;
|
use crate::discord::run_bot;
|
||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
use magick_rust::magick_wand_genesis;
|
use magick_rust::magick_wand_genesis;
|
||||||
use std::sync::Once;
|
|
||||||
use rustls::crypto;
|
use rustls::crypto;
|
||||||
|
use std::sync::Once;
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
use tracing_core::LevelFilter;
|
use tracing_core::LevelFilter;
|
||||||
use tracing_subscriber::EnvFilter;
|
use tracing_subscriber::EnvFilter;
|
||||||
@ -27,7 +27,9 @@ static START: Once = Once::new();
|
|||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
crypto::aws_lc_rs::default_provider().install_default().expect("Unable to setup default Rustls provider");
|
crypto::aws_lc_rs::default_provider()
|
||||||
|
.install_default()
|
||||||
|
.expect("Unable to setup default Rustls provider");
|
||||||
|
|
||||||
let args: Args = Args::from_args();
|
let args: Args = Args::from_args();
|
||||||
tracing_subscriber::fmt()
|
tracing_subscriber::fmt()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user