Change reminder sending behaviour to keep reminders but flag them as sent

This commit is contained in:
jude 2023-07-31 18:39:27 +01:00
parent db1a53a797
commit 902b7e1b4a
7 changed files with 67 additions and 22 deletions

View File

@ -5,7 +5,7 @@ export $(grep -v '^#' /etc/reminder-rs/config.env | xargs -d '\n')
REGEX='mysql://([A-Za-z]+)@(.+)/(.+)'
[[ $DATABASE_URL =~ $REGEX ]]
VAR=$(mysql -u "${BASH_REMATCH[1]}" -h "${BASH_REMATCH[2]}" -N -D "${BASH_REMATCH[3]}" -e "SELECT COUNT(1) FROM reminders WHERE utc_time < NOW() - INTERVAL 10 MINUTE AND enabled = 1")
VAR=$(mysql -u "${BASH_REMATCH[1]}" -h "${BASH_REMATCH[2]}" -N -D "${BASH_REMATCH[3]}" -e "SELECT COUNT(1) FROM reminders WHERE utc_time < NOW() - INTERVAL 10 MINUTE AND enabled = 1 AND status = 'pending'")
if [ "$VAR" -gt 0 ]
then

View File

@ -0,0 +1,2 @@
ALTER TABLE reminders ADD COLUMN `status` ENUM ('pending', 'sent', 'failed', 'deleted') NOT NULL DEFAULT 'pending';
ALTER TABLE reminders ADD COLUMN `status_message` TEXT;

View File

