<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>In case someone is interested this is the final version of the
      script:</p>
    <pre style="background-color:#ffffff;color:#000000;font-family:'JetBrains Mono',monospace;font-size:9,8pt;"><span style="color:#808080;font-style:italic;">-- To use
</span><span style="color:#808080;font-style:italic;">--
</span><span style="color:#808080;font-style:italic;">-- plugin {
</span><span style="color:#808080;font-style:italic;">--  push_notification_driver = lua:file=/etc/dovecot/dovecot-push.lua
</span><span style="color:#808080;font-style:italic;">--  push_lua_url = <a class="moz-txt-link-freetext" href="https://Bearer">https://Bearer</a>:<push-token>@<egroupware-domain>/egroupware/push
</span><span style="color:#808080;font-style:italic;">-- }
</span><span style="color:#808080;font-style:italic;">--
</span><span style="color:#808080;font-style:italic;">-- server is sent a PUT message with JSON body like push_notification_driver = ox:url=<push_lua_url> user_from_metadata
</span><span style="color:#808080;font-style:italic;">-- plus additionally the events MessageAppend, MessageExpunge, FlagsSet and FlagsClear
</span><span style="color:#808080;font-style:italic;">-- MessageTrash and MessageRead are ignored, so are empty FlagSet/Clear or FlagSet NonJunk (TB)
</span><span style="color:#808080;font-style:italic;">--
</span><span style="color:#808080;font-style:italic;">
</span><span style="color:#000080;font-weight:bold;">local </span>http = <span style="color:#cc542e;">require </span><span style="color:#008000;font-weight:bold;">"socket.http"
</span><span style="color:#000080;font-weight:bold;">local </span>ltn12 = <span style="color:#cc542e;">require </span><span style="color:#008000;font-weight:bold;">"ltn12"
</span><span style="color:#808080;font-style:italic;">-- luarocks install json-lua
</span><span style="color:#000080;font-weight:bold;">local </span>json = <span style="color:#cc542e;">require </span><span style="color:#008000;font-weight:bold;">"JSON"
</span><span style="color:#008000;font-weight:bold;">
</span><span style="color:#000080;font-weight:bold;">function </span><span style="color:#660e7a;font-style:italic;">table_get</span>(<span style="color:#006666;font-weight:bold;">t</span>, <span style="color:#006666;font-weight:bold;">k</span>, <span style="color:#006666;font-weight:bold;">d</span>)
  <span style="color:#000080;font-weight:bold;">return </span><span style="color:#006666;font-weight:bold;">t</span>[<span style="color:#006666;font-weight:bold;">k</span>] <span style="color:#000080;font-weight:bold;">or </span><span style="color:#006666;font-weight:bold;">d
</span><span style="color:#000080;font-weight:bold;">end
</span><span style="color:#000080;font-weight:bold;">
</span><span style="color:#000080;font-weight:bold;">function </span><span style="color:#660e7a;font-style:italic;">script_init</span>()
  <span style="color:#000080;font-weight:bold;">return </span><span style="color:#0000ff;">0
</span><span style="color:#000080;font-weight:bold;">end
</span><span style="color:#000080;font-weight:bold;">
</span><span style="color:#000080;font-weight:bold;">function </span><span style="color:#660e7a;font-style:italic;">dovecot_lua_notify_begin_txn</span>(<span style="color:#006666;font-weight:bold;">user</span>)
    <span style="color:#000080;font-weight:bold;">local </span>meta = <span style="color:#006666;font-weight:bold;">user</span>:metadata_get(<span style="color:#008000;font-weight:bold;">"/private/vendor/vendor.dovecot/http-notify"</span>)
    <span style="color:#000080;font-weight:bold;">if </span>(meta == <span style="color:#d700ff;">nil </span><span style="color:#000080;font-weight:bold;">or </span>meta:sub(<span style="color:#0000ff;">1</span>,<span style="color:#0000ff;">5</span>) ~= <span style="color:#008000;font-weight:bold;">"user="</span>)
    <span style="color:#000080;font-weight:bold;">then
