The Jitsi meetings and most settings are working well enough for IDAA members to use for now.

This commit is contained in:
Scott Idem
2025-12-04 15:37:04 -05:00
parent c1a440df6c
commit 484ea8c36c
2 changed files with 290 additions and 131 deletions

View File

@@ -3,145 +3,205 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>IDAA Novi Jitsi iframe Test Page</title>
<title>IDAA Novi Jitsi iframe Example Template Page</title>
</head>
<body>
<script>
let novi_customer_uid = '<%=Novi.User.CustomerUniqueId%>'; // NOTE: The Novi UUID for the current current user/customer
console.log(`Novi's Current User's ID: ${novi_customer_uid}`);
// var novi_current_user_role = '<%=Novi.User.xyz%>';
// console.log(`Novi's Current User's Role: ${novi_current_user_role}`);
<!-- START: Copy below this point -->
<!-- IMPORTANT: This <script> element and <p> element below are for using in an iframe in the IDAA Nov site. One Sky IT's Jitsi meeting iframe -->
let novi_api_root_url = 'https://www.idaa.org/api';
let novi_api_key_for_idaa = 'CmNdWgdPmgluBWjiTd8xsUCk5mio8F1O9DYAh0pVDcg=';
<!-- IDAA and Novi specific JavaScript to get current Novi user info and load Jitsi iframe -->
<script>
let novi_customer_uid = '<%=Novi.User.CustomerUniqueId%>'; // NOTE: The Novi UUID for the current current user/customer
console.log(`Novi's Current User's ID: ${novi_customer_uid}`);
let novi_current_user_obj = null;
let novi_current_user_email = null;
// var novi_current_user_role = '<%=Novi.User.xyz%>';
// console.log(`Novi's Current User's Role: ${novi_current_user_role}`);
let room_name = 'IDAA-Student-and-Resident-Meeting'; // 'IDAA-Student-and-Resident-Meeting' 'idaa-meeting'
let is_moderator = false;
let novi_api_root_url = 'https://www.idaa.org/api';
let novi_api_key_for_idaa = 'CmNdWgdPmgluBWjiTd8xsUCk5mio8F1O9DYAh0pVDcg=';
let idaa_osit_site_key = '8VTOJ0X5hvT6JdiTJsGEzQ'; // 'restricted-access'
// let idaa_ae_api_root_url = 'https://sk-idaa.oneskyit.com/idaa/jitsi_meet';
let idaa_ae_api_root_url =
'https://static.oneskyit.com/c/DgrZone/jitsi_iframe_api.html';
let idaa_ae_params = new URLSearchParams(document.location.search);
// let idaa_ae_slct_event_id = idaa_ae_params.get('event_id');
let novi_current_user_obj = null;
let novi_current_user_email = null;
let idaa_ae_iframe_height = null;
let room_name = 'IDAA-Example-Meeting'; // 'IDAA-Student-and-Resident-Meeting'; 'IDAA-Meeting';
let is_moderator = false;
var novi_api_headers = new Headers();
novi_api_headers.append('Authorization', `Basic ${novi_api_key_for_idaa}`);
// Disable Jitsi sound settings. Set to true DISABLES the sound.
let incoming_msg_sound = true;
let participant_joined_sound = false;
let participant_left_sound = false;
let reaction_sound = true;
let raise_hand_sound = true;
var requestOptions = {
method: 'GET',
headers: novi_api_headers,
redirect: 'follow'
};
let idaa_osit_site_key = '8VTOJ0X5hvT6JdiTJsGEzQ'; // 'restricted-access'
// let idaa_ae_api_root_url = 'https://sk-idaa.oneskyit.com/idaa/jitsi_meet';
let idaa_ae_api_root_url =
'https://static.oneskyit.com/c/DgrZone/jitsi_iframe_api_testing.html';
let idaa_ae_params = new URLSearchParams(document.location.search);
// let idaa_ae_slct_event_id = idaa_ae_params.get('event_id');
let novi_api_get_customer_endpoint = `${novi_api_root_url}/customers/${novi_customer_uid}`;
console.log(novi_api_get_customer_endpoint);
let idaa_ae_iframe_height = null;
fetch(novi_api_get_customer_endpoint, requestOptions)
// .then(response => response.text())
.then((response) => response.json())
.then((result) => {
novi_current_user_obj = result;
console.log(`Novi's Current User Obj:`, novi_current_user_obj);
// console.log(`Novi's Current User Obj (${novi_current_user_obj.Email}):`, novi_current_user_obj);
var novi_api_headers = new Headers();
novi_api_headers.append('Authorization', `Basic ${novi_api_key_for_idaa}`);
let full_name = novi_current_user_obj?.Name;
let first_name = novi_current_user_obj?.FirstName;
let last_initial = novi_current_user_obj?.LastName
? novi_current_user_obj.LastName.charAt(0).toUpperCase() + '.'
: '';
if (last_initial) {
full_name = `${first_name} ${last_initial}`;
}
console.log(`Novi's Current User's Full Name: ${full_name}`);
var requestOptions = {
method: 'GET',
headers: novi_api_headers,
redirect: 'follow'
};
let idaa_ae_iframe_element = document.getElementById(
'ae_idaa_jitsi_meeting_iframe'
);
let novi_api_get_customer_endpoint = `${novi_api_root_url}/customers/${novi_customer_uid}`;
console.log(novi_api_get_customer_endpoint);
idaa_ae_iframe_element.src = `${idaa_ae_api_root_url}?uuid=${novi_customer_uid}&email=${novi_current_user_obj.Email}&full_name=${full_name}&moderator=${is_moderator}&room=${room_name}&iframe=true&key=${idaa_osit_site_key}`;
fetch(novi_api_get_customer_endpoint, requestOptions)
// .then(response => response.text())
.then((response) => response.json())
.then((result) => {
novi_current_user_obj = result;
console.log(`Novi's Current User Obj:`, novi_current_user_obj);
// console.log(`Novi's Current User Obj (${novi_current_user_obj.Email}):`, novi_current_user_obj);
// url.searchParams.delete('event_id');
// history.pushState({}, '', url);
})
.catch((error) => console.log('error', error));
let full_name = novi_current_user_obj?.Name;
let first_name = novi_current_user_obj?.FirstName;
let last_initial = novi_current_user_obj?.LastName
? novi_current_user_obj.LastName.charAt(0).toUpperCase() + '.'
: '';
if (last_initial) {
full_name = `${first_name} ${last_initial}`;
}
console.log(`Novi's Current User's Full Name: ${full_name}`);
window.addEventListener('message', function (event) {
// console.log('Message received from the child:', event.data); // Message received from child
let idaa_ae_iframe_element = document.getElementById(
'ae_idaa_jitsi_meeting_iframe'
);
if (event.data) {
if (event.data.iframe_height) {
// console.log(`Got iframe height: ${event.data.iframe_height}`);
idaa_ae_iframe_height = event.data.iframe_height;
idaa_ae_iframe_element.src =
`${idaa_ae_api_root_url}?uuid=${novi_customer_uid}&email=${novi_current_user_obj.Email}&full_name=${full_name}&moderator=${is_moderator}&room=${room_name}&iframe=true&key=${idaa_osit_site_key}&incoming_msg_sound=${incoming_msg_sound}&participant_joined_sound=${participant_joined_sound}&participant_left_sound=${participant_left_sound}&reaction_sound=${reaction_sound}&raise_hand_sound=${raise_hand_sound}`
;
let idaa_ae_iframe_element = document.getElementById(
'ae_idaa_novi_meeting_iframe'
);
// url.searchParams.delete('event_id');
// history.pushState({}, '', url);
})
.catch((error) => console.log('error', error));
// idaa_ae_iframe_element.style.height = idaa_ae_iframe_height;
idaa_ae_iframe_element.style.height = `${idaa_ae_iframe_height + 50}px`;
}
window.addEventListener('message', function (event) {
// console.log('Message received from the child:', event.data); // Message received from child
if (event.data.scroll_to !== undefined) {
console.log(`Got scroll_to: ${event.data.scroll_to}`);
if (event.data) {
if (event.data.iframe_height) {
// console.log(`Got iframe height: ${event.data.iframe_height}`);
idaa_ae_iframe_height = event.data.iframe_height;
let idaa_ae_iframe_element = document.getElementById(
'ae_idaa_novi_meeting_iframe'
);
if (idaa_ae_iframe_element) {
console.log(`Scrolling to: ${event.data.scroll_to}`);
// window.scrollTo(0, 0); // This works for all current browsers
window.scrollTo({
top: 0,
left: 0,
behavior: 'smooth'
});
// idaa_ae_iframe_element.scrollTo({x: 0, y: 0}); // Scroll to top
// document.body.scrollTo({x: 0, y: 0}); // Scroll to top
// document.body.scrollTo({
// top: 0,
// behavior: 'smooth'
// });
// document.body.scrollTop = 0;
// idaa_ae_iframe_element?.scrollTo(0, 0)
// idaa_ae_iframe_element.scrollTo({
// top: 0,
// behavior: 'smooth'
// });
// idaa_ae_iframe_element.scrollTo({
// top: event.data.scroll_to,
// behavior: 'smooth'
// });
} else {
console.warn(
`Element with ID "ae_idaa_jitsi_meeting_iframe" not found.`
);
}
}
let idaa_ae_iframe_element = document.getElementById(
'ae_idaa_novi_meeting_iframe'
);
// idaa_ae_iframe_element.style.height = idaa_ae_iframe_height;
idaa_ae_iframe_element.style.height = `${idaa_ae_iframe_height + 50}px`;
}
if (event.data.scroll_to !== undefined) {
console.log(`Got scroll_to: ${event.data.scroll_to}`);
let idaa_ae_iframe_element = document.getElementById(
'ae_idaa_novi_meeting_iframe'
);
if (idaa_ae_iframe_element) {
console.log(`Scrolling to: ${event.data.scroll_to}`);
// window.scrollTo(0, 0); // This works for all current browsers
window.scrollTo({
top: 0,
left: 0,
behavior: 'smooth'
});
// idaa_ae_iframe_element.scrollTo({x: 0, y: 0}); // Scroll to top
// document.body.scrollTo({x: 0, y: 0}); // Scroll to top
// document.body.scrollTo({
// top: 0,
// behavior: 'smooth'
// });
// document.body.scrollTop = 0;
// idaa_ae_iframe_element?.scrollTo(0, 0)
// idaa_ae_iframe_element.scrollTo({
// top: 0,
// behavior: 'smooth'
// });
// idaa_ae_iframe_element.scrollTo({
// top: event.data.scroll_to,
// behavior: 'smooth'
// });
} else {
console.log(`No data in message? ${event}`);
console.warn(
`Element with ID "ae_idaa_jitsi_meeting_iframe" not found.`
);
}
});
</script>
}
} else {
console.log(`No data in message? ${event}`);
}
});
</script>
<!-- IDAA OSIT iframe container element for Novi - Jitsi Meeting iframe -->
<p>
<iframe
width="100%"
height="950"
id="ae_idaa_jitsi_meeting_iframe"
src=""
style="min-height: 750px; height: min-content; max-height: 2048px"
class="ae_idaa_iframe"
allow="camera; microphone; fullscreen; display-capture; autoplay; clipboard-write"
allowfullscreen
></iframe>
</p>
<!-- Enable or disable sounds -->
<div
class=""
style="margin-top: 1.5em; border-top: 2px dashed #ccc; padding: 1em; background-color: pink;"
>
<strong>Jitsi Sound Settings:</strong>
<label>
<input type="checkbox" id="incoming_msg_sound_checkbox" checked disabled />
Disable Incoming Message Sound
</label>
<label>
<input type="checkbox" id="participant_joined_sound_checkbox" disabled />
Disable Participant Joined Sound
</label>
<label>
<input type="checkbox" id="participant_left_sound_checkbox" disabled />
Disable Participant Left Sound
</label>
<label>
<input type="checkbox" id="reaction_sound_checkbox" checked disabled />
Disable Reaction Sound
</label>
<label>
<input type="checkbox" id="raise_hand_sound_checkbox" checked disabled />
Disable Raise Hand Sound
</label>
<button
id="reload_iframe_button"
style="background-color: orange;"
onclick="
let iframe_element = document.getElementById('ae_idaa_jitsi_meeting_iframe');
if (iframe_element) {
iframe_element.src = iframe_element.src;
}
">
Reload Iframe
</button>
</div>
<!-- STOP: Do not copy below this point -->
<!-- IDAA Aether Apps for Novi - Recovery Meetings (events) iframe -->
<p>
<iframe
width="100%"
height="950"
id="ae_idaa_jitsi_meeting_iframe"
src=""
style="min-height: 950px; height: min-content; max-height: 2048px"
class="ae_idaa_iframe"
allow="camera; microphone; fullscreen; display-capture; autoplay; clipboard-write"
allowfullscreen
></iframe>
</p>
</body>
</html>

View File

@@ -3,32 +3,72 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Jitsi Meetings iframe API for IDAA</title>
<title>OSIT Jitsi Meetings API Example Template Page</title>
</head>
<body>
<!-- <h1>New Jitsi Meetings for IDAA</h1> -->
<!-- IMPORTANT: This HTML page can be used in an iframe or directly as a page to host Jitsi meetings using the Jitsi Meet External API with JWT authentication. -->
<!-- <p>The URL parameters are passed from the Novi page that contains this as an iframe. This will automatically set the attendees name, email address, moderator status, and room name. The moderator status is based on the Novi UUID. This message will be hidden before going live.</p> -->
<div id="jitsi_meet_external_api_container" style="height: 750px; width: 100%"></div>
<script src="https://jitsi.dgrzone.com/external_api.js"></script>
<script lang="ts">
/* BEGIN: IDAA and Novi specific */
// Partial example of the URL params passed to this iframe from the Novi page:
// ?uuid=${novi_customer_uid}&email=${novi_current_user_obj.Email}&full_name=${full_name}&moderator=${is_moderator}&room=${room_name}&iframe=true&key=${idaa_osit_site_key}&incoming_msg_sound=${incoming_msg_sound}&participant_joined_sound=${participant_joined_sound}&participant_left_sound=${participant_left_sound}&reaction_sound=${reaction_sound}`
let novi_api_root_url = 'https://www.idaa.org/api';
// let novi_api_key_for_idaa = 'abc123';
let novi_api_key_for_idaa = 'CmNdWgdPmgluBWjiTd8xsUCk5mio8F1O9DYAh0pVDcg=';
// Get user info from URL parameters. Generated by the Novi page that contains this iframe.
let novi_url_params = new URLSearchParams(document.location.search);
let user_id = novi_url_params.get('uuid');
let user_full_name = novi_url_params.get('full_name');
let user_email = novi_url_params.get('email');
let user_moderator = novi_url_params.get('moderator');
// Jitsi Meet External API variables
let domain = 'jitsi.dgrzone.com';
let room_name = novi_url_params.get('room') ?? 'the-default-room';
let display_name = user_full_name ?? 'Not My Name';
let email = user_email ?? 'test+unknown@oneskyit.com';
// Replace spaces with plus symbol in email addresses
email = email.replace(/\s+/g, '+');
let is_moderator = user_moderator === 'true' || user_moderator === true ? true : false;
let novi_api_headers = new Headers();
novi_api_headers.append('Authorization', `Basic ${novi_api_key_for_idaa}`);
let requestOptions = {
method: 'GET',
headers: novi_api_headers,
redirect: 'follow'
};
let novi_customer_uid = novi_url_params.get('uuid');
let novi_api_get_customer_endpoint = `${novi_api_root_url}/customers/${novi_customer_uid}`;
console.log(novi_api_get_customer_endpoint);
fetch(novi_api_get_customer_endpoint, requestOptions)
.then((response) => response.json())
.then((result) => {
novi_current_user_obj = result;
// console.log(`Novi's Current User Obj:`, novi_current_user_obj);
console.log(`Novi's Current User Obj (${novi_current_user_obj.Email}):`, novi_current_user_obj);
let full_name = novi_current_user_obj?.Name;
let first_name = novi_current_user_obj?.FirstName;
let last_initial = novi_current_user_obj?.LastName
? novi_current_user_obj.LastName.charAt(0).toUpperCase() + '.'
: '';
if (last_initial) {
full_name = `${first_name} ${last_initial}`;
}
console.log(`Novi's Current User's Full Name: ${full_name}`);
let email = novi_current_user_obj?.Email;
console.log(`Novi's Current User's Email: ${email}`);
// We may need to remove or change a parameter passed here after using it.
// url.searchParams.delete('any_param_you_want_to_remove');
// history.pushState({}, '', url);
})
.catch((error) => console.log('error', error));
let novi_user_id = novi_url_params.get('uuid');
let novi_user_full_name = novi_url_params.get('full_name');
let novi_user_email = novi_url_params.get('email');
// I need to think of a better way to flag moderators if this is being used with Novi in an iframe.
// Temporarily hard coding moderators:
// 5724aad7-6d89-47e7-8943-966fd22911bd = Steven L. Klein - Stevenklein425@gmail.com
// 182d1db3-caa9-41bc-b04a-2facc6859aeb = Melissa Eve Valasky - melissav95@gmail.com
@@ -40,10 +80,39 @@
'182d1db3-caa9-41bc-b04a-2facc6859aeb'
];
if (novi_jitsi_mod_li.includes(user_id)) {
is_moderator = true;
let novi_user_moderator = novi_url_params.get('moderator');
let novi_is_moderator = false;
if (novi_jitsi_mod_li.includes(novi_user_id)) {
novi_is_moderator = true;
}
// Set variables for Jitsi Meet External API
let user_id = novi_user_id;
let user_full_name = novi_user_full_name;
let user_email = novi_user_email;
let user_moderator = novi_user_moderator;
let url_params = novi_url_params;
let is_moderator = novi_is_moderator
/* END: IDAA and Novi specific */
// These disabled sound options will be used in the disabledSounds array below.
let disabled_sounds = [
url_params.get('incoming_msg_sound') ? 'INCOMING_MSG_SOUND' : null,
url_params.get('participant_joined_sound') ? 'PARTICIPANT_JOINED_SOUND' : null,
url_params.get('participant_left_sound') ? 'PARTICIPANT_LEFT_SOUND' : null,
url_params.get('reaction_sound') ? 'REACTION_SOUND' : null,
url_params.get('raise_hand_sound') ? 'RAISE_HAND_SOUND' : null,
];
// Jitsi Meet External API variables
let domain = url_params.get('domain') ?? 'jitsi.dgrzone.com';
let room_name = url_params.get('room') ?? 'The-Default-Room';
let display_name = user_full_name ?? 'Not My Name';
let email = user_email ?? 'test+unknown@oneskyit.com';
// Replace spaces with plus symbol in email addresses
email = email.replace(/\s+/g, '+');
// let is_moderator = user_moderator === 'true' || user_moderator === true ? true : false;
// 1. Function to fetch the JWT from your backend
async function getJitsiJwt() {
const tokenEndpoint = 'https://api.oneskyit.com/api/jitsi_token';
@@ -155,6 +224,36 @@
startWithAudioMuted: true, // Mutes the local user upon joining
startWithVideoMuted: true, // Mutes the local user upon joining
enableLobby: is_moderator,
// OMG THESE disabledSounds ACTUALLY WORK!!!!
// Use the disableSounds array to disable per browser session instance. This should be configurable though. The JWT payload (above in getJitsiJwt()) does not seem to support it?
// Keep this disabledSounds list for reference:
// https://jitsi.github.io/handbook/docs/dev-guide/dev-guide-configuration/#disabledsounds
// disabledSounds: [
// 'ASKED_TO_UNMUTE_SOUND',
// 'E2EE_OFF_SOUND',
// 'E2EE_ON_SOUND',
// 'INCOMING_MSG_SOUND',
// 'KNOCKING_PARTICIPANT_SOUND',
// 'LIVE_STREAMING_OFF_SOUND',
// 'LIVE_STREAMING_ON_SOUND',
// 'NO_AUDIO_SIGNAL_SOUND',
// 'NOISY_AUDIO_INPUT_SOUND',
// 'OUTGOING_CALL_EXPIRED_SOUND',
// 'OUTGOING_CALL_REJECTED_SOUND',
// 'OUTGOING_CALL_RINGING_SOUND',
// 'OUTGOING_CALL_START_SOUND',
// 'PARTICIPANT_JOINED_SOUND',
// 'PARTICIPANT_LEFT_SOUND',
// 'RAISE_HAND_SOUND',
// 'REACTION_SOUND',
// 'RECORDING_OFF_SOUND',
// '_ON_SOUND',
// 'TALK_WHILE_MUTED_SOUND',
//],
disabledSounds: disabled_sounds.filter(sound => sound), // Remove any null/undefined entries
},
interfaceConfigOverwrite: {