@ -302,6 +302,7 @@ INNER JOIN
ON
reminders.channel_id = channels.id
WHERE
reminders.`status` = 'pending' AND
reminders.`id` IN (
SELECT
MIN(id)
@ -358,7 +359,7 @@ WHERE
&& self.interval_days == Some(0)
&& self.interval_months == Some(0)
{
self.force_delete(pool).await;
self.set_sent(pool).await;
}
let now = Utc::now();
@ -408,9 +409,9 @@ WHERE
None::<&'static str>,
)
.await;
self.force_delete(pool).await;
self.set_failed(pool, "Failed to update 4 times and so is being deleted").await;
} else if self.expires.map_or(false, |expires| updated_reminder_time > expires) {
self.force_delete(pool).await;
self.set_sent(pool).await;
} else {
sqlx::query!(
"UPDATE reminders SET `utc_time` = ? WHERE `id` = ?",
@ -422,7 +423,7 @@ WHERE
.expect(&format!("Could not update time on Reminder {}", self.id));
}
} else {
self.force_delete(pool).await;
self.set_sent(pool).await;
}
}
@ -468,13 +469,28 @@ WHERE
}
}
async fn force_delete(&self, pool: impl Executor<'_, Database = Database> + Copy) {
sqlx::query!("DELETE FROM reminders WHERE `id` = ?", self.id)
async fn set_sent(&self, pool: impl Executor<'_, Database = Database> + Copy) {
sqlx::query!("UPDATE reminders SET `status` = 'sent' WHERE `id` = ?", self.id)
.execute(pool)
.await
.expect(&format!("Could not delete Reminder {}", self.id));
}
async fn set_failed(
&self,
pool: impl Executor<'_, Database = Database> + Copy,
message: &'static str,
) {
sqlx::query!(
"UPDATE reminders SET `status` = 'failed', `status_message` = ? WHERE `id` = ?",
message,
self.id
)
.execute(pool)
.await
.expect(&format!("Could not delete Reminder {}", self.id));
}
async fn pin_message<M: Into<u64>>(&self, message_id: M, http: impl AsRef<Http>) {
let _ = http.as_ref().pin_message(self.channel_id, message_id.into(), None).await;
}
@ -649,7 +665,11 @@ WHERE
None::<&'static str>,
)
.await;
self.force_delete(pool).await;
self.set_failed(
pool,
"Could not be sent as channel does not exist",
)
.await;
}
10004 => {
self.log_error(
@ -658,7 +678,8 @@ WHERE
None::<&'static str>,
)
.await;
self.force_delete(pool).await;
self.set_failed(pool, "Could not be sent as guild does not exist")
.await;
}
50001 => {
self.log_error(
@ -667,7 +688,11 @@ WHERE
None::<&'static str>,
)
.await;
self.force_delete(pool).await;
self.set_failed(
pool,
"Could not be sent as permissions are invalid",
)
.await;
}
50007 => {
self.log_error(
@ -676,7 +701,8 @@ WHERE
None::<&'static str>,
)
.await;
self.force_delete(pool).await;
self.set_failed(pool, "Could not be sent as user has DMs disabled")
.await;
}
_ => {
self.log_error(

View File

@ -168,10 +168,13 @@ impl ComponentDataModel {
ComponentDataModel::DelSelector(selector) => {
let selected_id = component.data.values.join(",");
sqlx::query!("DELETE FROM reminders WHERE FIND_IN_SET(id, ?)", selected_id)
.execute(&data.database)
.await
.unwrap();
sqlx::query!(
"UPDATE reminders SET `status` = 'pending' WHERE FIND_IN_SET(id, ?)",
selected_id
)
.execute(&data.database)
.await
.unwrap();
let reminders = Reminder::from_guild(
&ctx,

View File

@ -159,6 +159,7 @@ LEFT JOIN
ON
reminders.set_by = users.id
WHERE
`status` = 'pending' AND
channels.channel = ? AND
FIND_IN_SET(reminders.enabled, ?)
ORDER BY
@ -217,6 +218,7 @@ LEFT JOIN
ON
reminders.set_by = users.id
WHERE
`status` = 'pending' AND
FIND_IN_SET(channels.channel, ?)
",
channels
@ -251,6 +253,7 @@ LEFT JOIN
ON
reminders.set_by = users.id
WHERE
`status` = 'pending' AND
channels.guild_id = (SELECT id FROM guilds WHERE guild = ?)
",
guild_id.as_u64()
@ -286,6 +289,7 @@ LEFT JOIN
ON
reminders.set_by = users.id
WHERE
`status` = 'pending' AND
channels.id = (SELECT dm_channel FROM users WHERE user = ?)
",
user.as_u64()
@ -300,7 +304,10 @@ WHERE
&self,
db: impl Executor<'_, Database = Database>,
) -> Result<(), sqlx::Error> {
sqlx::query!("DELETE FROM reminders WHERE uid = ?", self.uid).execute(db).await.map(|_| ())
sqlx::query!("UPDATE reminders SET `status` = 'deleted' WHERE uid = ?", self.uid)
.execute(db)
.await
.map(|_| ())
}
pub fn display_content(&self) -> &str {

View File

@ -45,7 +45,7 @@ pub async fn bot_data(cookies: &CookieJar<'_>, pool: &State<Pool<MySql>>) -> Jso
}
let backlog = sqlx::query!(
"SELECT COUNT(1) AS backlog FROM reminders WHERE `utc_time` < NOW() AND enabled = 1"
"SELECT COUNT(1) AS backlog FROM reminders WHERE `utc_time` < NOW() AND enabled = 1 AND `status` = 'pending'"
)
.fetch_one(pool.inner())
.await
@ -61,6 +61,7 @@ pub async fn bot_data(cookies: &CookieJar<'_>, pool: &State<Pool<MySql>>) -> Jso
`utc_time` < DATE_ADD(NOW(), INTERVAL 1 DAY) AND
`utc_time` >= NOW() AND
`enabled` = 1 AND
`status` = 'pending' AND
`interval_seconds` IS NULL AND
`interval_months` IS NULL AND
`interval_days` IS NULL
@ -80,6 +81,7 @@ pub async fn bot_data(cookies: &CookieJar<'_>, pool: &State<Pool<MySql>>) -> Jso
WHERE
`utc_time` < DATE_ADD(NOW(), INTERVAL 1 DAY) AND
`utc_time` >= NOW() AND
`status` = 'pending' AND
`enabled` = 1 AND (
`interval_seconds` IS NOT NULL OR
`interval_months` IS NOT NULL OR
@ -102,6 +104,7 @@ pub async fn bot_data(cookies: &CookieJar<'_>, pool: &State<Pool<MySql>>) -> Jso
`utc_time` < DATE_ADD(NOW(), INTERVAL 31 DAY) AND
`utc_time` >= NOW() AND
`enabled` = 1 AND
`status` = 'pending' AND
`interval_seconds` IS NULL AND
`interval_months` IS NULL AND
`interval_days` IS NULL
@ -121,6 +124,7 @@ pub async fn bot_data(cookies: &CookieJar<'_>, pool: &State<Pool<MySql>>) -> Jso
WHERE
`utc_time` < DATE_ADD(NOW(), INTERVAL 31 DAY) AND
`utc_time` >= NOW() AND
`status` = 'pending' AND
`enabled` = 1 AND (
`interval_seconds` IS NOT NULL OR
`interval_months` IS NOT NULL OR
@ -169,9 +173,11 @@ pub async fn bot_data(cookies: &CookieJar<'_>, pool: &State<Pool<MySql>>) -> Jso
"SELECT COUNT(1) AS count
FROM reminders
WHERE
`interval_seconds` IS NOT NULL OR
`interval_months` IS NOT NULL OR
`interval_days` IS NOT NULL"
`status` = 'pending' AND (
`interval_seconds` IS NOT NULL OR
`interval_months` IS NOT NULL OR
`interval_days` IS NOT NULL
)"
)
.fetch_one(pool.inner())
.await
@ -181,6 +187,7 @@ pub async fn bot_data(cookies: &CookieJar<'_>, pool: &State<Pool<MySql>>) -> Jso
"SELECT COUNT(1) AS count
FROM reminders
WHERE
`status` = 'pending' AND
`interval_seconds` IS NULL AND
`interval_months` IS NULL AND
`interval_days` IS NULL"

View File

@ -362,7 +362,7 @@ pub async fn get_reminders(
reminders.utc_time
FROM reminders
LEFT JOIN channels ON channels.id = reminders.channel_id
WHERE FIND_IN_SET(channels.channel, ?)",
WHERE `status` = 'pending' AND FIND_IN_SET(channels.channel, ?)",
channels
)
.fetch_all(pool.inner())
@ -602,7 +602,7 @@ pub async fn delete_reminder(
reminder: Json<DeleteReminder>,
pool: &State<Pool<MySql>>,
) -> JsonResult {
match sqlx::query!("DELETE FROM reminders WHERE uid = ?", reminder.uid)
match sqlx::query!("UPDATE reminders SET `status` = 'deleted' WHERE uid = ?", reminder.uid)
.execute(pool.inner())
.await
{