</span><span style="color:#000080;font-weight:bold;">        </span>meta = <span style="color:#d700ff;">nil</span>;
    <span style="color:#000080;font-weight:bold;">else
</span><span style="color:#000080;font-weight:bold;">        </span>meta = meta:sub(<span style="color:#0000ff;">6</span>)
    <span style="color:#000080;font-weight:bold;">end
</span><span style="color:#000080;font-weight:bold;">    return </span>{user=<span style="color:#006666;font-weight:bold;">user</span>, event=<span style="color:#660e7a;font-style:italic;">dovecot</span>.<span style="font-style:italic;">event</span>(), ep=<span style="color:#006666;font-weight:bold;">user</span>:plugin_getenv(<span style="color:#008000;font-weight:bold;">"push_lua_url"</span>), messages={}, meta=meta}
<span style="color:#000080;font-weight:bold;">end
</span><span style="color:#000080;font-weight:bold;">
</span><span style="color:#000080;font-weight:bold;">function </span><span style="color:#660e7a;font-style:italic;">dovecot_lua_notify_event_message_new</span>(<span style="color:#006666;font-weight:bold;">ctx</span>, <span style="color:#006666;font-weight:bold;">event</span>)
    <span style="color:#808080;font-style:italic;">-- check if there is a push token registered
</span><span style="color:#808080;font-style:italic;">    </span><span style="color:#000080;font-weight:bold;">if </span>(<span style="color:#006666;font-weight:bold;">ctx</span>.meta == <span style="color:#d700ff;">nil</span>) <span style="color:#000080;font-weight:bold;">then
</span><span style="color:#000080;font-weight:bold;">        return
</span><span style="color:#000080;font-weight:bold;">    end
</span><span style="color:#000080;font-weight:bold;">    </span><span style="color:#808080;font-style:italic;">-- get mailbox status
</span><span style="color:#808080;font-style:italic;">    </span><span style="color:#000080;font-weight:bold;">local </span>mbox = <span style="color:#006666;font-weight:bold;">ctx</span>.user:mailbox(<span style="color:#006666;font-weight:bold;">event</span>.mailbox)
    mbox:sync()
    <span style="color:#000080;font-weight:bold;">local </span>status = mbox:status(<span style="color:#660e7a;font-style:italic;">dovecot</span>.storage.STATUS_RECENT, <span style="color:#660e7a;font-style:italic;">dovecot</span>.storage.STATUS_UNSEEN, <span style="color:#660e7a;font-style:italic;">dovecot</span>.storage.STATUS_MESSAGES)
    mbox:free()
    <span style="color:#cc542e;">table</span>.insert(<span style="color:#006666;font-weight:bold;">ctx</span>.messages, {
        user = <span style="color:#006666;font-weight:bold;">ctx</span>.meta,
        [<span style="color:#008000;font-weight:bold;">"imap-uidvalidity"</span>] = <span style="color:#006666;font-weight:bold;">event</span>.uid_validity,
        [<span style="color:#008000;font-weight:bold;">"imap-uid"</span>] = <span style="color:#006666;font-weight:bold;">event</span>.uid,
        folder = <span style="color:#006666;font-weight:bold;">event</span>.mailbox,
        event = <span style="color:#006666;font-weight:bold;">event</span>.name,
        from = <span style="color:#006666;font-weight:bold;">event</span>.from,
        subject = <span style="color:#006666;font-weight:bold;">event</span>.subject,
        snippet = <span style="color:#006666;font-weight:bold;">event</span>.snippet,
        unseen = status.unseen,
        messages = status.messages
    })
<span style="color:#000080;font-weight:bold;">end
</span><span style="color:#000080;font-weight:bold;">
</span><span style="color:#000080;font-weight:bold;">function </span><span style="color:#660e7a;font-style:italic;">dovecot_lua_notify_event_message_append</span>(<span style="color:#006666;font-weight:bold;">ctx</span>, <span style="color:#006666;font-weight:bold;">event</span>)
  <span style="color:#660e7a;font-style:italic;">dovecot_lua_notify_event_message_new</span>(<span style="color:#006666;font-weight:bold;">ctx</span>, <span style="color:#006666;font-weight:bold;">event</span>)
