ansible-roles/roles/jitsi/files/prosody/modules/mod_measure_message_count.lua
2024-07-22 23:00:11 +02:00

167 lines
5.3 KiB
Lua

-- Measure the number of messages used in a meeting. Sends amplitude event.
-- Needs to be activated under the muc component where the limit needs to be applied (main muc and breakout muc)
-- Copyright (C) 2023-present 8x8, Inc.
local jid = require 'util.jid';
local http = require 'net.http';
local cjson_safe = require 'cjson.safe'
local amplitude_endpoint = module:get_option_string('amplitude_endpoint', 'https://api2.amplitude.com/2/httpapi');
local amplitude_api_key = module:get_option_string('amplitude_api_key');
if not amplitude_api_key then
module:log("warn", "No 'amplitude_api_key' option set, disabling amplitude reporting");
return
end
local muc_domain_base = module:get_option_string('muc_mapper_domain_base');
local isBreakoutRoom = module.host == 'breakout.' .. muc_domain_base;
local util = module:require 'util';
local is_healthcheck_room = util.is_healthcheck_room;
local extract_subdomain = util.extract_subdomain;
module:log('info', 'Loading measure message count');
local shard_name = module:context(muc_domain_base):get_option_string('shard_name');
local region_name = module:context(muc_domain_base):get_option_string('region_name');
local release_number = module:context(muc_domain_base):get_option_string('release_number');
local http_headers = {
['User-Agent'] = 'Prosody ('..prosody.version..'; '..prosody.platform..')',
['Content-Type'] = 'application/json'
};
local inspect = require "inspect"
function table.clone(t)
return {table.unpack(t)}
end
local function event_cb(content_, code_, response_, request_)
if code_ == 200 or code_ == 204 then
module:log('debug', 'URL Callback: Code %s, Content %s, Request (host %s, path %s, body %s), Response: %s',
code_, content_, request_.host, request_.path, inspect(request_.body), inspect(response_));
else
module:log('warn', 'URL Callback non successful: Code %s, Content %s, Request (%s), Response: %s',
code_, content_, inspect(request_), inspect(response_));
end
end
function send_event(room)
local user_properties = {
shard_name = shard_name;
region_name = region_name;
release_number = release_number;
};
local node = jid.split(room.jid);
local subdomain, room_name = extract_subdomain(node);
user_properties.tenant = subdomain or '/';
user_properties.conference_name = room_name or node;
local event_properties = {
messages_count = room._muc_messages_count or 0;
polls_count = room._muc_polls_count or 0;
tenant_mismatch = room.jitsi_meet_tenant_mismatch or false;
};
if room.created_timestamp then
event_properties.duration = (os.time() * 1000 - room.created_timestamp) / 1000;
end
local event = {
api_key = amplitude_api_key;
events = {
{
user_id = room._data.meetingId;
device_id = room._data.meetingId;
event_type = 'conference_ended';
event_properties = event_properties;
user_properties = user_properties;
}
};
};
local request = http.request(amplitude_endpoint, {
headers = http_headers,
method = "POST",
body = cjson_safe.encode(event)
}, event_cb);
end
function on_message(event)
local stanza = event.stanza;
local body = stanza:get_child('body');
if not body then
-- we ignore messages without body - lobby, polls ...
return;
end
local session = event.origin;
if not session or not session.jitsi_web_query_room then
return;
end
-- get room name with tenant and find room.
local room = get_room_by_name_and_subdomain(session.jitsi_web_query_room, session.jitsi_web_query_prefix);
if not room then
module:log('warn', 'No room found found for %s/%s',
session.jitsi_web_query_prefix, session.jitsi_web_query_room);
return;
end
if not room._muc_messages_count then
room._muc_messages_count = 0;
end
room._muc_messages_count = room._muc_messages_count + 1;
end
-- Conference ended, send stats
function room_destroyed(event)
local room, session = event.room, event.origin;
if is_healthcheck_room(room.jid) then
return;
end
if isBreakoutRoom then
return;
end
send_event(room);
end
function poll_created(event)
local session = event.event.origin;
-- get room name with tenant and find room.
local room = get_room_by_name_and_subdomain(session.jitsi_web_query_room, session.jitsi_web_query_prefix);
if not room then
module:log('warn', 'No room found found for %s/%s',
session.jitsi_web_query_prefix, session.jitsi_web_query_room);
return false;
end
if not room._muc_polls_count then
room._muc_polls_count = 0;
end
room._muc_polls_count = room._muc_polls_count + 1;
end
module:hook('message/full', on_message); -- private messages
module:hook('message/bare', on_message); -- room messages
module:hook('muc-room-destroyed', room_destroyed, -1);
module:hook("muc-occupant-left", function(event)
local occupant, room = event.occupant, event.room;
local session = event.origin;
if session and session.jitsi_meet_tenant_mismatch then
room.jitsi_meet_tenant_mismatch = true;
end
end);
module:hook('poll-created', poll_created);