comparison 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
comparison
equal deleted inserted replaced
39:471b13e6ce2c 40:7ea33179592a
1 local Luan = require "luan:Luan.luan"
2 local error = Luan.error
3 local ipairs = Luan.ipairs or error()
4 local pairs = Luan.pairs or error()
5 local stringify = Luan.stringify or error()
6 local Time = require "luan:Time.luan"
7 local time_now = Time.now or error()
8 local Thread = require "luan:Thread.luan"
9 local Http = require "luan:http/Http.luan"
10 local Chat = require "site:/lib/Chat.luan"
11 local User = require "site:/lib/User.luan"
12 local get_user_by_id = User.get_by_id or error()
13 local Db = require "site:/lib/Db.luan"
14 local run_in_transaction = Db.run_in_transaction or error()
15 local Shared = require "site:/lib/Shared.luan"
16 local send_mail = Shared.send_mail or error()
17 local Utils = require "site:/lib/Utils.luan"
18 local shallow_copy = Utils.shallow_copy or error()
19 local Logging = require "luan:logging/Logging.luan"
20 local logger = Logging.logger "Notify"
21
22
23 local Notify = {}
24
25 local url = Http.domain and "https://"..Http.domain.."/" or "http://localhost:8080/"
26
27 local wait = Time.period{seconds=10}
28
29 local function set_notified(user,was_notified)
30 run_in_transaction( function()
31 user = user.reload()
32 user.was_notified = was_notified
33 user.save()
34 end )
35 end
36
37 local function init()
38 local users = {}
39 local fns = {}
40
41 function fns.add(user_ids)
42 local now = time_now()
43 for _, user_id in ipairs(user_ids) do
44 local user = get_user_by_id(user_id)
45 if users[user_id] == nil and user.notify_email ~= nil and (user.multi_notify or not user.was_notified) then
46 users[user_id] = now
47 logger.info("add "..user_id)
48 end
49 end
50 end
51
52 function fns.remove(user_id)
53 users[user_id] = nil
54 logger.info("remove "..user_id)
55 end
56
57 function fns.notify()
58 logger.info("notify")
59 local now = time_now()
60 for user_id, when in pairs(shallow_copy(users)) do
61 if now - when > wait then
62 local user = get_user_by_id(user_id)
63 logger.info("notify "..user.notify_email.." "..user_id)
64 send_mail {
65 From = "Web Chat <chat@luan.software>"
66 To = user.notify_email
67 Subject = "New Messages"
68 body = `%>
69 You have received new messages.
70
71 <%= url %>
72 <% `
73 }
74 users[user_id] = nil
75 set_notified(user,true)
76 end
77 end
78 end
79
80 return fns
81 end
82
83 local glob = Thread.global_callable("notify",init)
84
85 function Notify.add(chat)
86 Thread.run(function()
87 glob.add(chat.user_ids)
88 end)
89 end
90
91 function Notify.remove(user)
92 Thread.run(function()
93 glob.remove(user.id)
94 if user.was_notified then
95 set_notified(user,false)
96 end
97 end)
98 end
99
100 Thread.schedule( glob.notify, { repeating_delay=Time.period{seconds=10} } )
101
102 return Notify