added rest of the buttons (still needs listeners) & reformatted/improved other code

This commit is contained in:
2025-06-06 15:37:06 +02:00
parent 53a1fdee19
commit c0793562e3
19 changed files with 132 additions and 105 deletions
+2
View File
@@ -1,5 +1,7 @@
### High priority:
- [ ] Reddit bot that scrapes images with tag "Original Art" and posts them in Discord server
- [ ] handle dm_on_error cfg
- [ ] Add button event listeners
- [ ] Allow updating the data autonomously and via manual commands.
- [ ] Automatically approve posts that don't get caught by reverse image search (ris)
- [ ] Make buttons do stuff
+3 -3
View File
@@ -6,10 +6,10 @@
"dc_msg_corrupted_data": "Oopsies `(。>\\\\<)`. It looks like my data i-is \\**sob*\\*... c-corrupted!\n[From Byte Dice]: I have no idea what I was thinking while writing this at 2am. I'm not removing it.",
"dc_msg_data_server_404": "This server is not in the data!\n Hint: Run the command `/add_server` inside of a Discord server (requires administrator permission).",
"dc_msg_dm_python_err_socket": "Unknown internal Python error occurred: Websocket response error",
"dc_msg_dm_python_err": "Unknown internal Python Error: {0}",
"dc_msg_dm_python_err": "Unknown internal Python Error: `{0}`",
"dc_msg_embed_default_embed_desc": "Default english embed description.",
"dc_msg_embed_re_post": "Spoilers and vote length anonymizer for fair review!\n## Post Data:\n**Post upvotes:** ||`{0:>6}`||\n**Moderator votes:** ||`{1:>6}`||\n**Media type:** `{2}`\n**URL:** ||<{3}>||\n\n## Listing Data:\n**Added by:** `{{ human: {4}, bot: {5} }}`\n**Approved by:** `{{ human: {6}, bot: [not implemented] }}`",
"dc_msg_embed_re_removed": "## Removed by `{0}`\n**Reason:** {1}\nURL: ||<{2}>||\n\nJSON: ||`{3}`||",
"dc_msg_embed_re_removed": "## Removed by `{0}`\n**Reason:** {1}\n**URL**: ||<{2}>||",
"dc_msg_err_trace": "Unknown error!\nError trace: {0}",
"dc_msg_failed_shorturl_conversion": "Couldn't convert to shortURL: Invalid Reddit URL format.",
"dc_msg_mandatory_response": "Mandatory response message, please ignore.",
@@ -25,7 +25,7 @@
"dc_msg_re_post_add_success": "Added post with URL \"<{0}>\"!",
"dc_msg_re_post_approve_success": "Successfully approved the post!",
"dc_msg_re_post_disapprove_success": "Successfully disapproved the post!",
"dc_msg_re_post_remove_success": "Successfully removed post!",
"dc_msg_re_post_remove_success": "Successfully removed post with URL \"<{0}>\"!",
"dc_msg_re_post_unremove_success": "Successfully un-removed post with URL \"<{0}>\"!",
"dc_msg_re_post_update_success": "Updated post with URL \"<{0}>\"!",
"dc_msg_re_posts_channel_404": "Could not find `re_posts_channel` in data!\nHint: Run `/admin_re_bindchannel` in a (preferably read-only) channel (requires administrator permission).",
+6 -6
View File
@@ -1,6 +1,11 @@
{
"posts": {
"EXAMPLE VALUE": {
"EXAMPLE URL": {
"removed": {
"removed": false,
"by": null,
"reason": null
},
"post_data": {
"title": "I JUST BOUGHT THE CONTINENT OF NORTH AMERICA FOR A DOLLAR!",
"upvotes": 69420,
@@ -21,11 +26,6 @@
"by_human": true,
"by_ris": true
}
},
"EXAMPLE VALUE DELETED": {
"removed": true,
"removed_by": "ME!!!!",
"remove_reason": "i HATED that post >:("
}
}
}
+1 -1
View File
@@ -19,7 +19,7 @@ pub async fn cmd(
read_cfg_data(&ctx.data(), false).await;
let d = get_mutex_data(&ctx.data().cfg).await?;
let d_str = serde_json::to_string(&d)?;
let r = send_cmd_json("update_cfg", Some(json!([d_str]))).await;
let r = send_cmd_json("update_cfg", Some(json!([d_str])), true).await;
if r.is_some() && r.unwrap()["value"].as_bool().unwrap() {
send_msg(
+1 -1
View File
@@ -26,7 +26,7 @@ pub async fn cmd(
let msg = send_msg(ctx, lang!("dc_msg_owner_data_save"), true, true).await.unwrap();
data::write_dc_data(ctx.data()).await;
data::write_re_data().await;
send_cmd_json("stop_praw", None).await;
send_cmd_json("stop_praw", None, true).await;
edit_reply(ctx, msg, lang!("dc_msg_owner_data_save_complete")).await;
ctx.serenity_context().set_presence(None, OnlineStatus::Invisible);
+3 -3
View File
@@ -103,13 +103,13 @@ fn generate_re_data() {
pub async fn update_re_data(data: &Data) {
send_cmd_json("update_data_file", None).await;
send_cmd_json("update_data_file", None, true).await;
read_re_data(data, false).await;
}
pub async fn write_re_data() {
send_cmd_json("update_data_file", None).await;
send_cmd_json("update_data_file", None, true).await;
}
@@ -127,7 +127,7 @@ pub async fn read_cfg_data(data: &Data, wipe: bool) {
let mut cfg_data = data.cfg.lock().await;
*cfg_data = json_data;
send_cmd_json("update_cfg", Some(json!([str_data]))).await;
send_cmd_json("update_cfg", Some(json!([str_data])), true).await;
}
+2 -4
View File
@@ -100,14 +100,12 @@ async fn make_cmd_vec(data: &Data) -> Vec<Cmd> {
re_cmds::top::cmd(),
re_cmds::update::cmd(),
re_cmds::vote::cmd(),
re_cmds::shorturl::cmd()
re_cmds::shorturl::cmd(),
re_cmds::admin_bind::cmd(),
]);
}
cmds.extend([
// reddit admin
re_cmds::admin_bind::cmd(),
// cfg
cmds::reload_cfg::cmd()
]);
+8 -2
View File
@@ -95,12 +95,14 @@ struct Data {
static CFG_DATA_RE: &str = "posts";
pub static mut LANG: Option<serde_json::Value> = None;
pub static mut NOPING: bool = false;
#[tokio::main]
async fn main() {
let args = <Args as clap::Parser>::parse();
let args_str = serde_json::to_string(&args).expect("Error serializing args to JSON");
unsafe { NOPING = args.noping; }
rs_println!("Fetching language file...");
data::load_lang_data(args.clone().lang);
@@ -118,6 +120,8 @@ async fn main() {
if args.dev && args.wipe { println!("----- \"DON'T WORRY ABOUT IT\" MODE ENABLED -----"); }
if args.nosched { println!("----- NO SCHEDULES -----"); }
// TODO: handle if config for reddit is disabled to not start python
if args.py && !args.rs {
println!("----- PYTHON ONLY MODE -----");
rs_println!("ARGS: {}", args_str);
@@ -174,6 +178,8 @@ async fn start(args: Args, owners: Vec<u64>) {
async fn read_reddit_inbox() {
unsafe { if !websocket::HAS_CONNECTED { return; } }
send_cmd_json("respond_mentions", None).await;
unsafe {
if !websocket::HAS_CONNECTED { return; }
send_cmd_json("respond_mentions", None, !NOPING).await;
}
}
+20 -18
View File
@@ -5,7 +5,6 @@ use crate::{lang, Args, Context};
use poise::serenity_prelude::json::Value;
use poise::{serenity_prelude::CreateMessage, CreateReply, ReplyHandle};
use poise::serenity_prelude::{ChannelId, Color, CreateActionRow, CreateButton, CreateEmbed, CreateEmbedAuthor, EditMessage, Http, Message, ReactionType, Timestamp, UserId};
use serde_json::json;
#[derive(Clone)]
@@ -48,6 +47,9 @@ impl Default for EmbedOptions {
static DEFAULT_DC_COL: u32 = 5793266;
static REMOVED_DC_COL: u32 = 16716032;
pub static JSON_TEXT_START: &str = "-# JSON: ||`";
pub static JSON_TEXT_END: &str = "`||";
fn none_to_empty(string: Option<String>) -> String {
return string.unwrap_or_default();
@@ -226,17 +228,11 @@ pub fn make_post_embed(post_data: &Value, url: &str, ephemeral: bool) -> EmbedOp
.collect::<Vec<_>>()
.join("\n");
let json_min = json!(
{"post_data": json!({ "upvotes": post_data["post_data"]["upvotes"] }),
"added": post_data["added"],
"approved": post_data["approved"],
"votes": json!({"mod_voters": post_data["votes"]["mod_voters"]})}
);
let media_urls = post_data["post_data"]["media_urls"].as_array().unwrap();
let action_row = CreateActionRow::Buttons(vec![
CreateButton::new("upvote_btn") .label("Upvote") .emoji(ReactionType::Unicode("⬆️".to_string())),
CreateButton::new("unupvote_btn") .label("Un-upvote"),
CreateButton::new("vote_btn") .label("Vote") .emoji(ReactionType::Unicode("⬆️".to_string())),
CreateButton::new("unvote_btn") .label("Un-vote"),
CreateButton::new("approve_btn") .label("Approve") .emoji(ReactionType::Unicode("".to_string())),
CreateButton::new("unapprove_btn").label("Disapprove") .emoji(ReactionType::Unicode("".to_string())),
CreateButton::new("remove_btn") .label("Remove") .emoji(ReactionType::Unicode("🗑️".to_string()))
@@ -244,7 +240,7 @@ pub fn make_post_embed(post_data: &Value, url: &str, ephemeral: bool) -> EmbedOp
return EmbedOptions {
title: Some(post_data["post_data"]["title"].as_str().unwrap().to_string()),
desc: format!("{}\n\nJSON: ||`{}`||", trimmed, serde_json::to_string(&json_min).unwrap()),
desc: format!("{}\n\n{}{}{}", trimmed, JSON_TEXT_START, serde_json::to_string(&post_data).unwrap(), JSON_TEXT_END),
col: Some(DEFAULT_DC_COL),
url: Some(url.to_string()),
ts: Some(Timestamp::from_unix_timestamp(post_data["post_data"]["date_unix"].as_i64().unwrap()).unwrap()),
@@ -259,20 +255,26 @@ pub fn make_post_embed(post_data: &Value, url: &str, ephemeral: bool) -> EmbedOp
pub fn make_removed_embed(post_data: &Value, url: &str, ephemeral: bool) -> EmbedOptions {
return EmbedOptions {
title: Some("REMOVED!".to_string()),
desc: lang!(
let action_row = CreateActionRow::Buttons(vec![
CreateButton::new("unremove_btn").label("Un-remove").emoji(ReactionType::Unicode("↩️".to_string()))
]);
let desc = lang!(
"dc_msg_embed_re_removed",
post_data["removed_by"].as_str().unwrap(),
if !post_data["remove_reason"].is_null() { post_data["remove_reason"].as_str().unwrap() }
post_data["removed"]["by"].as_str().unwrap(),
if !post_data["removed"]["reason"].is_null() { post_data["removed"]["reason"].as_str().unwrap() }
else { "None" },
url,
serde_json::to_string(&post_data).unwrap()
),
url
);
return EmbedOptions {
title: Some(format!("[REMOVED] {}", post_data["post_data"]["title"])),
desc: format!("{}\n\n{}{}{}", desc, JSON_TEXT_START, serde_json::to_string(&post_data).unwrap(), JSON_TEXT_END),
col: Some(REMOVED_DC_COL),
url: Some(url.to_string()),
ts: Some(Timestamp::from_unix_timestamp(post_data["post_data"]["date_unix"].as_i64().unwrap()).unwrap()),
ephemeral,
actionrows: Some(vec![action_row]),
..Default::default()
};
}
+25 -20
View File
@@ -18,6 +18,9 @@ class PostData:
date_unix: int,
media_type: str,
media_urls: list[str],
removed: bool = False,
removed_by: str | None = None,
removed_reason: str | None = None,
voters_re: list[str] = [],
voters_dc: list[int] = [],
mod_voters: list[int] = [],
@@ -26,6 +29,9 @@ class PostData:
approved_by_human: bool = False,
approved_by_ris: bool = False
):
self.removed = removed
self.removed_by = removed_by
self.removed_reason = removed_reason
self.url = url
self.title = title
self.upvotes = upvotes
@@ -42,6 +48,11 @@ class PostData:
def to_json(self):
return {
"removed": {
"removed": self.removed,
"by": self.removed_reason,
"reason": self.removed_reason
},
"post_data": {
"title": self.title,
"upvotes": self.upvotes,
@@ -125,31 +136,26 @@ async def read_cfg(bot: botPy.Bot) -> bool:
def add_post_to_data(bot: botPy.Bot, new_data: PostData, bypass_conditions: bool = False) -> bool:
if new_data.removed:
new_data.removed = False
new_data.removed_by = None
new_data.removed_reason = None
if bypass_conditions:
bot.data[botPy.RE_DATA_POSTS][new_data.url] = new_data.to_json()
if bot.args["dev"]:
py_print(f"Added post \"{new_data.url}\" (Conditions bypassed)")
if bot.args["dev"]: py_print(f"Added post \"{new_data.url}\" (Conditions bypassed)")
return True
# not sure what this is for
updated = False
if new_data.url not in bot.data[botPy.RE_DATA_POSTS] or updated:
if new_data.url not in bot.data[botPy.RE_DATA_POSTS]:
bot.data[botPy.RE_DATA_POSTS][new_data.url] = new_data.to_json()
if bot.args["dev"]:
py_print(f"Added post \"{new_data.url}\"")
if bot.args["dev"]: py_print(f"Added post \"{new_data.url}\"")
return True
if "removed" not in bot.data[botPy.RE_DATA_POSTS][new_data.url]:
updated = new_data.upvotes != bot.data[botPy.RE_DATA_POSTS][new_data.url]["post_data"]
else:
py_print(f"Failed to add post \"{new_data.url}\": Removed flag is True.")
return False
def set_approve_post(bot: botPy.Bot, approved: bool, url: str) -> bool:
if not hasattr(bot.data[botPy.RE_DATA_POSTS][url], "removed"):
if not bot.data[botPy.RE_DATA_POSTS][url]["removed"]["removed"]:
bot.data[botPy.RE_DATA_POSTS][url]["approved"]["by_human"] = approved
return True
@@ -160,12 +166,11 @@ def remove_post(bot: botPy.Bot, url: str, removed_by: str = "UNKNOWN", reason: s
weekly = bot.data[botPy.RE_DATA_POSTS]
if url in weekly:
weekly[url] = {
"removed": True,
"removed_by": removed_by,
"remove_reason": reason,
"post_data": { "date_unix": weekly[url]["post_data"]["date_unix"] }
}
rm = weekly[url]["removed"]
rm["removed"] = True
rm["by"] = removed_by
rm["reason"] = reason
weekly[url]["removed"] = rm
return True
else:
return False
+7 -5
View File
@@ -46,7 +46,7 @@ async def parse_json(response: str, bot: botPy.Bot):
try:
json_response = json.loads(json_str)
if json_response["value"] not in ["respond_mentions"] or bot.args["dev"]:
py_print(f"Received from Rust: {response}")
if json_response["print"]: py_print(f"Received from Rust: {response}")
result = await json_to_func(json_response, bot)
await ws_global.ping()
@@ -86,13 +86,15 @@ async def json_to_func(v: dict, bot: botPy.Bot) -> dict:
case "stop_praw": r = await bot .stop ()
case _: value_supported = False
print_result = v["print"]
if not value_supported:
val = v["value"]
py_print(f"Value \"{val}\" is not supported")
return {"type": "result", "value": False}
return result_json(False, print_result)
return result_json(r)
return result_json(r, print_result)
def result_json(bool: bool) -> dict:
return {"type": "result", "value": bool}
def result_json(bool: bool, print_result: bool) -> dict:
return {"type": "result", "value": bool, "print": print_result}
+12 -14
View File
@@ -2,8 +2,9 @@ use serde_json::json;
use crate::data::get_mutex_data;
use crate::messages::send_msg;
use crate::{data, websocket, Context, Error, CFG_DATA_RE};
use crate::re_cmds::generic_fns::{get_readable_subreddits, is_bk_mod, to_shorturl};
use crate::re_cmds::get::get_post_from_data;
use crate::{data, websocket::send_cmd_json, Context, Error, CFG_DATA_RE};
use crate::re_cmds::generic_fns::{get_readable_subreddits, is_bk_mod, send_embed_for_post, to_shorturl};
use crate::lang;
#[poise::command(
@@ -34,7 +35,7 @@ pub async fn cmd(
if let Some(bk_week) = reddit_data.get(CFG_DATA_RE) {
let a = approve.unwrap_or(false);
let r = websocket::send_cmd_json("add_post_url", Some(json!([&shorturl, a, true]))).await.unwrap();
let r = send_cmd_json("add_post_url", Some(json!([&shorturl, a, true])), true).await.unwrap();
if !r["value"].as_bool().unwrap() {
send_msg(
@@ -49,20 +50,17 @@ pub async fn cmd(
}
if let Some(post) = bk_week.get(shorturl) {
if post.get("removed").is_some() {
send_msg(ctx, lang!("dc_msg_re_post_unremove_success", url), true, true).await;
if post["removed"]["removed"].as_bool().unwrap()
{ send_msg(ctx, lang!("dc_msg_re_post_unremove_success", &shorturl), true, true).await; }
else { send_msg(ctx, lang!("dc_msg_re_post_update_success", &shorturl), true, true).await; }
}
else {
send_msg(ctx, lang!("dc_msg_re_post_update_success", url), true, true).await;
}
}
else {
send_msg(ctx, lang!("dc_msg_re_post_add_success", &shorturl), true, true).await;
else { send_msg(ctx, lang!("dc_msg_re_post_add_success", &shorturl), true, true).await; }
if a { send_msg(ctx, lang!("dc_msg_re_also_approved"), true, true).await; }
}
if a {
send_msg(ctx, lang!("dc_msg_re_also_approved"), true, true).await;
}
if let Some(post) = get_post_from_data(ctx, &reddit_data, &url).await? {
send_embed_for_post(ctx, post, &url).await?;
}
return Ok(());
+1 -1
View File
@@ -40,7 +40,7 @@ async fn approve_cmd(ctx: Context<'_>, url: &str, reddit_data: &Value, approve:
return;
}
let r = websocket::send_cmd_json("set_approve_post", Some(json!([approve, &url]))).await.unwrap();
let r = websocket::send_cmd_json("set_approve_post", Some(json!([approve, &url])), true).await.unwrap();
if r.get("value").is_some() {
if approve {
send_msg(ctx, lang!("dc_msg_re_post_approve_success"), true, true).await;
+1 -1
View File
@@ -36,7 +36,7 @@ pub async fn send_embed_for_removed(ctx: Context<'_>, url: &str, post: &Value) {
pub async fn get_readable_subreddits(ctx: Context<'_>) -> Result<String, Error> {
let d = get_mutex_data(&ctx.data().cfg).await?;
let sr = d["reddit"]["subreddits"].as_str().ok_or("Item of key \"subreddit\" is not a string type.\nTrace: get_readable_subreddits -> let sr = ...")?;
let sr = d["reddit"]["subreddits"].as_str().ok_or("Item of key \"subreddit\" is not a string type.\nTrace: `get_readable_subreddits -> let sr = ...`")?;
let split: Vec<&str> = sr.split("+").collect();
let join = split.join(", r/");
+2 -2
View File
@@ -29,10 +29,10 @@ pub async fn cmd(
}
async fn get_post_from_data(ctx: Context<'_>, reddit_data: &Value, url: &str) -> Result<Option<Value>, Error> {
pub async fn get_post_from_data(ctx: Context<'_>, reddit_data: &Value, url: &str) -> Result<Option<Value>, Error> {
if let Some(bk_week) = reddit_data.get(CFG_DATA_RE) {
if let Some(post) = bk_week.get(url) {
if post.get("removed").is_some() {
if post["removed"]["removed"].as_bool().unwrap() {
send_embed_for_removed(ctx, url, post).await;
return Ok(None);
}
+12 -3
View File
@@ -1,6 +1,6 @@
use serde_json::json;
use crate::{lang, messages::send_msg, re_cmds::generic_fns::{get_readable_subreddits, is_bk_mod}, websocket::send_cmd_json, Context, Error};
use crate::{data::{self, get_mutex_data}, lang, messages::send_msg, re_cmds::{generic_fns::{get_readable_subreddits, is_bk_mod, send_embed_for_removed}, get::get_post_from_data}, websocket::send_cmd_json, Context, Error};
#[poise::command(
slash_command,
@@ -23,12 +23,12 @@ pub async fn cmd(
}
let auth = &ctx.author().name;
let r = send_cmd_json("remove_post_url", Some(json!([&url, &auth, &reason]))).await.unwrap();
let r = send_cmd_json("remove_post_url", Some(json!([&url, &auth, &reason])), true).await.unwrap();
if r["value"].as_bool().unwrap() {
send_msg(
ctx,
lang!("dc_msg_re_post_remove_success"),
lang!("dc_msg_re_post_remove_success", &url),
true,
true
).await;
@@ -37,5 +37,14 @@ pub async fn cmd(
send_msg(ctx, lang!("dc_msg_re_post_404"), false, false).await;
}
data::update_re_data(ctx.data()).await;
let reddit_data = get_mutex_data(&ctx.data().reddit_data).await?;
if let Some(post) = get_post_from_data(ctx, &reddit_data, &url).await? {
if post["removed"]["removed"].as_bool().unwrap() {
send_embed_for_removed(ctx, &url, &post).await;
}
}
return Ok(());
}
+4 -4
View File
@@ -3,7 +3,7 @@ use std::time::{SystemTime, UNIX_EPOCH};
use poise::{serenity_prelude::{ChannelId, EditMessage, GetMessages, Http, Message, MessageId, UserId}, ReplyHandle};
use serde_json::{json, Map, Value};
use crate::{data::{self, get_mutex_data, DC_POSTS_CHANNEL_KEY}, lang, messages::{edit_reply, embed_from_options, http_send_embed, make_post_embed, make_removed_embed, send_msg}, websocket::send_cmd_json, Context, Error, CFG_DATA_RE};
use crate::{data::{self, get_mutex_data, DC_POSTS_CHANNEL_KEY}, lang, messages::{edit_reply, embed_from_options, http_send_embed, make_post_embed, make_removed_embed, send_msg, JSON_TEXT_END, JSON_TEXT_START}, websocket::send_cmd_json, Context, Error, CFG_DATA_RE};
#[poise::command(
slash_command,
@@ -35,7 +35,7 @@ pub async fn cmd(
let max_age_u = max_age.unwrap_or(8);
let max_age_secs = max_age_u as u64 * (60 * 60 * 24);
send_cmd_json("add_new_posts", Some(json!([max_age_secs]))).await;
send_cmd_json("add_new_posts", Some(json!([max_age_secs])), true).await;
data::update_re_data(ctx.data()).await;
let r_data = get_mutex_data(&ctx.data().reddit_data).await?;
@@ -80,7 +80,7 @@ pub async fn cmd(
if max_age_u > 0 {
p_text = update_progress(ctx, progress.clone(), p_text.clone(), format!("\nRemoving old posts (threshold: {}d)...", max_age_u)).await;
remove_old(http, c_id, &msgs_json).await;
send_cmd_json("remove_old_posts", Some(json!([max_age_secs]))).await;
send_cmd_json("remove_old_posts", Some(json!([max_age_secs])), true).await;
}
// Removing duplicate posts
@@ -181,7 +181,7 @@ async fn msgs_to_json(msgs: Vec<Message>, reddit_data: &Value, max_age: u64) ->
if msg_last_len < 13 { continue; }
let msg_json_str = &msg_lines.clone().last().unwrap()[9..msg_last_len - 3];
let msg_json_str = &msg_lines.clone().last().unwrap()[JSON_TEXT_START.len()..msg_last_len - JSON_TEXT_END.len()];
let msg_json = serde_json::from_str(msg_json_str);
if msg_json.is_err() { continue; }
+1 -1
View File
@@ -47,7 +47,7 @@ pub async fn cmd(
return Ok(());
}
let r = send_cmd_json("set_vote_post", Some(json!([url, uid, is_mod, true, unw_vote]))).await.unwrap();
let r = send_cmd_json("set_vote_post", Some(json!([url, uid, is_mod, true, unw_vote])), true).await.unwrap();
let unw_r = r["value"].as_bool().unwrap();
if unw_r && !unw_vote && is_mod {
+7 -2
View File
@@ -47,7 +47,7 @@ pub async fn send_msg(msg: &str) {
#[allow(static_mut_refs)]
pub async fn send_cmd_json(func_name: &str, func_args: Option<Value>) -> Option<Value> {
pub async fn send_cmd_json(func_name: &str, func_args: Option<Value>, print_output: bool) -> Option<Value> {
unsafe {
let Some(sender) = &GLOBAL_SENDER else { return None };
let mut sender = sender.lock().await;
@@ -56,7 +56,7 @@ pub async fn send_cmd_json(func_name: &str, func_args: Option<Value>) -> Option<
let unw_args = func_args.unwrap_or(json!([]));
let json_str = format!(
"json:{{\"type\": \"function\", \"value\":\"{}\", \"args\": {}}}",
"json:{{\"type\": \"function\", \"value\":\"{}\", \"args\": {}, \"print\": {print_output}}}",
func_name, unw_args
);
@@ -65,6 +65,11 @@ pub async fn send_cmd_json(func_name: &str, func_args: Option<Value>) -> Option<
}
let r = receive_response().await;
if let Some(rs) = r.clone() {
if !rs.get("print").unwrap_or(&json![false]).as_bool().unwrap()
{ return r; }
}
if !["respond_mentions"].contains(&func_name) || <Args as clap::Parser>::parse().dev {
rs_println!("Received from Python: [RESPONSE] {:?}", r);
}