changeset 3498:69219097aa85

muc_notifications: notify non-present members of new messages This module, in the event of a new message in a Group Chat, will generate a notification for each of those members not present at that time in the Group Chat
author marc0s <marcos.devera@quobis.com>
date Fri, 29 Mar 2019 17:03:05 +0100
parents bc67519803f5
children a1fc677d0cc8
files mod_muc_notifications/README.markdown mod_muc_notifications/mod_muc_notifications.lua
diffstat 2 files changed, 108 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_muc_notifications/README.markdown	Fri Mar 29 17:03:05 2019 +0100
@@ -0,0 +1,41 @@
+---
+labels:
+- 'Stage-alpha'
+summary: 'Notify of MUC messages to not present members'
+...
+
+Introduction
+============
+
+This module listens to MUC messages and sends a notification to the
+MUC members not present in the MUC at that moment.
+
+By default, the notification will be a message with a simple text as body.
+
+By sending this "out-of-MUC" notification, not-joined members will be able to
+know that new messages are available.
+
+Usage
+=====
+
+First copy the module to the prosody plugins directory.
+
+Then add "muc\_notifications" to your modules\_enabled list in your
+MUC component:
+
+```{.lua}
+Component "conference.example.org" "muc"
+modules_enabled = {
+	"muc_notifications",
+}
+```
+
+You may also want to enable "offline\_hints" module so the notification messages
+sent by this module are not added to the offline storage for later delivery.
+
+Configuration
+=============
+
+  Option                      Description
+  --------------------------- ----------------------------------------------------------------------------------------------
+  muc\_notification\_invite   If set to `true`, the notification sent will take the form of a MUC invite. (default: `false`)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_muc_notifications/mod_muc_notifications.lua	Fri Mar 29 17:03:05 2019 +0100
@@ -0,0 +1,67 @@
+-- mod_muc_notifications
+--
+-- Copyright (C) 2019 Marcos de Vera Piquero <marcos.devera@quobis.com>
+--
+-- This file is MIT/X11 licensed.
+--
+-- A module to notify non-present members of messages in a group chat
+--
+
+local id = require"util.id"
+local st = require"util.stanza"
+
+local use_invite = module:get_option_boolean("muc_notification_invite", false)
+
+-- Given a stanza, compute if it qualifies as important (notifiable)
+-- return true for message stanzas with non-empty body
+-- Should probably use something similar to muc-message-is-historic event
+local function is_important(stanza)
+	local body = stanza:find("body#")
+	return body and #body
+end
+
+local function handle_muc_message(event)
+	-- event.room and event.stanza are available
+	local room = event.room
+	local stanza = event.stanza
+	for jid, aff in pairs(room._affiliations) do
+		if aff ~= "outcast" then
+			local is_occupant = false
+			for _, occupant in pairs(room._occupants) do
+				if occupant.bare_jid == jid then
+					is_occupant = true
+					break
+				end
+			end
+			if not is_occupant and is_important(stanza) then
+				-- send notification to jid
+				local attrs = {
+					to = jid,
+					id = id.short(),
+					from = room.jid,
+				}
+				local not_attrs = {
+					xmlns = "http://quobis.com/xmpp/muc#push",
+					jid = room.jid,
+				}
+				local reason = "You have messages in group chat "..room:get_name()
+				local notification = st.message(attrs)
+					:body(reason):up()
+					:tag("notification", not_attrs):up()
+					:tag("no-store", {xmlns = "urn:xmpp:hints"})
+				local invite = st.message(attrs):tag("x", {xmlns = "http://jabber.org/protocol/muc#user"})
+					:tag("invite", {from = stanza.attr.from})
+					:tag("reason"):text(reason):up():up():up()
+					:tag("notification", not_attrs):up()
+					:tag("no-store", {xmlns = "urn:xmpp:hints"})
+				module:log("debug", "notifying with %s", tostring(use_invite and invite or notification))
+				module:send(use_invite and invite or notification)
+				module:log("debug", "sent notification of MUC message %s", use_invite and invite or notification)
+			end
+		end
+	end
+end
+
+module:hook("muc-broadcast-message", handle_muc_message)
+
+module:log("debug", "Module loaded")