How to access mailbox metadata in Lua push driver
Ralf Becker
rb at egroupware.org
Mon Aug 3 22:58:09 EEST 2020
Some answers to my questions, a first version of my script and more
questions ;)
Am 03.08.20 um 18:15 schrieb Ralf Becker:
> Currently looking into the following questions:
>
> - can I get the rfc 5423 type of event somehow (obviously I can set it
> on the event myself depending of the function called)
event.name
> - looking at the example code, it looks like it can be called for
> multiple messages, when does that happen (LMTP send more then one)
still no idea, maybe Ake?
I noticed that some events have the same uid-validity, are the from a
single transaction, eg. I delete my Trash?
> - why is the mailbox status put into an other structure and send with
> a different notifiction
> - does anyone have a code snippet to send a JSON encoded message
> (probably easy to figure out looking at Lua docu)
these two I managed to solve im my current version of the script, which
also support now all message event types:
-- To use -- -- plugin { -- push_notification_driver =
lua:file=/etc/dovecot/dovecot-push.lua -- push_lua_url =
http://push.notification.server/handler -- } -- -- server is sent a PUT
message with JSON body like push_notification_driver =
ox:url=<push_lua_url> user_from_metadata -- local http = require "socket.http" local ltn12 = require "ltn12" -- luarocks install json-lua local json = require "JSON" function table_get(t, k, d)
return t[k] or d end function script_init()
return 0 end function dovecot_lua_notify_begin_txn(user)
local meta = user:metadata_get("/private/vendor/vendor.dovecot/http-notify")
return {user=user, event=dovecot.event(), ep=user:plugin_getenv("push_lua_url"), messages={}, meta=meta}
end function dovecot_lua_notify_event_message_new(ctx, event)
-- check if there is a push token registered if (ctx.meta == nil or ctx.meta == '') then return end -- get mailbox status local mbox = ctx.user:mailbox(event.mailbox)
mbox:sync()
local status = mbox:status(dovecot.storage.STATUS_RECENT, dovecot.storage.STATUS_UNSEEN, dovecot.storage.STATUS_MESSAGES)
mbox:free()
table.insert(ctx.messages, {
user = ctx.meta,
["imap-uidvalidity"] = event.uid_validity,
["imap-uid"] = event.uid,
folder = event.mailbox,
event = event.name,
from = event.from,
subject = event.subject,
snippet = event.snippet,
unseen = status.unseen
})
end function dovecot_lua_notify_event_message_append(ctx, event)
dovecot_lua_notify_event_message_new(ctx, event)
end function dovecot_lua_notify_event_message_read(ctx, event)
-- check if there is a push token registered if (ctx.meta == nil or ctx.meta == '') then return end -- get mailbox status local mbox = ctx.user:mailbox(event.mailbox)
mbox:sync()
local status = mbox:status(dovecot.storage.STATUS_RECENT, dovecot.storage.STATUS_UNSEEN, dovecot.storage.STATUS_MESSAGES)
mbox:free()
table.insert(ctx.messages, {
user = ctx.meta,
["imap-uidvalidity"] = event.uid_validity,
["imap-uid"] = event.uid,
folder = event.mailbox,
event = event.name,
unseen = status.unseen
})
end function dovecot_lua_notify_event_message_trash(ctx, event)
dovecot_lua_notify_event_message_read(ctx, event)
end function dovecot_lua_notify_event_message_expunge(ctx, event)
dovecot_lua_notify_event_message_read(ctx, event)
end function dovecot_lua_notify_event_flags_set(ctx, event)
-- check if there is a push token registered if (ctx.meta == nil or ctx.meta == '') then return end table.insert(ctx.messages, {
user = ctx.meta,
["imap-uidvalidity"] = event.uid_validity,
["imap-uid"] = event.uid,
folder = event.mailbox,
event = event.name,
flags = event.flags,
["keywords-set"] = event.keywords_set
})
end function dovecot_lua_notify_event_flags_clear(ctx, event)
-- check if there is a push token registered if (ctx.meta == nil or ctx.meta == '') then return end table.insert(ctx.messages, {
user = ctx.meta,
["imap-uidvalidity"] = event.uid_validity,
["imap-uid"] = event.uid,
folder = event.mailbox,
event = event.name,
flags = event.flags,
["keywords-clear"] = event.keywords_clear,
["keywords-old"] = event.keywords_old
})
end function dovecot_lua_notify_end_txn(ctx)
-- report all states for i,msg in ipairs(ctx.messages) do local e = dovecot.event(ctx.event)
e:set_name("lua_notify_mail_finished")
reqbody = json:encode(msg)
e:log_debug(ctx.ep .. " - sending " .. reqbody)
res, code = http.request({
method = "PUT",
url = ctx.ep,
source = ltn12.source.string(reqbody),
headers={
["content-type"] = "application/json; charset=utf-8",
["content-length"] = tostring(#reqbody)
}
})
e:add_int("result_code", code)
e:log_info("Mail notify status " .. tostring(code))
end end
This leads to a couple more questions ;)
- is there a way (eg. return value) to stop event processing already in
dovecot_lua_notify_begin_txn
- sometimes multiple events are generated, eg. when I read an email:
{"event":"FlagsClear","flags":[],"folder":"INBOX/eGroupWare/calconnect","imap-uid":2275,"imap-uidvalidity":1499767470,"keywords-old":[],"user":"user=5::42;***"}
{"event":"FlagsSet","flags":["\\Seen"],"folder":"INBOX/eGroupWare/calconnect","imap-uid":2275,"imap-uidvalidity":1499767470,"user":"user=5::42;***"}
{"event":"MessageRead","folder":"INBOX/eGroupWare/calconnect","imap-uid":2275,"imap-uidvalidity":1499767470,"unseen":0,"user":"user=5::42;***"}
Ralf
--
Ralf Becker
EGroupware GmbH [www.egroupware.org]
Handelsregister HRB Kaiserslautern 3587
Geschäftsführer Birgit und Ralf Becker
Leibnizstr. 17, 67663 Kaiserslautern, Germany
Telefon +49 631 31657-0
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://dovecot.org/pipermail/dovecot/attachments/20200803/581220a1/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: OpenPGP digital signature
URL: <https://dovecot.org/pipermail/dovecot/attachments/20200803/581220a1/attachment-0001.sig>
More information about the dovecot
mailing list