<span style="color:#000080;font-weight:bold;">end
</span><span style="color:#000080;font-weight:bold;">
</span><span style="color:#808080;font-style:italic;">-- ignored, as FlagSet flags=[\Seen] is sent anyway too
</span><span style="color:#808080;font-style:italic;">-- function dovecot_lua_notify_event_message_read(ctx, event)
</span><span style="color:#808080;font-style:italic;">--    dovecot_lua_notify_event_message_expunge(ctx, event)
</span><span style="color:#808080;font-style:italic;">-- end
</span><span style="color:#808080;font-style:italic;">
</span><span style="color:#808080;font-style:italic;">-- ignored, as most MUA nowadays expunge immediatly
</span><span style="color:#808080;font-style:italic;">-- function dovecot_lua_notify_event_message_trash(ctx, event)
</span><span style="color:#808080;font-style:italic;">--    dovecot_lua_notify_event_message_expunge(ctx, event)
</span><span style="color:#808080;font-style:italic;">-- end
</span><span style="color:#808080;font-style:italic;">
</span><span style="color:#000080;font-weight:bold;">function </span><span style="color:#660e7a;font-style:italic;">dovecot_lua_notify_event_message_expunge</span>(<span style="color:#006666;font-weight:bold;">ctx</span>, <span style="color:#006666;font-weight:bold;">event</span>)
    <span style="color:#808080;font-style:italic;">-- check if there is a push token registered
</span><span style="color:#808080;font-style:italic;">    </span><span style="color:#000080;font-weight:bold;">if </span>(<span style="color:#006666;font-weight:bold;">ctx</span>.meta == <span style="color:#d700ff;">nil</span>) <span style="color:#000080;font-weight:bold;">then
</span><span style="color:#000080;font-weight:bold;">        return
</span><span style="color:#000080;font-weight:bold;">    end
</span><span style="color:#000080;font-weight:bold;">    </span><span style="color:#808080;font-style:italic;">-- get mailbox status
</span><span style="color:#808080;font-style:italic;">    </span><span style="color:#000080;font-weight:bold;">local </span>mbox = <span style="color:#006666;font-weight:bold;">ctx</span>.user:mailbox(<span style="color:#006666;font-weight:bold;">event</span>.mailbox)
    mbox:sync()
    <span style="color:#000080;font-weight:bold;">local </span>status = mbox:status(<span style="color:#660e7a;font-style:italic;">dovecot</span>.storage.STATUS_RECENT, <span style="color:#660e7a;font-style:italic;">dovecot</span>.storage.STATUS_UNSEEN, <span style="color:#660e7a;font-style:italic;">dovecot</span>.storage.STATUS_MESSAGES)
    mbox:free()
    <span style="color:#808080;font-style:italic;">-- agregate multiple Expunge (or Trash or Read)
</span><span style="color:#808080;font-style:italic;">    </span><span style="color:#000080;font-weight:bold;">if </span>(#<span style="color:#006666;font-weight:bold;">ctx</span>.messages == <span style="color:#0000ff;">1 </span><span style="color:#000080;font-weight:bold;">and </span><span style="color:#006666;font-weight:bold;">ctx</span>.messages[<span style="color:#0000ff;">1</span>].user == <span style="color:#006666;font-weight:bold;">ctx</span>.meta <span style="color:#000080;font-weight:bold;">and </span><span style="color:#006666;font-weight:bold;">ctx</span>.messages[<span style="color:#0000ff;">1</span>].folder == <span style="color:#006666;font-weight:bold;">event</span>.mailbox <span style="color:#000080;font-weight:bold;">and
</span><span style="color:#000080;font-weight:bold;">        </span><span style="color:#006666;font-weight:bold;">ctx</span>.messages[<span style="color:#0000ff;">1</span>][<span style="color:#008000;font-weight:bold;">"imap-uidvalidity"</span>] == <span style="color:#006666;font-weight:bold;">event</span>.uid_validity <span style="color:#000080;font-weight:bold;">and </span><span style="color:#006666;font-weight:bold;">ctx</span>.messages[<span style="color:#0000ff;">1</span>].event == <span style="color:#006666;font-weight:bold;">event</span>.name)
    <span style="color:#000080;font-weight:bold;">then
