Forget-Me-Not/helpers/reminder.nim

91 lines
4.0 KiB
Nim
Raw Normal View History

2025-05-15 08:01:35 -05:00
import std/[times, osproc, strutils], smtp
import ../models/reminder, ../models/user, datetime
proc setFutureSendDate(reminderId: int) =
var reminder: Reminder
reminder = getReminderById(reminderId)
var newSendDate: DateTime
case reminder.repeatFreq:
of "day":
newSendDate = now() + 1.days
reminder.sendDate = $format(newSendDate, "yyyy-MM-dd")
updateReminderSendDate(reminder)
of "week":
newSendDate = nextWeekday(reminder.weeklyOn)
reminder.sendDate = $format(newSendDate, "yyyy-MM-dd")
updateReminderSendDate(reminder)
of "month":
if reminder.monthlyOnDay > 0:
#create DateTime with current month and year and reminder.monthlyOnDay
newSendDate = dateTime(year(now()), month(now()), reminder.monthlyOnDay)
#add 1 month only if monthlyOnDay hasn't occured in current month yet.
if reminder.monthlyOnDay < monthDay(now()):
newSendDate = newSendDate + 1.months
reminder.sendDate = $format(newSendDate, "yyyy-MM-dd")
updateReminderSendDate(reminder)
else:
#monthly on week number and weekday. e.g. "third thursday of every month".
newSendDate = nextMonthlyOnWeekdayOfWeek($reminder.monthlyOnWeekday, $reminder.monthlyOnWeek)
reminder.sendDate = $format(newSendDate, "yyyy-MM-dd")
updateReminderSendDate(reminder)
of "year":
#yearly on month and day.
#string zeros (db artifacts) have a length of 1...
if reminder.yearlyOnMonth.len() > 1:
newSendDate = nextYearlyDate(reminder.yearlyOnMonth, reminder.yearlyOnDay)
reminder.sendDate = $format(newSendDate, "yyyy-MM-dd")
updateReminderSendDate(reminder)
#yearly on weekday of week of month. e.g. third thursday of november of each year.
else:
newSendDate = nextYearlyOnWeekdayOfWeekOfMonth($reminder.yearlyOnWeekday, $reminder.yearlyOnWeek, $reminder.yearlyOnMonth2)
reminder.sendDate = $format(newSendDate, "yyyy-MM-dd")
updateReminderSendDate(reminder)
else:
echo "Invalid value for reminder.repeatFreq in setFutureSendDate()"
clearAllReminders()
proc sendEmail(reminderMsg: string) =
let userEmailAddress = getEmailByUserId("1")
let headers = @[("From", "mailer@itwrx.org")]
let msg = createMessage("Reminder from Forget-Me-Not", reminderMsg, @[userEmailAddress], mCc = @[""], otherHeaders = headers)
{.cast(raises: []).}:
let smtpConn = newSmtp(debug=false)
smtpConn.connect("email.itwrx.org", Port 587)
smtpConn.startTls()
smtpConn.auth("mailer@itwrx.org", ".AQ8u((xB(AgZh^a`jEJ~W~{0Eq?fd$")
#loop through email messages and send to reuse connection?
smtpConn.sendmail("mailer@itwrx.org", @[userEmailAddress], $msg)
#manually closing not necessary?
smtpConn.close()
proc sendXMPP(reminderMsg: string) =
var output: string
var status: int
(output, status) = execCmdEx("xmppc -m message chat itwrx@sec-chat.itwrx.org \"" & reminderMsg & "\"")
if status != 0:
#log this later instead.
echo output
echo "error sending XMPP msg"
#send reminders that haven't been sent yet and set new sendDate (if repeating).
proc sendReminders*() =
let nowDT = now()
let reminders = getAllReminders()
for reminder in reminders:
let sendDateDTString = $reminder.sendDate & " " & $reminder.sendTimeHr & ":" & $reminder.sendTimeMin & ":" & $reminder.sendTimeAmPm
#single digits for minutes, as db send_time_min is integer and won't use "00", which results in runtime parse error.
let sendDateDT = parse(sendDateDTString, "yyyy-M-d h:m:tt")
#if sendDate is not in the future, it hasn't been sent yet (we are changing sendDate to future date during each send) and needs to be sent.
if sendDateDT <= nowDT:
#send reminder notification
case reminder.notifyVia:
of "email":
sendEmail(reminder.message)
of "xmpp":
sendXMPP(reminder.message)
else:
sendXMPP(reminder.message)
sendEmail(reminder.message)
if reminder.repeats == 1:
setFutureSendDate(reminder.id)