plugins/mod_announce.lua

1
-- Prosody IM
2
-- Copyright (C) 2008-2010 Matthew Wild
3
-- Copyright (C) 2008-2010 Waqas Hussain
4
-- 
5
-- This project is MIT/X11 licensed. Please see the
6
-- COPYING file in the source package for more information.
7
--
8
 
9
local st, jid = require "util.stanza", require "util.jid";
10
 
11
local is_admin = require "core.usermanager".is_admin;
12
 
13
function send_to_online(message, host)
14
	local sessions;
15
	if host then
16
		sessions = { [host] = hosts[host] };
17
	else
18
		sessions = hosts;
19
	end
20
 
21
	local c = 0;
22
	for hostname, host_session in pairs(sessions) do
23
		if host_session.sessions then
24
			message.attr.from = hostname;
25
			for username in pairs(host_session.sessions) do
26
				c = c + 1;
27
				message.attr.to = username.."@"..hostname;
28
				core_post_stanza(host_session, message);
29
			end
30
		end
31
	end
32
 
33
	return c;
34
end
35
 
36
 
37
-- Old <message>-based jabberd-style announcement sending
38
function handle_announcement(event)
39
	local origin, stanza = event.origin, event.stanza;
40
	local node, host, resource = jid.split(stanza.attr.to);
41
	
42
	if resource ~= "announce/online" then
43
		return; -- Not an announcement
44
	end
45
	
46
	if not is_admin(stanza.attr.from) then
47
		-- Not an admin? Not allowed!
48
		module:log("warn", "Non-admin '%s' tried to send server announcement", stanza.attr.from);
49
		return;
50
	end
51
	
52
	module:log("info", "Sending server announcement to all online users");
53
	local message = st.clone(stanza);
54
	message.attr.type = "headline";
55
	message.attr.from = host;
56
	
57
	local c = send_to_online(message, host);
58
	module:log("info", "Announcement sent to %d online users", c);
59
	return true;
60
end
61
module:hook("message/host", handle_announcement);
62
 
63
-- Ad-hoc command (XEP-0133)
64
local dataforms_new = require "util.dataforms".new;
65
local announce_layout = dataforms_new{
66
	title = "Making an Announcement";
67
	instructions = "Fill out this form to make an announcement to all\nactive users of this service.";
68
 
69
	{ name = "FORM_TYPE", type = "hidden", value = "http://jabber.org/protocol/admin" };
70
	{ name = "subject", type = "text-single", label = "Subject" };
71
	{ name = "announcement", type = "text-multi", required = true, label = "Announcement" };
72
};
73
 
74
function announce_handler(self, data, state)
75
	if state then
76
		if data.action == "cancel" then
77
			return { status = "canceled" };
78
		end
79
 
80
		local fields = announce_layout:data(data.form);
81
 
82
		module:log("info", "Sending server announcement to all online users");
83
		local message = st.message({type = "headline"}, fields.announcement):up()
84
			:tag("subject"):text(fields.subject or "Announcement");
85
		
86
		local count = send_to_online(message, data.to);
87
		
88
		module:log("info", "Announcement sent to %d online users", count);
89
		return { status = "completed", info = ("Announcement sent to %d online users"):format(count) };
90
	else
91
		return { status = "executing", form = announce_layout }, "executing";
92
	end
93
 
94
	return true;
95
end
96
 
97
local adhoc_new = module:require "adhoc".new;
98
local announce_desc = adhoc_new("Send Announcement to Online Users", "http://jabber.org/protocol/admin#announce", announce_handler, "admin");
99
module:add_item("adhoc", announce_desc);