Skip to content

Instantly share code, notes, and snippets.

@shawnchin
Created October 23, 2022 16:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shawnchin/8d853a500d9f4ab52118a0d79e37fe83 to your computer and use it in GitHub Desktop.
Save shawnchin/8d853a500d9f4ab52118a0d79e37fe83 to your computer and use it in GitHub Desktop.
Legacy version of mod_lobby_autostart.lua
-- This module auto-activates lobby for all rooms.
--
-- IMPORTANT: do not use this unless you have some mechanism for moderators to bypass the lobby, otherwise everybody
-- stops at the lobby with nobody to admit them.
--
-- This module should be added to the main virtual host domain.
-- It assumes you have properly configured the muc_lobby_rooms module and lobby muc component.
--
--
local util = module:require "util";
local is_healthcheck_room = util.is_healthcheck_room;
local main_muc_component_host = module:get_option_string('main_muc');
local lobby_muc_component_host = module:get_option_string('lobby_muc');
if main_muc_component_host == nil then
module:log('error', 'main_muc not configured. Cannot proceed.');
return;
end
if lobby_muc_component_host == nil then
module:log('error', 'lobby not enabled missing lobby_muc config');
return;
end
-- Helper function to wait till a component is loaded before running the given callback
function run_when_component_loaded(component_host_name, callback)
local function trigger_callback()
module:log('info', 'Component loaded %s', component_host_name);
callback(module:context(component_host_name), component_host_name);
end
if prosody.hosts[component_host_name] == nil then
module:log('debug', 'Host %s not yet loaded. Will trigger when it is loaded.', component_host_name);
prosody.events.add_handler('host-activated', function (host)
if host == component_host_name then
trigger_callback();
end
end);
else
trigger_callback();
end
end
-- Helper function to wait till a component's muc module is loaded before running the given callback
function run_when_muc_module_loaded(component_host_module, component_host_name, callback)
local function trigger_callback()
module:log('info', 'MUC module loaded for %s', component_host_name);
callback(prosody.hosts[component_host_name].modules.muc, component_host_module);
end
if prosody.hosts[component_host_name].modules.muc == nil then
module:log('debug', 'MUC module for %s not yet loaded. Will trigger when it is loaded.', component_host_name);
prosody.hosts[component_host_name].events.add_handler('module-loaded', function(event)
if (event.module == 'muc') then
trigger_callback();
end
end);
else
trigger_callback()
end
end
local lobby_muc_service;
local main_muc_service;
local main_muc_module;
-- Helper method to trigger main room destroy
local function trigger_room_destroy(room)
room:set_persistent(false);
room:destroy(nil, 'main room and lobby now empty');
end
-- Handle events on main muc module
run_when_component_loaded(main_muc_component_host, function(host_module, host_name)
run_when_muc_module_loaded(host_module, host_name, function (main_muc, main_module)
main_muc_service = main_muc; -- so it can be accessed from lobby muc event handlers
main_muc_module = main_module;
main_module:hook("muc-room-pre-create", function (event)
local main_room = event.room;
if is_healthcheck_room(main_room.jid) then
return;
end
-- Activate lobby
prosody.events.fire_event("create-lobby-room", { room = main_room; });
-- we also need to disable the empty-room-deletion feature for the main room since initial users could be
-- waiting in the lobby before anybody joins the room, and empty rooms will get deleted after a period
-- and users still in lobby end up in an error state.
main_room:set_persistent(true);
end);
-- N.B. Since we main room and lobby room are now persistent, we need to trigger deletion ourselves when both
-- the main room and the lobby room is empty. This will be checked each time an occupant leaves the main room
-- of if someone drops off the lobby.
main_module:hook("muc-occupant-left", function(event)
-- Check if room should be destroyed when someone leaves the main room
local main_room = event.room;
local lobby_room_jid = main_room._data.lobbyroom;
-- If occupant leaving results in main room being empty, we trigger room destroy if
-- a) lobby exists and is not empty
-- b) lobby does not exist (possible for lobby to be disabled manually by moderator in meeting)
--
-- (main room destroy also triggers lobby room destroy in muc_lobby_rooms)
if not main_room:has_occupant() then
if lobby_room_jid == nil then -- lobby disabled
trigger_room_destroy(main_room);
else -- lobby exists
local lobby_room = lobby_muc_service.get_room_from_jid(lobby_room_jid);
if lobby_room and not lobby_room:has_occupant() then
trigger_room_destroy(main_room);
end
end
end
end);
end);
end);
-- Handle events on lobby muc module
run_when_component_loaded(lobby_muc_component_host, function(host_module, host_name)
run_when_muc_module_loaded(host_module, host_name, function (lobby_muc, lobby_module)
lobby_muc_service = lobby_muc; -- so it can be accessed from main muc event handlers
lobby_module:hook("muc-occupant-left", function(event)
-- Check if room should be destroyed when someone leaves the lobby
local lobby_room = event.room;
local main_room = lobby_room.main_room;
-- If both lobby room and main room are empty, we destroy main room.
-- (main room destroy also triggers lobby room destroy in muc_lobby_rooms)
if not lobby_room:has_occupant() and main_room and not main_room:has_occupant() then
trigger_room_destroy(main_room);
end
end);
end);
end);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment