feat: send category
This commit is contained in:
parent
18eba1d443
commit
e739c443ac
7 changed files with 53 additions and 13 deletions
|
|
@ -46,6 +46,7 @@ impl Handler {
|
||||||
사용 가능 변수:
|
사용 가능 변수:
|
||||||
- `reactions`: map<string, i64> (이모지 - 개수)
|
- `reactions`: map<string, i64> (이모지 - 개수)
|
||||||
- `channel`: string (채널 ID)
|
- `channel`: string (채널 ID)
|
||||||
|
- `category`: string (카테고리 ID, 없을 시 UNIT)
|
||||||
|
|
||||||
`result("채널ID", 리액션 개수, "메시지에 사용될 아이콘(이모지 권장)")` 를 리턴해주세요(unit이나 다른 값 반환 시 무시됩니다)
|
`result("채널ID", 리액션 개수, "메시지에 사용될 아이콘(이모지 권장)")` 를 리턴해주세요(unit이나 다른 값 반환 시 무시됩니다)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ use serde::Deserialize;
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
|
pub debug: Option<bool>,
|
||||||
pub bot: BotConfig,
|
pub bot: BotConfig,
|
||||||
pub db: DatabaseConfig,
|
pub db: DatabaseConfig,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,14 @@ use sqlx::prelude::FromRow;
|
||||||
|
|
||||||
#[derive(Debug, FromRow)]
|
#[derive(Debug, FromRow)]
|
||||||
pub struct GuildRow {
|
pub struct GuildRow {
|
||||||
pub id: String,
|
// pub id: String,
|
||||||
pub script: Option<String>,
|
pub script: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, FromRow)]
|
#[derive(Debug, FromRow)]
|
||||||
pub struct MessageRow {
|
pub struct MessageRow {
|
||||||
// pub guild_id: String,
|
// pub guild_id: String,
|
||||||
pub message_id: String,
|
// pub message_id: String,
|
||||||
pub counter_id: String,
|
pub counter_id: String,
|
||||||
pub counter_channel_id: String,
|
pub counter_channel_id: String,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@ use serenity::{
|
||||||
Attachment, CacheHttp, ChannelId, Component, Context, CreateComponent, CreateMediaGallery,
|
Attachment, CacheHttp, ChannelId, Component, Context, CreateComponent, CreateMediaGallery,
|
||||||
CreateMediaGalleryItem, CreateSeparator, CreateTextDisplay, CreateUnfurledMediaItem,
|
CreateMediaGalleryItem, CreateSeparator, CreateTextDisplay, CreateUnfurledMediaItem,
|
||||||
CreateWebhook, EditWebhookMessage, EventHandler, ExecuteWebhook, FullEvent,
|
CreateWebhook, EditWebhookMessage, EventHandler, ExecuteWebhook, FullEvent,
|
||||||
GenericChannelId, GuildId, Interaction, InteractionType, Message, MessageFlags, MessageId,
|
GenericChannelId, GuildId, Interaction, Message, MessageFlags, MessageId, MessageSnapshot,
|
||||||
MessageSnapshot, Reaction, StickerFormatType, StickerItem, Webhook, WebhookId,
|
Reaction, StickerFormatType, StickerItem, Webhook, WebhookId,
|
||||||
},
|
},
|
||||||
async_trait,
|
async_trait,
|
||||||
futures::lock::Mutex,
|
futures::lock::Mutex,
|
||||||
|
|
@ -151,12 +151,28 @@ impl Handler {
|
||||||
CloneBuilderMessage::from(msg.clone())
|
CloneBuilderMessage::from(msg.clone())
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(result) =
|
let channel = reaction.channel(&ctx.http).await?;
|
||||||
paringboard::script::check(script, reactions, reaction.channel_id.to_string())?
|
|
||||||
|
debug!("channel: {channel:?}");
|
||||||
|
|
||||||
|
let Some(result) = paringboard::script::check(
|
||||||
|
script,
|
||||||
|
reactions,
|
||||||
|
reaction.channel_id.to_string(),
|
||||||
|
channel
|
||||||
|
.guild()
|
||||||
|
.and_then(|x| x.parent_id)
|
||||||
|
.map(|x| x.to_string()),
|
||||||
|
)
|
||||||
|
.inspect_err(|res| {
|
||||||
|
error!("check failed: {res:?}");
|
||||||
|
})?
|
||||||
else {
|
else {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
debug!("check result: {result:?}");
|
||||||
|
|
||||||
let channel_id = result
|
let channel_id = result
|
||||||
.channel_id
|
.channel_id
|
||||||
.parse()
|
.parse()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use std::{str::FromStr, sync::Arc};
|
use std::{str::FromStr, sync::Arc};
|
||||||
|
|
||||||
|
use crate::{config::Config, handler::Handler};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
use figment::{
|
use figment::{
|
||||||
|
|
@ -12,8 +13,7 @@ use serenity::{
|
||||||
all::{GatewayIntents, Token},
|
all::{GatewayIntents, Token},
|
||||||
};
|
};
|
||||||
use sqlx::{migrate, postgres::PgPoolOptions};
|
use sqlx::{migrate, postgres::PgPoolOptions};
|
||||||
|
use tracing::Level;
|
||||||
use crate::{config::Config, handler::Handler};
|
|
||||||
|
|
||||||
mod commands;
|
mod commands;
|
||||||
mod config;
|
mod config;
|
||||||
|
|
@ -26,7 +26,7 @@ extern crate tracing;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
||||||
tracing_subscriber::fmt::init();
|
let mut fmt = tracing_subscriber::fmt();
|
||||||
|
|
||||||
let figment = Figment::new()
|
let figment = Figment::new()
|
||||||
.merge(Toml::file("config.toml"))
|
.merge(Toml::file("config.toml"))
|
||||||
|
|
@ -34,6 +34,12 @@ async fn main() -> anyhow::Result<()> {
|
||||||
|
|
||||||
let config: Config = figment.extract()?;
|
let config: Config = figment.extract()?;
|
||||||
|
|
||||||
|
if config.debug.unwrap_or(false) {
|
||||||
|
fmt = fmt.with_max_level(Level::DEBUG);
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.init();
|
||||||
|
|
||||||
info!("config: {config:?}");
|
info!("config: {config:?}");
|
||||||
|
|
||||||
let db = PgPoolOptions::new()
|
let db = PgPoolOptions::new()
|
||||||
|
|
@ -49,7 +55,9 @@ async fn main() -> anyhow::Result<()> {
|
||||||
|
|
||||||
let mut client = Client::builder(
|
let mut client = Client::builder(
|
||||||
Token::from_str(config.bot.token.expose_secret()).unwrap(),
|
Token::from_str(config.bot.token.expose_secret()).unwrap(),
|
||||||
GatewayIntents::GUILD_MESSAGES | GatewayIntents::GUILD_MESSAGE_REACTIONS,
|
GatewayIntents::GUILD_MESSAGES
|
||||||
|
| GatewayIntents::GUILD_MESSAGE_REACTIONS
|
||||||
|
| GatewayIntents::GUILDS,
|
||||||
)
|
)
|
||||||
.event_handler(Arc::new(Handler {
|
.event_handler(Arc::new(Handler {
|
||||||
db,
|
db,
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
use anyhow::Context as _;
|
use anyhow::Context as _;
|
||||||
use serenity::all::{
|
use serenity::all::{
|
||||||
Component, Context, CreateInteractionResponseMessage, Label, LabelComponent, ModalInteraction,
|
Component, Context, CreateInteractionResponseMessage, LabelComponent, ModalInteraction,
|
||||||
Permissions,
|
Permissions,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{db, handler::Handler};
|
use crate::handler::Handler;
|
||||||
|
|
||||||
impl Handler {
|
impl Handler {
|
||||||
pub async fn process_modal(
|
pub async fn process_modal(
|
||||||
|
|
@ -54,8 +54,8 @@ impl Handler {
|
||||||
.context("unable to get value text from input")?;
|
.context("unable to get value text from input")?;
|
||||||
|
|
||||||
sqlx::query("insert into guilds (id, script) values ($1, $2) on conflict (id) do update set script = excluded.script")
|
sqlx::query("insert into guilds (id, script) values ($1, $2) on conflict (id) do update set script = excluded.script")
|
||||||
.bind(value.as_str())
|
|
||||||
.bind(guild_id.to_string())
|
.bind(guild_id.to_string())
|
||||||
|
.bind(value.as_str())
|
||||||
.execute(&self.db)
|
.execute(&self.db)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ use std::collections::HashMap;
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use rhai::{Dynamic, Engine, Map, Scope};
|
use rhai::{Dynamic, Engine, Map, Scope};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
use tracing::debug;
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Clone)]
|
#[derive(Debug, Deserialize, Clone)]
|
||||||
pub struct ReactionResult {
|
pub struct ReactionResult {
|
||||||
|
|
@ -15,7 +16,9 @@ pub fn check(
|
||||||
script: &str,
|
script: &str,
|
||||||
reactions: HashMap<String, i64>,
|
reactions: HashMap<String, i64>,
|
||||||
channel: String,
|
channel: String,
|
||||||
|
category: Option<String>,
|
||||||
) -> anyhow::Result<Option<ReactionResult>> {
|
) -> anyhow::Result<Option<ReactionResult>> {
|
||||||
|
debug!("script: {script}");
|
||||||
let mut engine = Engine::new();
|
let mut engine = Engine::new();
|
||||||
engine.set_max_operations(1000);
|
engine.set_max_operations(1000);
|
||||||
engine.register_type::<ReactionResult>();
|
engine.register_type::<ReactionResult>();
|
||||||
|
|
@ -45,10 +48,21 @@ pub fn check(
|
||||||
scope.set_value("reactions", Dynamic::from(emotes_input));
|
scope.set_value("reactions", Dynamic::from(emotes_input));
|
||||||
scope.set_value("channel", Dynamic::from(channel));
|
scope.set_value("channel", Dynamic::from(channel));
|
||||||
|
|
||||||
|
scope.set_value(
|
||||||
|
"category",
|
||||||
|
if let Some(value) = category {
|
||||||
|
Dynamic::from(value)
|
||||||
|
} else {
|
||||||
|
Dynamic::UNIT
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
let result: Dynamic = engine
|
let result: Dynamic = engine
|
||||||
.eval_with_scope(&mut scope, script)
|
.eval_with_scope(&mut scope, script)
|
||||||
.map_err(|e| anyhow!("{e:?}"))?;
|
.map_err(|e| anyhow!("{e:?}"))?;
|
||||||
|
|
||||||
|
debug!("result: {result:?}");
|
||||||
|
|
||||||
let result: Option<ReactionResult> = if result.is_unit() {
|
let result: Option<ReactionResult> = if result.is_unit() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue