diff src/lib/Notify.luan @ 40:7ea33179592a

email notification
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 27 Feb 2025 16:44:20 -0700
parents
children 818697418dbe
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/Notify.luan	Thu Feb 27 16:44:20 2025 -0700
@@ -0,0 +1,102 @@
+local Luan = require "luan:Luan.luan"
+local error = Luan.error
+local ipairs = Luan.ipairs or error()
+local pairs = Luan.pairs or error()
+local stringify = Luan.stringify or error()
+local Time = require "luan:Time.luan"
+local time_now = Time.now or error()
+local Thread = require "luan:Thread.luan"
+local Http = require "luan:http/Http.luan"
+local Chat = require "site:/lib/Chat.luan"
+local User = require "site:/lib/User.luan"
+local get_user_by_id = User.get_by_id or error()
+local Db = require "site:/lib/Db.luan"
+local run_in_transaction = Db.run_in_transaction or error()
+local Shared = require "site:/lib/Shared.luan"
+local send_mail = Shared.send_mail or error()
+local Utils = require "site:/lib/Utils.luan"
+local shallow_copy = Utils.shallow_copy or error()
+local Logging = require "luan:logging/Logging.luan"
+local logger = Logging.logger "Notify"
+
+
+local Notify = {}
+
+local url = Http.domain and "https://"..Http.domain.."/" or "http://localhost:8080/"
+
+local wait = Time.period{seconds=10}
+
+local function set_notified(user,was_notified)
+	run_in_transaction( function()
+		user = user.reload()
+		user.was_notified = was_notified
+		user.save()
+	end )
+end
+
+local function init()
+	local users = {}
+	local fns = {}
+
+	function fns.add(user_ids)
+		local now = time_now()
+		for _, user_id in ipairs(user_ids) do
+			local user = get_user_by_id(user_id)
+			if users[user_id] == nil and user.notify_email ~= nil and (user.multi_notify or not user.was_notified) then
+				users[user_id] = now
+logger.info("add "..user_id)
+			end
+		end
+	end
+
+	function fns.remove(user_id)
+		users[user_id] = nil
+logger.info("remove "..user_id)
+	end
+
+	function fns.notify()
+logger.info("notify")
+		local now = time_now()
+		for user_id, when in pairs(shallow_copy(users)) do
+			if now - when > wait then
+				local user = get_user_by_id(user_id)
+logger.info("notify "..user.notify_email.." "..user_id)
+				send_mail {
+					From = "Web Chat <chat@luan.software>"
+					To = user.notify_email
+					Subject = "New Messages"
+					body = `%>
+You have received new messages.
+
+<%= url %>
+<%					`
+				}
+				users[user_id] = nil
+				set_notified(user,true)
+			end
+		end
+	end
+
+	return fns
+end
+
+local glob = Thread.global_callable("notify",init)
+
+function Notify.add(chat)
+	Thread.run(function()
+		glob.add(chat.user_ids)
+	end)
+end
+
+function Notify.remove(user)
+	Thread.run(function()
+		glob.remove(user.id)
+		if user.was_notified then
+			set_notified(user,false)
+		end
+	end)
+end
+
+Thread.schedule( glob.notify, { repeating_delay=Time.period{seconds=10} } )
+
+return Notify