Compare commits

...

5 Commits

Author SHA1 Message Date
damencho
a24ddf205c feat(visitors): Adds enabled flag in the metadata. 2025-07-09 15:51:21 +03:00
damencho
7a97d15e89 feat(conference): Clears any error from previous attempts.
When you see the error, you may click join on pre-join again, which may succeeded, so clear previous errors.
2025-07-09 14:14:49 +03:00
damencho
1acb99d763 fix(av-moderation): Fixes auto starting av moderation, notify everyone. 2025-07-08 21:18:44 +03:00
damencho
adbe990867 fix(visitors): A join case with live rooms. 2025-07-08 19:10:28 +03:00
Saúl Ibarra Corretgé
a4367567ab fix(amplitude) adjust to new SDK API changes
Ref: https://amplitude.com/docs/sdks/analytics/browser/migrate-from-javascript-sdk-to-browser-sdk-2-0
2025-07-08 17:40:46 +02:00
10 changed files with 85 additions and 52 deletions

View File

@@ -1131,10 +1131,6 @@ var config = {
// The Amplitude APP Key:
// amplitudeAPPKey: '<APP_KEY>',
// Enables Amplitude UTM tracking:
// Default value is false.
// amplitudeIncludeUTM: false,
// Obfuscates room name sent to analytics (amplitude, rtcstats)
// Default value is false.
// obfuscateRoomName: false,

View File

@@ -84,7 +84,6 @@ export async function createHandlers({ getState }: IStore) {
} = config;
const {
amplitudeAPPKey,
amplitudeIncludeUTM,
blackListedEvents,
scriptURLs,
matomoEndpoint,
@@ -94,7 +93,6 @@ export async function createHandlers({ getState }: IStore) {
const { group, user } = state['features/base/jwt'];
const handlerConstructorOptions = {
amplitudeAPPKey,
amplitudeIncludeUTM,
blackListedEvents,
envType: deploymentInfo?.envType || 'dev',
matomoEndpoint,

View File

@@ -11,7 +11,6 @@ export interface IEvent {
interface IOptions {
amplitudeAPPKey?: string;
amplitudeIncludeUTM?: boolean;
blackListedEvents?: string[];
envType?: string;
group?: string;

View File

@@ -4,7 +4,7 @@ import logger from '../logger';
import AbstractHandler, { IEvent } from './AbstractHandler';
import { fixDeviceID } from './amplitude/fixDeviceID';
import amplitude from './amplitude/lib';
import amplitude, { initAmplitude } from './amplitude/lib';
/**
* Analytics handler for Amplitude.
@@ -15,8 +15,7 @@ export default class AmplitudeHandler extends AbstractHandler {
* Creates new instance of the Amplitude analytics handler.
*
* @param {Object} options - The amplitude options.
* @param {string} options.amplitudeAPPKey - The Amplitude app key required by the Amplitude API.
* @param {boolean} options.amplitudeIncludeUTM - Whether to include UTM parameters
* @param {string} options.amplitudeAPPKey - The Amplitude app key required by the Amplitude API
* in the Amplitude events.
*/
constructor(options: any) {
@@ -24,47 +23,26 @@ export default class AmplitudeHandler extends AbstractHandler {
const {
amplitudeAPPKey,
amplitudeIncludeUTM: includeUtm = true,
user
} = options;
this._enabled = true;
const onError = (e: Error) => {
logger.error('Error initializing Amplitude', e);
this._enabled = false;
};
// Forces sending all events on exit (flushing) via sendBeacon
const onExitPage = () => {
amplitude.flush();
};
if (navigator.product === 'ReactNative') {
amplitude.init(amplitudeAPPKey);
fixDeviceID(amplitude);
} else {
const amplitudeOptions: any = {
includeReferrer: true,
includeUtm,
saveParamsReferrerOncePerSession: false,
onError,
onExitPage
};
amplitude.init(amplitudeAPPKey, undefined, amplitudeOptions);
fixDeviceID(amplitude);
}
if (user) {
amplitude.setUserId(user);
}
initAmplitude(amplitudeAPPKey, user)
.then(() => {
logger.info('Amplitude initialized');
fixDeviceID(amplitude);
})
.catch(e => {
logger.error('Error initializing Amplitude', e);
this._enabled = false;
});
}
/**
* Sets the Amplitude user properties.
*
* @param {Object} userProps - The user portperties.
* @param {Object} userProps - The user properties.
* @returns {void}
*/
setUserProperties(userProps: any) {
@@ -95,7 +73,7 @@ export default class AmplitudeHandler extends AbstractHandler {
const eventName = this._extractName(event) ?? '';
amplitude.logEvent(eventName, event);
amplitude.track(eventName, event);
}
/**

View File

@@ -1,3 +1,15 @@
import { createInstance } from '@amplitude/analytics-react-native';
import amplitude from '@amplitude/analytics-react-native';
export default createInstance();
export default amplitude;
/**
* Initializes the Amplitude instance.
*
* @param {string} amplitudeAPPKey - The Amplitude app key.
* @param {string | undefined} user - The user ID.
* @returns {Promise} The initialized Amplitude instance.
*/
export function initAmplitude(
amplitudeAPPKey: string, user: string | undefined): Promise<unknown> {
return amplitude.init(amplitudeAPPKey, user, {}).promise;
}

View File

@@ -1,3 +1,38 @@
import { createInstance } from '@amplitude/analytics-browser';
export default createInstance();
const amplitude = createInstance();
export default amplitude;
/**
* Initializes the Amplitude instance.
*
* @param {string} amplitudeAPPKey - The Amplitude app key.
* @param {string | undefined} user - The user ID.
* @returns {Promise} The initialized Amplitude instance.
*/
export function initAmplitude(
amplitudeAPPKey: string, user: string | undefined): Promise<unknown> {
// Forces sending all events on exit (flushing) via sendBeacon.
window.addEventListener('pagehide', () => {
// Set https transport to use sendBeacon API.
amplitude.setTransport('beacon');
// Send all pending events to server.
amplitude.flush();
});
const options = {
autocapture: {
attribution: true,
pageViews: true,
sessions: false,
fileDownloads: false,
formInteractions: false,
elementInteractions: false
},
defaultTracking: false
};
return amplitude.init(amplitudeAPPKey, user, options).promise;
}

View File

@@ -16,7 +16,7 @@ import { IStore } from '../../app/types';
import { removeLobbyChatParticipant } from '../../chat/actions.any';
import { openDisplayNamePrompt } from '../../display-name/actions';
import { isVpaasMeeting } from '../../jaas/functions';
import { showErrorNotification, showNotification } from '../../notifications/actions';
import { clearNotifications, showErrorNotification, showNotification } from '../../notifications/actions';
import { NOTIFICATION_TIMEOUT_TYPE } from '../../notifications/constants';
import { INotificationProps } from '../../notifications/types';
import { hasDisplayName } from '../../prejoin/utils';
@@ -25,7 +25,7 @@ import LocalRecordingManager from '../../recording/components/Recording/LocalRec
import { AudioMixerEffect } from '../../stream-effects/audio-mixer/AudioMixerEffect';
import { iAmVisitor } from '../../visitors/functions';
import { overwriteConfig } from '../config/actions';
import { CONNECTION_ESTABLISHED, CONNECTION_FAILED } from '../connection/actionTypes';
import { CONNECTION_ESTABLISHED, CONNECTION_FAILED, CONNECTION_WILL_CONNECT } from '../connection/actionTypes';
import { connectionDisconnected, disconnect } from '../connection/actions';
import { validateJwt } from '../jwt/functions';
import { JitsiConferenceErrors, JitsiConferenceEvents, JitsiConnectionErrors } from '../lib-jitsi-meet';
@@ -99,6 +99,11 @@ MiddlewareRegistry.register(store => next => action => {
case CONNECTION_FAILED:
return _connectionFailed(store, next, action);
case CONNECTION_WILL_CONNECT:
// we are starting a new join process, let's clear the error notifications if any from any previous attempt
store.dispatch(clearNotifications());
break;
case CONFERENCE_SUBJECT_CHANGED:
return _conferenceSubjectChanged(store, next, action);

View File

@@ -172,7 +172,6 @@ export interface IConfig {
_screenshotHistoryRegionUrl?: number;
analytics?: {
amplitudeAPPKey?: string;
amplitudeIncludeUTM?: boolean;
blackListedEvents?: string[];
disabled?: boolean;
matomoEndpoint?: string;

View File

@@ -337,9 +337,12 @@ function occupant_joined(event)
if not room._data.av_can_unmute then
for _,mediaType in pairs({'audio', 'video'}) do
start_av_moderation(room, mediaType, occupant);
notify_occupants_enable(nil, true, room, occupant.nick, mediaType);
end
room._data.av_first_moderator_joined = true;
return;
end
end

View File

@@ -558,13 +558,14 @@ process_host_module(muc_domain_prefix..'.'..muc_domain_base, function(host_modul
:tag('no-main-participants', { xmlns = 'jitsi:visitors' }));
return true;
end
elseif is_live == false and room._data.participants then
-- This is non jaas room which is not live and has a list of participants
-- allowed to participate in the main room, but this participant is not one of them
elseif room._data.participants then
-- This is non jaas room which has a list of participants allowed to participate in the main room
-- but this occupant is not one of them and the room is either not live or has no participants joined
session.log('warn',
'Deny user join in the main not live meeting, not in the list of main participants');
session.send(st.error_reply(
stanza, 'cancel', 'not-allowed', 'Tried to join the main (not live) room')
stanza, 'cancel', 'not-allowed',
'Tried to join the main (not live or without main participants) room')
:tag('not-live-room', { xmlns = 'jitsi:visitors' }));
return true;
end
@@ -713,6 +714,13 @@ process_host_module(muc_domain_prefix..'.'..muc_domain_base, function(host_modul
host_module:context(host):hook("muc-config-form", function(event)
table.insert(event.form, visitorsEnabledField);
end);
if not room.jitsiMetadata then
room.jitsiMetadata = {};
end
room.jitsiMetadata.visitorsEnabled = true;
module:context(muc_domain_prefix..'.'..muc_domain_base)
:fire_event('room-metadata-changed', { room = room; });
end
end);