</span><span style="color:#000080;font-weight:bold;">        if </span>(<span style="color:#cc542e;">type</span>(<span style="color:#006666;font-weight:bold;">ctx</span>.messages[<span style="color:#0000ff;">1</span>][<span style="color:#008000;font-weight:bold;">"imap-uid"</span>]) ~= <span style="color:#008000;font-weight:bold;">'table'</span>) <span style="color:#000080;font-weight:bold;">then
</span><span style="color:#000080;font-weight:bold;">            </span><span style="color:#006666;font-weight:bold;">ctx</span>.messages[<span style="color:#0000ff;">1</span>][<span style="color:#008000;font-weight:bold;">"imap-uid"</span>] = {<span style="color:#006666;font-weight:bold;">ctx</span>.messages[<span style="color:#0000ff;">1</span>][<span style="color:#008000;font-weight:bold;">"imap-uid"</span>]}
        <span style="color:#000080;font-weight:bold;">end
</span><span style="color:#000080;font-weight:bold;">        </span><span style="color:#cc542e;">table</span>.insert(<span style="color:#006666;font-weight:bold;">ctx</span>.messages[<span style="color:#0000ff;">1</span>][<span style="color:#008000;font-weight:bold;">"imap-uid"</span>], <span style="color:#006666;font-weight:bold;">event</span>.uid)
        <span style="color:#006666;font-weight:bold;">ctx</span>.messages[<span style="color:#0000ff;">1</span>].unseen = status.unseen
        <span style="color:#006666;font-weight:bold;">ctx</span>.messages[<span style="color:#0000ff;">1</span>].messages = status.messages
        <span style="color:#000080;font-weight:bold;">return</span>;
    <span style="color:#000080;font-weight:bold;">end
</span><span style="color:#000080;font-weight:bold;">    </span><span style="color:#cc542e;">table</span>.insert(<span style="color:#006666;font-weight:bold;">ctx</span>.messages, {
        user = <span style="color:#006666;font-weight:bold;">ctx</span>.meta,
        [<span style="color:#008000;font-weight:bold;">"imap-uidvalidity"</span>] = <span style="color:#006666;font-weight:bold;">event</span>.uid_validity,
        [<span style="color:#008000;font-weight:bold;">"imap-uid"</span>] = <span style="color:#006666;font-weight:bold;">event</span>.uid,
        folder = <span style="color:#006666;font-weight:bold;">event</span>.mailbox,
        event = <span style="color:#006666;font-weight:bold;">event</span>.name,
        unseen = status.unseen,
        messages = status.messages
    })
<span style="color:#000080;font-weight:bold;">end
</span><span style="color:#000080;font-weight:bold;">
</span><span style="color:#000080;font-weight:bold;">function </span><span style="color:#660e7a;font-style:italic;">dovecot_lua_notify_event_flags_set</span>(<span style="color:#006666;font-weight:bold;">ctx</span>, <span style="color:#006666;font-weight:bold;">event</span>)
    <span style="color:#808080;font-style:italic;">-- check if there is a push token registered
