parent
b110456029
commit
a06ef00e2a
@ -14,6 +14,9 @@ local get_room_from_jid = rawget(mod_muc, "get_room_from_jid");
|
|||||||
|
|
||||||
module:depends"http";
|
module:depends"http";
|
||||||
|
|
||||||
|
local mod_muc_peertubelivechat_terms = module:depends"muc_peertubelivechat_terms";
|
||||||
|
local set_muc_terms = rawget(mod_muc_peertubelivechat_terms, "set_muc_terms");
|
||||||
|
|
||||||
function check_auth(routes)
|
function check_auth(routes)
|
||||||
local function check_request_auth(event)
|
local function check_request_auth(event)
|
||||||
local apikey = module:get_option_string("peertubelivechat_manage_rooms_apikey", "")
|
local apikey = module:get_option_string("peertubelivechat_manage_rooms_apikey", "")
|
||||||
@ -94,6 +97,12 @@ local function update_room(event)
|
|||||||
must104 = true;
|
must104 = true;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if (type(config.livechat_muc_terms) == "string") then
|
||||||
|
-- to easily detect if the value is given or not, we consider that the caller passes "" when terms must be deleted.
|
||||||
|
if set_muc_terms then
|
||||||
|
set_muc_terms(room, config.livechat_muc_terms or nil);
|
||||||
|
end
|
||||||
|
end
|
||||||
if type(config.removeAffiliationsFor) == "table" then
|
if type(config.removeAffiliationsFor) == "table" then
|
||||||
-- array of jids
|
-- array of jids
|
||||||
for _, jid in ipairs(config.removeAffiliationsFor) do
|
for _, jid in ipairs(config.removeAffiliationsFor) do
|
||||||
|
@ -121,6 +121,11 @@ local function apply_config(room, settings)
|
|||||||
if (type(config.mute_anonymous) == "boolean") then
|
if (type(config.mute_anonymous) == "boolean") then
|
||||||
room._data.x_peertubelivechat_mute_anonymous = config.mute_anonymous;
|
room._data.x_peertubelivechat_mute_anonymous = config.mute_anonymous;
|
||||||
end
|
end
|
||||||
|
if (type(config.livechat_muc_terms) == "string") then
|
||||||
|
-- we don't need to use set_muc_terms here, as this is called for a newly created room
|
||||||
|
-- (and thus we don't need to broadcast changes)
|
||||||
|
room._data.livechat_muc_terms = config.livechat_muc_terms;
|
||||||
|
end
|
||||||
elseif config ~= nil then
|
elseif config ~= nil then
|
||||||
module:log("error", "Invalid config returned from API for %s: %q", room.jid, config);
|
module:log("error", "Invalid config returned from API for %s: %q", room.jid, config);
|
||||||
return nil, "format", { field = "config" };
|
return nil, "format", { field = "config" };
|
||||||
|
@ -29,6 +29,6 @@ The nickname that will be used by service messages.
|
|||||||
This module reserves the nickname, so than nobody can use it in MUC rooms
|
This module reserves the nickname, so than nobody can use it in MUC rooms
|
||||||
(we don't want any user to spoof this nickname).
|
(we don't want any user to spoof this nickname).
|
||||||
|
|
||||||
### muc_terms
|
### muc_terms_global
|
||||||
|
|
||||||
The global terms.
|
The global terms.
|
||||||
|
@ -7,30 +7,71 @@
|
|||||||
-- Please see the Peertube livechat plugin copyright information.
|
-- Please see the Peertube livechat plugin copyright information.
|
||||||
-- https://livingston.frama.io/peertube-plugin-livechat/credits/
|
-- https://livingston.frama.io/peertube-plugin-livechat/credits/
|
||||||
--
|
--
|
||||||
|
|
||||||
|
-- Exposed functions:
|
||||||
|
-- get_muc_terms
|
||||||
|
-- set_muc_terms
|
||||||
|
|
||||||
local jid_escape = require "util.jid".escape;
|
local jid_escape = require "util.jid".escape;
|
||||||
local jid_resource = require "util.jid".resource;
|
local jid_resource = require "util.jid".resource;
|
||||||
local st = require "util.stanza";
|
local st = require "util.stanza";
|
||||||
local id = require "util.id";
|
local id = require "util.id";
|
||||||
|
|
||||||
local service_nickname = module:get_option_string("muc_terms_service_nickname", "Service");
|
local service_nickname = module:get_option_string("muc_terms_service_nickname", "Service");
|
||||||
local global_terms = module:get_option_string("muc_terms", "");
|
local global_terms = module:get_option_string("muc_terms_global", "");
|
||||||
|
|
||||||
|
local function create_terms_message(room, type, terms)
|
||||||
|
local from = room.jid .. '/' .. jid_escape(service_nickname);
|
||||||
|
module:log("debug", "Creating %s terms message from %s (room %s)", type, from, room);
|
||||||
|
local msg = st.message({
|
||||||
|
type = "groupchat",
|
||||||
|
from = from,
|
||||||
|
id = id.medium()
|
||||||
|
}, terms)
|
||||||
|
:tag('x-livechat-terms', { type = type }):up(); -- adding a custom tag to specify that it is a "terms" message, so that frontend can display it with a special template.
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
end
|
||||||
|
|
||||||
|
-- MUC Getter/Setter
|
||||||
|
function get_muc_terms(room)
|
||||||
|
return room._data.livechat_muc_terms or nil;
|
||||||
|
end
|
||||||
|
|
||||||
|
function set_muc_terms(room, terms)
|
||||||
|
terms = terms or nil;
|
||||||
|
|
||||||
|
if get_muc_terms(room) == terms then return false; end
|
||||||
|
|
||||||
|
room._data.livechat_muc_terms = terms;
|
||||||
|
if terms ~= nil then
|
||||||
|
-- we must send new terms to all occupants.
|
||||||
|
local msg = create_terms_message(room, "muc", terms);
|
||||||
|
module:log("debug", "Broadcasting terms message to room %s", room);
|
||||||
|
room:broadcast_message(msg);
|
||||||
|
end
|
||||||
|
return true;
|
||||||
|
end
|
||||||
|
|
||||||
-- send the terms when joining:
|
-- send the terms when joining:
|
||||||
function send_terms(event)
|
local function send_terms(event)
|
||||||
local origin = event.origin;
|
local origin = event.origin;
|
||||||
local room = event.room;
|
local room = event.room;
|
||||||
local occupant = event.occupant;
|
local occupant = event.occupant;
|
||||||
if global_terms then
|
if global_terms then
|
||||||
|
module:log("debug", "Sending global terms to %s", occupant.jid);
|
||||||
|
local msg = create_terms_message(room, "global", global_terms);
|
||||||
|
msg.attr.to = occupant.jid;
|
||||||
|
origin.send(msg);
|
||||||
|
end
|
||||||
|
|
||||||
|
local muc_terms = get_muc_terms(room);
|
||||||
|
if muc_terms then
|
||||||
local from = room.jid .. '/' .. jid_escape(service_nickname);
|
local from = room.jid .. '/' .. jid_escape(service_nickname);
|
||||||
module:log("debug", "Sending global terms to %s from %s (room %s)", occupant.jid, from, room);
|
module:log("debug", "Sending muc terms to %s", occupant.jid);
|
||||||
local message = st.message({
|
local msg = create_terms_message(room, "muc", muc_terms);
|
||||||
type = "groupchat",
|
msg.attr.to = occupant.jid;
|
||||||
to = occupant.jid,
|
origin.send(msg);
|
||||||
from = from,
|
|
||||||
id = id.medium()
|
|
||||||
}, global_terms)
|
|
||||||
:tag('x-livechat-terms', { type = "global" }):up(); -- adding a custom tag to specify that it is a "terms" message, so that frontend can display it with a special template.
|
|
||||||
origin.send(message);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- Note: we could do that on muc-occupant-joined or muc-occupant-session-new.
|
-- Note: we could do that on muc-occupant-joined or muc-occupant-session-new.
|
||||||
@ -39,7 +80,7 @@ end
|
|||||||
module:hook("muc-occupant-session-new", send_terms);
|
module:hook("muc-occupant-session-new", send_terms);
|
||||||
|
|
||||||
-- reserve the service_nickname:
|
-- reserve the service_nickname:
|
||||||
function enforce_nick_policy(event)
|
local function enforce_nick_policy(event)
|
||||||
local origin, stanza = event.origin, event.stanza;
|
local origin, stanza = event.origin, event.stanza;
|
||||||
local requested_nick = jid_resource(stanza.attr.to);
|
local requested_nick = jid_resource(stanza.attr.to);
|
||||||
local room = event.room;
|
local room = event.room;
|
||||||
|
@ -119,6 +119,7 @@ async function initChannelConfiguration (options: RegisterServerOptions): Promis
|
|||||||
// FIXME: this piece of code should not be in this file (nothing to do with initChannelConfiguration,
|
// FIXME: this piece of code should not be in this file (nothing to do with initChannelConfiguration,
|
||||||
// but will be more efficient to add here, as we already tested hasChat).
|
// but will be more efficient to add here, as we already tested hasChat).
|
||||||
// Note: no need to await here, would only degrade performances.
|
// Note: no need to await here, would only degrade performances.
|
||||||
|
// FIXME: should also update livechat_muc_terms if channel has changed.
|
||||||
updateProsodyRoom(options, video.uuid, {
|
updateProsodyRoom(options, video.uuid, {
|
||||||
name: video.name
|
name: video.name
|
||||||
}).then(
|
}).then(
|
||||||
|
@ -64,6 +64,7 @@ async function updateProsodyRoom (
|
|||||||
data: {
|
data: {
|
||||||
name?: string
|
name?: string
|
||||||
slow_mode_duration?: number
|
slow_mode_duration?: number
|
||||||
|
livechat_muc_terms?: string
|
||||||
addAffiliations?: Affiliations
|
addAffiliations?: Affiliations
|
||||||
removeAffiliationsFor?: string[]
|
removeAffiliationsFor?: string[]
|
||||||
}
|
}
|
||||||
@ -92,6 +93,9 @@ async function updateProsodyRoom (
|
|||||||
if (('slow_mode_duration' in data) && data.slow_mode_duration !== undefined) {
|
if (('slow_mode_duration' in data) && data.slow_mode_duration !== undefined) {
|
||||||
apiData.slow_mode_duration = data.slow_mode_duration
|
apiData.slow_mode_duration = data.slow_mode_duration
|
||||||
}
|
}
|
||||||
|
if ('livechat_muc_terms' in data) {
|
||||||
|
apiData.livechat_muc_terms = data.livechat_muc_terms ?? ''
|
||||||
|
}
|
||||||
if (('addAffiliations' in data) && data.addAffiliations !== undefined) {
|
if (('addAffiliations' in data) && data.addAffiliations !== undefined) {
|
||||||
apiData.addAffiliations = data.addAffiliations
|
apiData.addAffiliations = data.addAffiliations
|
||||||
}
|
}
|
||||||
|
@ -246,7 +246,7 @@ class ProsodyConfigContent {
|
|||||||
this.muc.add('modules_enabled', 'muc_peertubelivechat_terms')
|
this.muc.add('modules_enabled', 'muc_peertubelivechat_terms')
|
||||||
this.muc.set('muc_terms_service_nickname', 'Peertube')
|
this.muc.set('muc_terms_service_nickname', 'Peertube')
|
||||||
if (chatTerms) {
|
if (chatTerms) {
|
||||||
this.muc.set('muc_terms', new ConfigEntryValueMultiLineString(chatTerms))
|
this.muc.set('muc_terms_global', new ConfigEntryValueMultiLineString(chatTerms))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
import type { RegisterServerOptions } from '@peertube/peertube-types'
|
import type { RegisterServerOptions } from '@peertube/peertube-types'
|
||||||
import type { RoomConf } from 'xmppjs-chat-bot'
|
import type { RoomConf } from 'xmppjs-chat-bot'
|
||||||
import { getProsodyDomain } from '../prosody/config/domain'
|
import { getProsodyDomain } from '../prosody/config/domain'
|
||||||
import { listProsodyRooms } from '../prosody/api/manage-rooms'
|
import { listProsodyRooms, updateProsodyRoom } from '../prosody/api/manage-rooms'
|
||||||
import { getChannelInfosById } from '../database/channel'
|
import { getChannelInfosById } from '../database/channel'
|
||||||
import { ChannelConfigurationOptions } from '../../../shared/lib/types'
|
import { ChannelConfigurationOptions } from '../../../shared/lib/types'
|
||||||
import {
|
import {
|
||||||
@ -292,10 +292,7 @@ class RoomChannel {
|
|||||||
this.logger.info('Syncing...')
|
this.logger.info('Syncing...')
|
||||||
this.isWriting = true
|
this.isWriting = true
|
||||||
|
|
||||||
// Note 2024-05-15: slow_mode_duration becomes a default value.
|
const prosodyRoomUpdates = new Map<string, Parameters<typeof updateProsodyRoom>[2]>()
|
||||||
// We dont need prosodyRoomUpdates anymore. but keeping the code commented,
|
|
||||||
// if we want to enable again a similar sync.
|
|
||||||
// const prosodyRoomUpdates = new Map<string, Parameters<typeof updateProsodyRoom>[2]>()
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const data = this._serializeData() // must be atomic
|
const data = this._serializeData() // must be atomic
|
||||||
@ -355,12 +352,12 @@ class RoomChannel {
|
|||||||
|
|
||||||
await BotConfiguration.singleton().updateRoom(roomJID, botConf)
|
await BotConfiguration.singleton().updateRoom(roomJID, botConf)
|
||||||
|
|
||||||
// // Now we also must update some room metadata (slow mode duration, ...)
|
// Now we also must update some room metadata on Prosody side (livechat_muc_terms, ...)
|
||||||
// // This can be done without waiting for the API call to finish, but we don't want to send thousands of
|
// This can be done without waiting for the API call to finish, but we don't want to send thousands of
|
||||||
// // API calls at the same time. So storing data in a map, and we well launch it sequentially at the end
|
// API calls at the same time. So storing data in a map, and we well launch it sequentially at the end
|
||||||
// prosodyRoomUpdates.set(roomJID, {
|
prosodyRoomUpdates.set(roomJID, {
|
||||||
// slow_mode_duration: channelConfigurationOptions.slowMode.duration
|
livechat_muc_terms: channelConfigurationOptions.terms
|
||||||
// })
|
})
|
||||||
|
|
||||||
this.roomConfToUpdate.delete(roomJID)
|
this.roomConfToUpdate.delete(roomJID)
|
||||||
}
|
}
|
||||||
@ -374,22 +371,22 @@ class RoomChannel {
|
|||||||
this.isWriting = false
|
this.isWriting = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (prosodyRoomUpdates.size) {
|
if (prosodyRoomUpdates.size) {
|
||||||
// // Here we don't have to wait.
|
// Here we don't have to wait.
|
||||||
// // If it fails (for example because we are turning off prosody), it is not a big deal.
|
// If it fails (for example because we are turning off prosody), it is not a big deal.
|
||||||
// // Does not worth the cost to wait.
|
// Does not worth the cost to wait.
|
||||||
// // eslint-disable-next-line @typescript-eslint/no-misused-promises
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||||
// setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
// this.logger.info('Syncing done, but still some data to send to Prosody')
|
this.logger.info('Syncing done, but still some data to send to Prosody')
|
||||||
// for (const [roomJID, data] of prosodyRoomUpdates.entries()) {
|
for (const [roomJID, data] of prosodyRoomUpdates.entries()) {
|
||||||
// try {
|
try {
|
||||||
// await updateProsodyRoom(this.options, roomJID, data)
|
await updateProsodyRoom(this.options, roomJID, data)
|
||||||
// } catch (err) {
|
} catch (err) {
|
||||||
// this.logger.error(`Failed updating prosody room info: "${err as string}".`)
|
this.logger.error(`Failed updating prosody room info: "${err as string}".`)
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }, 0)
|
}, 0)
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,6 +37,7 @@ interface RoomDefaults {
|
|||||||
// Following fields are specific to livechat (for now), and requires a customized version for mod_muc_http_defaults.
|
// Following fields are specific to livechat (for now), and requires a customized version for mod_muc_http_defaults.
|
||||||
slow_mode_duration?: number
|
slow_mode_duration?: number
|
||||||
mute_anonymous?: boolean
|
mute_anonymous?: boolean
|
||||||
|
livechat_muc_terms?: string
|
||||||
}
|
}
|
||||||
affiliations?: Affiliations
|
affiliations?: Affiliations
|
||||||
}
|
}
|
||||||
@ -50,7 +51,8 @@ async function _getChannelSpecificOptions (
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
slow_mode_duration: channelOptions.slowMode.duration,
|
slow_mode_duration: channelOptions.slowMode.duration,
|
||||||
mute_anonymous: channelOptions.mute.anonymous
|
mute_anonymous: channelOptions.mute.anonymous,
|
||||||
|
livechat_muc_terms: channelOptions.terms
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user