This commit is contained in:
2021-11-13 14:12:37 +00:00
parent d8f42c1b25
commit 5230101a8d
6 changed files with 148 additions and 77 deletions

View File

@ -22,10 +22,52 @@ fn footer(ctx: &Context) -> impl FnOnce(&mut CreateEmbedFooter) -> &mut CreateEm
}
}
#[command]
#[description("Get an overview of the bot commands")]
async fn help(ctx: &Context, invoke: &mut CommandInvoke) {
let footer = footer(ctx);
let _ = invoke
.respond(
&ctx,
CreateGenericResponse::new().embed(|e| {
e.title("Help")
.color(*THEME_COLOR)
.description(
"__Info Commands__
`/help` `/info` `/donate` `/dashboard` `/clock`
*run these commands with no options*
__Reminder Commands__
`/remind` - Create a new reminder that will send a message at a certain time
`/timer` - Start a timer from now, that will count time passed. Also used to view and remove timers
__Reminder Management__
`/del` - Delete reminders
`/look` - View reminders
`/pause` - Pause all reminders on the channel
`/offset` - Move all reminders by a certain time
`/nudge` - Move all new reminders on this channel by a certain time
__Todo Commands__
`/todo` - Add, view and manage the server, channel or user todo lists
__Setup Commands__
`/timezone` - Set your timezone (necessary for `/remind` to work properly)
__Advanced Commands__
`/macro` - Record and replay command sequences
",
)
.footer(footer)
}),
)
.await;
}
#[command]
#[aliases("invite")]
#[description("Get information about the bot")]
#[group("Info")]
async fn info(ctx: &Context, invoke: &mut CommandInvoke) {
let footer = footer(ctx);

View File

@ -11,7 +11,7 @@ use regex_command_attr::command;
use serenity::{builder::CreateEmbed, client::Context, model::channel::Channel};
use crate::{
check_subscription,
check_guild_subscription, check_subscription,
component_models::{
pager::{DelPager, LookPager, Pager},
ComponentDataModel, DelSelector,
@ -164,7 +164,7 @@ async fn offset(ctx: &Context, invoke: &mut CommandInvoke, args: CommandOptions)
UPDATE reminders
INNER JOIN
`channels` ON `channels`.id = reminders.channel_id
SET reminders.`utc_time` = reminders.`utc_time` + ?
SET reminders.`utc_time` = DATE_ADD(reminders.`utc_time`, INTERVAL ? SECOND)
WHERE FIND_IN_SET(channels.`channel`, ?)",
combined_time,
channels
@ -647,7 +647,7 @@ DELETE FROM timers WHERE owner = ? AND name = ?
required = false
)]
#[arg(
name = "repeat",
name = "interval",
description = "(Patreon only) Time to wait before repeating the reminder. Leave blank for one-shot reminder",
kind = "String",
required = false
@ -666,11 +666,11 @@ DELETE FROM timers WHERE owner = ? AND name = ?
)]
#[hook(CHECK_GUILD_PERMISSIONS_HOOK)]
async fn remind(ctx: &Context, invoke: &mut CommandInvoke, args: CommandOptions) {
if args.get("repeat").is_none() && args.get("expires").is_some() {
if args.get("interval").is_none() && args.get("expires").is_some() {
let _ = invoke
.respond(
&ctx,
CreateGenericResponse::new().content("`expires` can only be used with `repeat`"),
CreateGenericResponse::new().content("`expires` can only be used with `interval`"),
)
.await;
@ -704,14 +704,21 @@ async fn remind(ctx: &Context, invoke: &mut CommandInvoke, args: CommandOptions)
.unwrap_or_default();
if list.is_empty() {
vec![ReminderScope::Channel(invoke.channel_id().0)]
if invoke.guild_id().is_some() {
vec![ReminderScope::Channel(invoke.channel_id().0)]
} else {
vec![ReminderScope::User(invoke.author_id().0)]
}
} else {
list
}
};
let (interval, expires) = if let Some(repeat) = args.get("repeat") {
if check_subscription(&ctx, invoke.author_id()).await {
let (interval, expires) = if let Some(repeat) = args.get("interval") {
if check_subscription(&ctx, invoke.author_id()).await
|| (invoke.guild_id().is_some()
&& check_guild_subscription(&ctx, invoke.guild_id().unwrap()).await)
{
(
humantime::parse_duration(&repeat.to_string())
.or_else(|_| {
@ -739,28 +746,48 @@ async fn remind(ctx: &Context, invoke: &mut CommandInvoke, args: CommandOptions)
(None, None)
};
let mut builder = MultiReminderBuilder::new(ctx, invoke.guild_id())
.author(user_data)
.content(content)
.time(time)
.expires(expires)
.interval(interval);
if interval.is_none() && args.get("interval").is_some() {
let _ = invoke
.respond(
&ctx,
CreateGenericResponse::new().content(
"Repeat interval could not be processed. Try and format the repetition similar to `1 hour` or `4 days`",
),
)
.await;
} else if expires.is_none() && args.get("expires").is_some() {
let _ = invoke
.respond(
&ctx,
CreateGenericResponse::new().content(
"Expiry time failed to process. Please make it as clear as possible",
),
)
.await;
} else {
let mut builder = MultiReminderBuilder::new(ctx, invoke.guild_id())
.author(user_data)
.content(content)
.time(time)
.expires(expires)
.interval(interval);
builder.set_scopes(scopes);
builder.set_scopes(scopes);
let (errors, successes) = builder.build().await;
let (errors, successes) = builder.build().await;
let embed = create_response(successes, errors, time);
let embed = create_response(successes, errors, time);
let _ = invoke
.respond(
&ctx,
CreateGenericResponse::new().embed(|c| {
*c = embed;
c
}),
)
.await;
let _ = invoke
.respond(
&ctx,
CreateGenericResponse::new().embed(|c| {
*c = embed;
c
}),
)
.await;
}
}
None => {
let _ = invoke

View File

@ -68,18 +68,6 @@ struct Handler;
#[async_trait]
impl EventHandler for Handler {
async fn cache_ready(&self, ctx: Context, _: Vec<GuildId>) {
let framework = ctx
.data
.read()
.await
.get::<RegexFramework>()
.cloned()
.expect("RegexFramework not found in context");
framework.build_slash(ctx).await;
}
async fn channel_delete(&self, ctx: Context, channel: &GuildChannel) {
let pool = ctx
.data
@ -210,7 +198,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
}))
.dm_enabled(dm_enabled)
// info commands
//.add_command("help", &info_cmds::HELP_COMMAND)
.add_command(&info_cmds::HELP_COMMAND)
.add_command(&info_cmds::INFO_COMMAND)
.add_command(&info_cmds::DONATE_COMMAND)
.add_command(&info_cmds::DASHBOARD_COMMAND)
@ -267,6 +255,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
data.insert::<RecordingMacros>(Arc::new(RwLock::new(HashMap::new())));
}
framework_arc.build_slash(&client.cache_and_http.http).await;
if let Ok((Some(lower), Some(upper))) = env::var("SHARD_RANGE").map(|sr| {
let mut split =
sr.split(',').map(|val| val.parse::<u64>().expect("SHARD_RANGE not an integer"));
@ -316,3 +306,16 @@ pub async fn check_subscription(cache_http: impl CacheHttp, user_id: impl Into<U
true
}
}
pub async fn check_guild_subscription(
cache_http: impl CacheHttp,
guild_id: impl Into<GuildId>,
) -> bool {
if let Some(guild) = cache_http.cache().unwrap().guild(guild_id) {
let owner = guild.owner_id;
check_subscription(&cache_http, owner).await
} else {
false
}
}