</span><span style="color:#808080;font-style:italic;">    </span><span style="color:#000080;font-weight:bold;">if </span>(<span style="color:#006666;font-weight:bold;">ctx</span>.meta == <span style="color:#d700ff;">nil </span><span style="color:#000080;font-weight:bold;">or
</span><span style="color:#000080;font-weight:bold;">        </span>(#<span style="color:#006666;font-weight:bold;">event</span>.flags == <span style="color:#0000ff;">0 </span><span style="color:#000080;font-weight:bold;">and </span>#<span style="color:#006666;font-weight:bold;">event</span>.keywords == <span style="color:#0000ff;">0</span>) <span style="color:#000080;font-weight:bold;">or </span><span style="color:#808080;font-style:italic;">-- ignore TB sends it empty
</span><span style="color:#808080;font-style:italic;">        </span>(#<span style="color:#006666;font-weight:bold;">event</span>.keywords == <span style="color:#0000ff;">1 </span><span style="color:#000080;font-weight:bold;">and </span><span style="color:#006666;font-weight:bold;">event</span>.keywords[<span style="color:#0000ff;">1</span>] == <span style="color:#008000;font-weight:bold;">"NonJunk"</span>)) <span style="color:#808080;font-style:italic;">-- ignore TB NonJunk
</span><span style="color:#808080;font-style:italic;">    </span><span style="color:#000080;font-weight:bold;">then
</span><span style="color:#000080;font-weight:bold;">        return
</span><span style="color:#000080;font-weight:bold;">    end
</span><span style="color:#000080;font-weight:bold;">    local </span>status = <span style="color:#d700ff;">nil</span>;
    <span style="color:#000080;font-weight:bold;">if </span>(#<span style="color:#006666;font-weight:bold;">event</span>.flags == <span style="color:#0000ff;">1 </span><span style="color:#000080;font-weight:bold;">and </span><span style="color:#006666;font-weight:bold;">event</span>.flags[<span style="color:#0000ff;">1</span>] == <span style="color:#008000;font-weight:bold;">"</span><span style="color:#000080;font-weight:bold;">\\</span><span style="color:#008000;font-weight:bold;">Seen"</span>)
    <span style="color:#000080;font-weight:bold;">then
</span><span style="color:#000080;font-weight:bold;">        </span><span style="color:#808080;font-style:italic;">-- get mailbox status
</span><span style="color:#808080;font-style:italic;">        </span><span style="color:#000080;font-weight:bold;">local </span>mbox = <span style="color:#006666;font-weight:bold;">ctx</span>.user:mailbox(<span style="color:#006666;font-weight:bold;">event</span>.mailbox)
        mbox:sync()
        status = mbox:status(<span style="color:#660e7a;font-style:italic;">dovecot</span>.storage.STATUS_RECENT, <span style="color:#660e7a;font-style:italic;">dovecot</span>.storage.STATUS_UNSEEN, <span style="color:#660e7a;font-style:italic;">dovecot</span>.storage.STATUS_MESSAGES)
        mbox:free()
    <span style="color:#000080;font-weight:bold;">end
</span><span style="color:#000080;font-weight:bold;">    </span><span style="color:#808080;font-style:italic;">-- agregate multiple FlagSet
</span><span style="color:#808080;font-style:italic;">    </span><span style="color:#000080;font-weight:bold;">if </span>(#<span style="color:#006666;font-weight:bold;">ctx</span>.messages == <span style="color:#0000ff;">1 </span><span style="color:#000080;font-weight:bold;">and </span><span style="color:#006666;font-weight:bold;">ctx</span>.messages[<span style="color:#0000ff;">1</span>].user == <span style="color:#006666;font-weight:bold;">ctx</span>.meta <span style="color:#000080;font-weight:bold;">and </span><span style="color:#006666;font-weight:bold;">ctx</span>.messages[<span style="color:#0000ff;">1</span>].folder == <span style="color:#006666;font-weight:bold;">event</span>.mailbox <span style="color:#000080;font-weight:bold;">and
</span><span style="color:#000080;font-weight:bold;">        </span><span style="color:#006666;font-weight:bold;">ctx</span>.messages[<span style="color:#0000ff;">1</span>][<span style="color:#008000;font-weight:bold;">"imap-uidvalidity"</span>] == <span style="color:#006666;font-weight:bold;">event</span>.uid_validity <span style="color:#000080;font-weight:bold;">and </span><span style="color:#006666;font-weight:bold;">ctx</span>.messages[<span style="color:#0000ff;">1</span>].event == <span style="color:#006666;font-weight:bold;">event</span>.name <span style="color:#000080;font-weight:bold;">and
</span><span style="color:#000080;font-weight:bold;">        </span><span style="color:#660e7a;font-style:italic;">arrayEqual</span>(<span style="color:#006666;font-weight:bold;">ctx</span>.messages[<span style="color:#0000ff;">1</span>].flags, <span style="color:#006666;font-weight:bold;">event</span>.flags) <span style="color:#000080;font-weight:bold;">and </span><span style="color:#660e7a;font-style:italic;">arrayEqual</span>(<span style="color:#006666;font-weight:bold;">ctx</span>.messages[<span style="color:#0000ff;">1</span>].keywords, <span style="color:#006666;font-weight:bold;">event</span>.keywords))
    <span style="color:#000080;font-weight:bold;">then
</span><span style="color:#000080;font-weight:bold;">        if </span>(<span style="color:#cc542e;">type</span>(<span style="color:#006666;font-weight:bold;">ctx</span>.messages[<span style="color:#0000ff;">1</span>][<span style="color:#008000;font-weight:bold;">"imap-uid"</span>]) ~= <span style="color:#008000;font-weight:bold;">'table'</span>) <span style="color:#000080;font-weight:bold;">then
</span><span style="color:#000080;font-weight:bold;">            </span><span style="color:#006666;font-weight:bold;">ctx</span>.messages[<span style="color:#0000ff;">1</span>][<span style="color:#008000;font-weight:bold;">"imap-uid"</span>] = {<span style="color:#006666;font-weight:bold;">ctx</span>.messages[<span style="color:#0000ff;">1</span>][<span style="color:#008000;font-weight:bold;">"imap-uid"</span>]}
        <span style="color:#000080;font-weight:bold;">end
</span><span style="color:#000080;font-weight:bold;">        </span><span style="color:#cc542e;">table</span>.insert(<span style="color:#006666;font-weight:bold;">ctx</span>.messages[<span style="color:#0000ff;">1</span>][<span style="color:#008000;font-weight:bold;">"imap-uid"</span>], <span style="color:#006666;font-weight:bold;">event</span>.uid)
        <span style="color:#000080;font-weight:bold;">if </span>(status ~= <span style="color:#d700ff;">nil</span>)
        <span style="color:#000080;font-weight:bold;">then
</span><span style="color:#000080;font-weight:bold;">            </span><span style="color:#006666;font-weight:bold;">ctx</span>.messages[<span style="color:#0000ff;">1</span>].unseen = status.unseen
        <span style="color:#000080;font-weight:bold;">end
</span><span style="color:#000080;font-weight:bold;">        return</span>;
    <span style="color:#000080;font-weight:bold;">end
</span><span style="color:#000080;font-weight:bold;">    </span><span style="color:#cc542e;">table</span>.insert(<span style="color:#006666;font-weight:bold;">ctx</span>.messages, {
        user = <span style="color:#006666;font-weight:bold;">ctx</span>.meta,
        [<span style="color:#008000;font-weight:bold;">"imap-uidvalidity"</span>] = <span style="color:#006666;font-weight:bold;">event</span>.uid_validity,
        [<span style="color:#008000;font-weight:bold;">"imap-uid"</span>] = <span style="color:#006666;font-weight:bold;">event</span>.uid,
        folder = <span style="color:#006666;font-weight:bold;">event</span>.mailbox,
        event = <span style="color:#006666;font-weight:bold;">event</span>.name,
        flags = <span style="color:#006666;font-weight:bold;">event</span>.flags,
        keywords = <span style="color:#006666;font-weight:bold;">event</span>.keywords,
        unseen = status.unseen
    })
<span style="color:#000080;font-weight:bold;">end
</span><span style="color:#000080;font-weight:bold;">
</span><span style="color:#000080;font-weight:bold;">function </span><span style="color:#660e7a;font-style:italic;">arrayEqual</span>(<span style="color:#006666;font-weight:bold;">t1</span>, <span style="color:#006666;font-weight:bold;">t2</span>)
    <span style="color:#000080;font-weight:bold;">if </span>(#<span style="color:#006666;font-weight:bold;">t1 </span>~= #<span style="color:#006666;font-weight:bold;">t2</span>)
    <span style="color:#000080;font-weight:bold;">then
</span><span style="color:#000080;font-weight:bold;">        return </span><span style="color:#d700ff;">false
</span><span style="color:#d700ff;">    </span><span style="color:#000080;font-weight:bold;">end
</span><span style="color:#000080;font-weight:bold;">    if </span>(#<span style="color:#006666;font-weight:bold;">t1 </span>== <span style="color:#0000ff;">1 </span><span style="color:#000080;font-weight:bold;">and </span><span style="color:#006666;font-weight:bold;">t1</span>[<span style="color:#0000ff;">1</span>] == <span style="color:#006666;font-weight:bold;">t2</span>[<span style="color:#0000ff;">1</span>])
    <span style="color:#000080;font-weight:bold;">then
</span><span style="color:#000080;font-weight:bold;">        return </span><span style="color:#d700ff;">true
</span><span style="color:#d700ff;">    </span><span style="color:#000080;font-weight:bold;">end
</span><span style="color:#000080;font-weight:bold;">    return </span><span style="font-weight:bold;font-style:italic;">json</span>:encode(<span style="color:#006666;font-weight:bold;">t1</span>) == <span style="font-weight:bold;font-style:italic;">json</span>:encode(<span style="color:#006666;font-weight:bold;">t2</span>)
<span style="color:#000080;font-weight:bold;">end
</span><span style="color:#000080;font-weight:bold;">
</span><span style="color:#000080;font-weight:bold;">function </span><span style="color:#660e7a;font-style:italic;">dovecot_lua_notify_event_flags_clear</span>(<span style="color:#006666;font-weight:bold;">ctx</span>, <span style="color:#006666;font-weight:bold;">event</span>)
    <span style="color:#808080;font-style:italic;">-- check if there is a push token registered AND something to clear (TB sends it empty)
</span><span style="color:#808080;font-style:italic;">    </span><span style="color:#000080;font-weight:bold;">if </span>(<span style="color:#006666;font-weight:bold;">ctx</span>.meta == <span style="color:#d700ff;">nil </span><span style="color:#000080;font-weight:bold;">or </span>(#<span style="color:#006666;font-weight:bold;">event</span>.flags == <span style="color:#0000ff;">0 </span><span style="color:#000080;font-weight:bold;">and </span>#<span style="color:#006666;font-weight:bold;">event</span>.keywords == <span style="color:#0000ff;">0</span>)) <span style="color:#000080;font-weight:bold;">then
</span><span style="color:#000080;font-weight:bold;">        return
</span><span style="color:#000080;font-weight:bold;">    end
</span><span style="color:#000080;font-weight:bold;">    </span><span style="color:#cc542e;">table</span>.insert(<span style="color:#006666;font-weight:bold;">ctx</span>.messages, {
        user = <span style="color:#006666;font-weight:bold;">ctx</span>.meta,
        [<span style="color:#008000;font-weight:bold;">"imap-uidvalidity"</span>] = <span style="color:#006666;font-weight:bold;">event</span>.uid_validity,
        [<span style="color:#008000;font-weight:bold;">"imap-uid"</span>] = <span style="color:#006666;font-weight:bold;">event</span>.uid,
        folder = <span style="color:#006666;font-weight:bold;">event</span>.mailbox,
        event = <span style="color:#006666;font-weight:bold;">event</span>.name,
        flags = <span style="color:#006666;font-weight:bold;">event</span>.flags,
        [<span style="color:#008000;font-weight:bold;">"flags-old"</span>] = <span style="color:#006666;font-weight:bold;">event</span>.flags_old,
        keywords = <span style="color:#006666;font-weight:bold;">event</span>.keywords,
        [<span style="color:#008000;font-weight:bold;">"keywords-old"</span>] = <span style="color:#006666;font-weight:bold;">event</span>.keywords_old
    })
<span style="color:#000080;font-weight:bold;">end
</span><span style="color:#000080;font-weight:bold;">
</span><span style="color:#000080;font-weight:bold;">function </span><span style="color:#660e7a;font-style:italic;">dovecot_lua_notify_end_txn</span>(<span style="color:#006666;font-weight:bold;">ctx</span>)
    <span style="color:#808080;font-style:italic;">-- report all states
</span><span style="color:#808080;font-style:italic;">    </span><span style="color:#000080;font-weight:bold;">for </span><span style="color:#006666;font-weight:bold;">i</span>,<span style="color:#006666;font-weight:bold;">msg </span><span style="color:#000080;font-weight:bold;">in </span><span style="color:#cc542e;">ipairs</span>(<span style="color:#006666;font-weight:bold;">ctx</span>.messages) <span style="color:#000080;font-weight:bold;">do
</span><span style="color:#000080;font-weight:bold;">        local </span>e = <span style="color:#660e7a;font-style:italic;">dovecot</span>.<span style="font-style:italic;">event</span>(<span style="color:#006666;font-weight:bold;">ctx</span>.event)
        e:set_name(<span style="color:#008000;font-weight:bold;">"lua_notify_mail_finished"</span>)
        <span style="color:#660e7a;font-style:italic;">reqbody </span>= <span style="font-weight:bold;font-style:italic;">json</span>:encode(<span style="color:#006666;font-weight:bold;">msg</span>)
        e:log_debug(<span style="color:#006666;font-weight:bold;">ctx</span>.ep .. <span style="color:#008000;font-weight:bold;">" - sending " </span>.. <span style="color:#660e7a;font-style:italic;">reqbody</span>)
        <span style="color:#660e7a;font-style:italic;">res</span>, <span style="color:#660e7a;font-style:italic;">code </span>= <span style="font-weight:bold;font-style:italic;">http</span>.<span style="font-style:italic;">request</span>({
            method = <span style="color:#008000;font-weight:bold;">"PUT"</span>,
            url = <span style="color:#006666;font-weight:bold;">ctx</span>.ep,
            source = <span style="font-weight:bold;font-style:italic;">ltn12</span>.source.<span style="font-style:italic;">string</span>(<span style="color:#660e7a;font-style:italic;">reqbody</span>),
            headers={
                [<span style="color:#008000;font-weight:bold;">"content-type"</span>] = <span style="color:#008000;font-weight:bold;">"application/json; charset=utf-8"</span>,
                [<span style="color:#008000;font-weight:bold;">"content-length"</span>] = <span style="color:#cc542e;">tostring</span>(#<span style="color:#660e7a;font-style:italic;">reqbody</span>)
            }
        })
        e:add_int(<span style="color:#008000;font-weight:bold;">"result_code"</span>, <span style="color:#660e7a;font-style:italic;">code</span>)
        e:log_info(<span style="color:#008000;font-weight:bold;">"Mail notify status " </span>.. <span style="color:#cc542e;">tostring</span>(<span style="color:#660e7a;font-style:italic;">code</span>))
    <span style="color:#000080;font-weight:bold;">end
</span><span style="color:#000080;font-weight:bold;">end
</span></pre>
    <p>It's also in our Github repo:
<a class="moz-txt-link-freetext" href="https://raw.githubusercontent.com/EGroupware/swoolepush/master/doc/dovecot-push.lua">https://raw.githubusercontent.com/EGroupware/swoolepush/master/doc/dovecot-push.lua</a></p>
    <p>Ralf<br>
    </p>
    <pre class="moz-signature" cols="72">-- 
Ralf Becker
EGroupware GmbH [<a class="moz-txt-link-abbreviated" href="http://www.egroupware.org">www.egroupware.org</a>]
Handelsregister HRB Kaiserslautern 3587
Geschäftsführer Birgit und Ralf Becker
Leibnizstr. 17, 67663 Kaiserslautern, Germany
Telefon +49 631 31657-0
</pre>
  </body>
</html>