Close room properly (prosody custom module)

I did finish my client side implementation and it works cleanly. Much better that the room.clear() and room.destroy(). I did not need to use the listener. Before I show you how I implemented let me explain what my goal was.

Goal: I wanted to limit my duration of call to a max time and also limit the amount of time we have less than the required number of occupants for a given time. The easiest way to limit was to disconnect every one individually client side.

Implementation: (I will list for someone who is getting mixed up with which code where)

  • In /usr/share/jitsi-meet/ create a file myname_conf.js
  • In /usr/share/jitsi-meet/index.html add this line … -#include virtual="/myname_conf_q.js" … and also add the myname_conf.js to the var critical files (not sure if this last one needs to be done).
  • In myname_conf.js add code to use a timer
    var timer;
    var ms = 60000; // this is one minute
    var occCount = 0;
    var mins = 0;
    … add what ever vars you need
    function startCounting(){…
    min = min +1;
    occCount = APP.conference.membersCount; // this is working

    // Do whatever you want with the time and members count
    // To redirect to home page from here is simple
    setTimeout(startCounting, ms); // the function calls itself before exiting
    // you should be able to APP.conference.addConferenceListener in this file - i have not tired
    timer = setTimeout(startCounting, ms);
  • You do not need to restart anything when you do this just go straight to testing after you save the js file.

Hope this helps.

1 Like

Please see my post above this should help you redirect to home page.

Can someone please tell me why I keep getting this error on my prososdy.log when I try to clear room. Is it because the occupants are all owners and moderators?
timer error Traceback[timer]: /usr/share/jitsi-meet/prosody-plugins/mod_quit.lua:63: attempt to index local ‘stanza’ (a nil value)
/usr/share/jitsi-meet/prosody-plugins/mod_quit.lua:63: in function ‘?’
/usr/lib/prosody/util/events.lua:79: in function </usr/lib/prosody/util/events.lua:75>
(…tail calls…)
/usr/lib/prosody/modules/muc/muc.lib.lua:882: in function ‘clear’
/usr/share/jitsi-meet/prosody-plugins/mod_quit.lua:27: in function ‘delayedCounter’
/usr/share/jitsi-meet/prosody-plugins/mod_quit.lua:25: in function </usr/share/jitsi-meet/prosody-plugins/mod_quit.lua:25>
[C]: in function ‘xpcall’
/usr/lib/prosody/util/timer.lua:39: in function ‘callback’
/usr/lib/prosody/net/server_select.lua:876: in function ‘?’
/usr/lib/prosody/net/server_select.lua:907: in function </usr/lib/prosody/net/server_select.lua:899>
[C]: in function ‘xpcall’
/usr/bin/prosody:80: in function ‘loop’
/usr/bin/prosody:90: in main chunk
[C]: in ?

I tried to add clientside javascript to do the redirection.
I created the file: /usr/share/jitsi-meet/quit_conf.js with the following code:

In index.html I added the script
<script><!--#include virtual="/quit_conf.js" --></script><!-- add quit conference script -->

And I also added it to the var critical files.

Via console.log… I confirmed that the module is loaded.
But I get an error

script loaded

TypeError: H is undefined[conference.js:2512:8](webpack:///conference.js)

addConferenceListener conference.js:2512


Do you have any idea why the “APP.conference.addConferenceListener…”-part is not working?
I destroy the room when the moderator leaves as descriped in Close room properly (prosody custom module) and Close room properly (prosody custom module)


Hi @plokta,
Please let me know is this work on with out enable token base authentication.

You need to wait for APP and APP.conference and some other things to be ready. You cannot add the event listeners as soon as the page loads.

Like this:

if (typeof APP !== "undefined" && 
    typeof APP.conference !== "undefined" &&
   // okay to attach listeners now
  APP.conference.addConferenceListener("conference.failed",function (e)
        case "conference.destroyed":


This solution isn’t linked to authentication. the focus_user_jid user is always added the the conferences behind the scenes even if you are not using the secure domain setup. It’s usually "" If your domain is then your focus user is

Hi @corby,
Thank you very much for your quick response. I tried to do your solution. But the thing is all the logs are work. But participent not kick out. Can you please help me to fix this issue. ?

Sorry @akalana, I have not implemented @plokta solution on my Jitsi Meet server. I was just trying to clarify some points as they were asked.

Hi @corby
Please let me know do you have any solution for this ?

Apologies if this sounds rude, but I think so many codes flying around make a new user/developer on this thread even more confused.

Not sure if there is a way to consolidate all the coddes in one place that shows what all needs to be done from start to finish in one-shot. And pls dont forget to include/metion the path of the file that needs to be edited.

I for example have an issue (right now). I opened a room few weeks ago and when I run the live room report, I can see that room is still open with 3 participant in it. So I joined that room as a new user and I can still join it and the report shows 4 users in the room, which means that the room is live.

I have used all the codes presented here in different folders and files but the session/users/room does not get terminated/killed/disconnected.

So either I am editing a wrong file (@ wrong path) or my setup/infrastructure is different or the given code does not work after the recent update (which I doubt).

If someone is willing to help me only, I am happy to consolidate everything and present it as a document that can be used by others.

Just so you know,I am behind a natted firewall and right now I am running an open server, which means no one needs to register or authenticate anything. (Can this be the root cause of the issue)?
Everything else so far is working perfectly fine… its just that I want to terminate the room once the moderator leaves.

Many Thanks,

1 Like

Is it possible that we can pass the. Duration value in the jwt token e.g for 1hr and acoording to that when Jitsi room reaches at time limit room will be destroyed by

If yes please guide me how to achieve this

Thank you

Hi @plokta,

Where should i put these settings:

close_room_delay = 30;  -- seconds until conference is destroyed after last moderator left
focus_user_jid = "focus@meet.jitsi";  -- JID of your focus/jicofo user. Should be same as in 'admins' array

Should it be in /etc/prosody/conf.d/mydomain.cfg.lua?


the time restricted conference

Hi everyone.

I tried to implement this in my self-host Jitsi but it doesn’t work. I created a file called “mod_close_rooms.lua” in this path:


And here, I put this code (is the same code above from @plotka ):

local async = require "util.async";
local timer = require "util.timer";

local delay = module:get_option_number("close_room_delay", 30);
local focus_jid = module:get_option_string("focus_user_jid", "");

module:log("info","module loaded");

local async_destroy = async.runner(function (event)
        local leaver = event.occupant.bare_jid;
        local room =;
    local wait, done = async.waiter();

    timer.add_task(delay, function ()
    wait(); -- Wait here until done() is called

    local mods = room:each_affiliation("owner");
    for mod in mods do
        module:log("debug", "administrador encontrado: %s", tostring(mod));
            if mod ~= leaver and mod ~= focus_jid then
            -- there is still a moderator in this room, dont kick participants
            module:log("info", "el administrador sigue presente en la sala: %s", mod);
    module:log("info", "room destroyed.");

module:hook("muc-occupant-left", function(event)
    local barejid = event.occupant.bare_jid;
    local role =;
    module:log("debug", "el usuario %s ha dejado la sala: %s", role, barejid);
    if role == "owner" and barejid ~= "" then

So, I modified the file:


To put the changes that I see above and the conference component it has been like this:

Component "" "muc"
    storage = "memory"
    modules_enabled = {
        -- "token_verification";
    admins = { "" }
    muc_room_locking = false
    muc_room_default_public_jids = true
    close_room_delay = 10;  -- seconds until conference is destroyed after last moderator left
    focus_user_jid = "";  -- JID of your focus/jicofo user. Should be same as in 'admins' array

I restarted the prosody service using:

sudo systemctl restart prosody

Finally, I started a meeting in a laptop and gives me administrator roles (correct) and then in other laptop I join the meeting. And, when I hang up (leave) the administrator, the other user stills in the meeting, don’t close the room automatically after 10 seconds.

So, where can be the mistake?


I used the same code as you did, but it says async file missing. How to solve this, Please help.

To check if the prosody muc is closed, open a conference with three participants and make the admin leave. After 10 seconds, the remaining two participants should be disconnected from each other, i.e., while they remain in the conference view, they cannot see or hear each other anymore.

The example prosody module destroys the muc room, so the conference is killed. However, as mentioned in the original post above, you would need to implement a hangup or a redirect in the frontend code if you want the participants to leave the conference view.

I did exactly same as what @Ferran_Munoz didi but still not working!

module:log(“debug”, “el usuario %s ha dejado la sala: %s”, role, barejid);
if role == “owner” and barejid ~= “” then

do I need to change with from the module?

does it work with JWT token authentication? do we need to define something in the JWT payload?

Yes, you need to set the config option focus_user_jid to the exact same value of the focus user from the admins array. This may also be the same issue @Ferran_Munoz has had when trying this code.

It should work with JWT authentication as well, since the focus user is always present in a conference regardless of the authentication method used. However, I did not try it myself with JWT auth enabled.

This is not necessary but could probably be done if you want to. As has been discussed in the beginning of this thread, you could try to check event.origin.auth_token to see if the leaving user is authenticated via JWT instead of checking for the owner role

So I have to do the following steps:

  1. Save the above code as /usr/share/jitsi-meet/prosody-plugins/mod_quit.lua

local async = require “util.async”;

  1. Paste “quit”; in /etc/prosody/conf.avail/my.domain.cfg.lua
    Is this ok?