mod_sms_free/mod_sms_free.lua
author Matthew Wild <mwild1@gmail.com>
Sat, 24 Sep 2022 09:26:26 +0100
changeset 5063 5f1120c284c5
parent 3699 5a70dd2349a7
permissions -rw-r--r--
mod_cloud_notify_extensions: Add note about dependency Noting here because people might not click through to see it on the mod_cloud_notify_encrypted page.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3699
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
     1
local http = require "net.http";
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
     2
local jid_split = require "util.jid".split;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
     3
local dataforms_new = require "util.dataforms".new;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
     4
local adhoc_new = module:require "adhoc".new;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
     5
local adhoc_simple_form = require "util.adhoc".new_simple_form;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
     6
local t_concat = table.concat;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
     7
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
     8
local store = module:open_store();
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
     9
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    10
local function api_handler(body, code)
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    11
	if code == 200 then
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    12
		module:log("debug", "SMS correctly sent.");
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    13
	elseif code == 0 then
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    14
		module:log("error", "error querying Free API: %s", body);
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    15
	elseif code >= 400 then
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    16
		module:log("warn", "received error code %d: %s", code, body);
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    17
	end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    18
end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    19
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    20
local function message_handler(event)
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    21
	local message = event.stanza;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    22
	local username, host = jid_split(message.attr.to);
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    23
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    24
	-- Only proceed if the user has set Free credentials.
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    25
	local data = store:get(username);
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    26
	if not data then
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    27
		return;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    28
	end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    29
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    30
	-- Only proceed if the message is of type chat or normal.
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    31
	local message_type = message.attr.type;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    32
	if message_type == "error" or message_type == "headline" or message_type == "groupchat" then
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    33
		-- TODO: Maybe handle groupchat or headline in the future.
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    34
		return;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    35
	end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    36
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    37
	-- Only proceed if the message contains a body.
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    38
	local body = message:get_child_text("body");
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    39
	if not body then
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    40
		return;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    41
	end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    42
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    43
	-- Only proceed if all sessions are "xa", or if there are no sessions.
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    44
	local sessions = prosody.hosts[host].sessions[username];
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    45
	if sessions then
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    46
		local do_send = true;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    47
		for _, session in pairs(sessions.sessions) do
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    48
			local show = session.presence:get_child_text("show");
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    49
			if show ~= "xa" then
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    50
				do_send = false;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    51
			end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    52
		end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    53
		if not do_send then
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    54
			return;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    55
		end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    56
	end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    57
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    58
	-- Then do the actual request to send the SMS.
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    59
	local headers = {
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    60
		user = data.user,
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    61
		pass = data.pass,
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    62
		msg = http.urlencode(body),
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    63
	};
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    64
	http.request("https://smsapi.free-mobile.fr/sendmsg", { headers = headers }, api_handler);
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    65
end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    66
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    67
local set_form = dataforms_new {
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    68
	title = "Set mobile.free.fr SMS credentials";
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    69
	instructions = "Enable the “Notifications by SMS” service at https://mobile.free.fr/moncompte/ and paste the credentials in this form.";
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    70
	{
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    71
		type = "hidden";
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    72
		name = "FORM_TYPE";
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    73
		value = "http://prosody.im/protocol/sms_free#set";
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    74
	};
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    75
	{
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    76
		type = "text-single";
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    77
		name = "user";
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    78
		label = "Your login on Free’s website";
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    79
	};
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    80
	{
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    81
		type = "text-single";
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    82
		name = "pass";
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    83
		label = "Your authentication key";
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    84
	};
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    85
};
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    86
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    87
local set_adhoc = adhoc_simple_form(set_form, function (data, errors, state)
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    88
	if errors then
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    89
		local errmsg = {};
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    90
		for name, text in pairs(errors) do
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    91
			errmsg[#errmsg + 1] = name .. ": " .. text;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    92
		end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    93
		return { status = "completed", error = { message = t_concat(errmsg, "\n") } };
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    94
	end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    95
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    96
	local username, host = jid_split(state.from);
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    97
	module:log("debug", "Setting mobile.free.fr credentials for %s@%s: user=%s, pass=%s", username, host, data.user, data.pass);
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    98
	local ok, err = store:set(username, { user = data.user, pass = data.pass });
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
    99
	if ok then
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
   100
		return { status = "completed", info = "SMS notifications to your phone enabled." };
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
   101
	else
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
   102
		return { status = "completed", error = { message = err } };
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
   103
	end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
   104
end);
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
   105
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
   106
module:provides("adhoc", adhoc_new("Set mobile.free.fr SMS notification credentials", "http://prosody.im/protocol/sms_free#set", set_adhoc));
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
   107
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
   108
module:provides("adhoc", adhoc_new("Unset mobile.free.fr SMS notifications", "http://prosody.im/protocol/sms_free#unset", function (_, data)
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
   109
	if data.action ~= "execute" then
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
   110
		return { status = "canceled" };
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
   111
	end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
   112
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
   113
	module:log("debug", "Unsetting mobile.free.fr credentials.");
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
   114
	local username, host = jid_split(data.from);
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
   115
	local ok, err = store:set(username, nil);
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
   116
	if ok then
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
   117
		return { status = "completed", info = "SMS notifications to your phone disabled." };
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
   118
	else
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
   119
		return { status = "completed", error = { message = err } };
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
   120
	end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
   121
end));
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
   122
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
   123
-- Stanzas sent to local clients.
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
   124
module:hook("message/bare", message_handler);
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
   125
module:hook("message/full", message_handler);