• Added a new setting to update YouTube titles on start

• Reduced the number of calls to FetchBroadcast() to optimize API quota usage
This commit is contained in:
nuttylmao
2025-09-17 23:44:32 +10:00
parent f5c8481473
commit 9990755ccc
3 changed files with 105 additions and 5 deletions
+14 -1
View File
@@ -25,6 +25,8 @@
<div class="broadcast-info"> <div class="broadcast-info">
<label class="setting-attribute"> <label class="setting-attribute">
<i>YouTube stream info can only be updated while live</i> <i>YouTube stream info can only be updated while live</i>
<br>
<i><span id="youtube-title-on-broadcast-start-label"></span></i>
</label> </label>
</div> </div>
@@ -59,6 +61,17 @@
<input type="text" id="all-category-input" placeholder="Leave empty to keep current category"> <input type="text" id="all-category-input" placeholder="Leave empty to keep current category">
</div> </div>
<div id="include-youtube-setting-wrapper" class="setting">
<div>
<div class="setting-label">Include YouTube</div>
<div class="setting-description">Update YouTube title as soon as broadcast starts</div>
</div>
<label class="switch" style="margin-left: auto;">
<input type="checkbox" id="include-youtube-setting" name="include-youtube-setting" checked>
<span class="slider round"></span>
</label>
</div>
<button id="all-submit-button" onclick="UpdateAllSubmit()">Update All</button> <button id="all-submit-button" onclick="UpdateAllSubmit()">Update All</button>
</div> </div>
@@ -211,7 +224,7 @@
<div class="broadcast-info"> <div class="broadcast-info">
<label id="broadcast-title"></label> <label id="broadcast-title"></label>
<label id="broadcast-category" class="setting-description"></label> <label id="broadcast-category" class="setting-description"></label>
<label id="kick-warning" class="setting-attribute"><br><i>Stream info only available when live — Showing <label id="kick-warning" class="setting-attribute"><br><i>Most up to date stream info only available when live — Showing
last known stream title</i></label> last known stream title</i></label>
</div> </div>
+84 -4
View File
@@ -8,6 +8,7 @@ const sbActionOpenUrl = '14da1d44-6e29-4582-92c3-2c59388be57e';
let currentBroadcastId = ''; let currentBroadcastId = '';
let runningActionId = ''; let runningActionId = '';
let youtubeTitleOnBroadcastStart = '';
/////////////////// ///////////////////
@@ -21,6 +22,9 @@ const updateKickDialog = document.getElementById('update-kick-dialog');
const updateYouTubeDialog = document.getElementById('update-youtube-dialog'); const updateYouTubeDialog = document.getElementById('update-youtube-dialog');
const broadcastList = document.getElementById('broadcast-list'); const broadcastList = document.getElementById('broadcast-list');
const youtubeWarning = document.getElementById('youtube-warning'); const youtubeWarning = document.getElementById('youtube-warning');
const includeYouTubeSettingWrapper = document.getElementById('include-youtube-setting-wrapper');
const includeYouTubeSetting = document.getElementById('include-youtube-setting');
const youtubeTitleOnBroadcastStartLabel = document.getElementById('youtube-title-on-broadcast-start-label');
@@ -37,6 +41,21 @@ window.parent.sbClient.on('General.Custom', (response) => {
GeneralCustom(response.data); GeneralCustom(response.data);
}) })
window.parent.sbClient.on('YouTube.BroadcastStarted', (response) => {
console.debug(response.data);
YouTubeBroadcastStarted(response.data);
})
window.parent.sbClient.on('Twitch.StreamUpdate', (response) => {
console.debug(response.data);
FetchBroadcasts();
})
window.parent.sbClient.on('YouTube.BroadcastUpdated', (response) => {
console.debug(response.data);
FetchBroadcasts();
})
/////////////////////////////// ///////////////////////////////
@@ -64,9 +83,17 @@ async function GeneralCustom(data) {
// Only show the warning if there are 0 monitored broadcasts // Only show the warning if there are 0 monitored broadcasts
const ytBroadcastCount = data.broadcastList.filter(b => b.platform === "youtube").length; const ytBroadcastCount = data.broadcastList.filter(b => b.platform === "youtube").length;
if (ytBroadcastCount <= 0) if (ytBroadcastCount <= 0)
{
youtubeWarning.style.display = 'flex'; youtubeWarning.style.display = 'flex';
includeYouTubeSettingWrapper.style.display = 'flex';
includeYouTubeSetting.checked = true;
}
else else
{
youtubeWarning.style.display = 'none'; youtubeWarning.style.display = 'none';
includeYouTubeSettingWrapper.style.display = 'none';
includeYouTubeSetting.checked = false;
}
// Set the URL to the livestreaming dashboard // Set the URL to the livestreaming dashboard
const broadcastButton = youtubeWarning.querySelector('#broadcast-dashboard-button'); const broadcastButton = youtubeWarning.querySelector('#broadcast-dashboard-button');
@@ -83,7 +110,7 @@ async function GeneralCustom(data) {
const childDivs = broadcastList.querySelectorAll(":scope > div"); const childDivs = broadcastList.querySelectorAll(":scope > div");
childDivs.forEach(childDiv => { childDivs.forEach(childDiv => {
var result = data.broadcastList.find(obj => { var result = data.broadcastList.find(obj => {
return obj.id === childDiv.id return `id-${obj.id}` === childDiv.id;
}) })
if (result == null) if (result == null)
childDiv.remove(); childDiv.remove();
@@ -93,17 +120,58 @@ async function GeneralCustom(data) {
} }
} }
function YouTubeBroadcastStarted(data) {
if (!includeYouTubeSetting.checked)
return;
setTimeout(async () => {
await window.parent.sbClient.doAction(
action = {
id: sbActionUpdateStreamInfo
},
args = {
platform: 'youtube',
title: youtubeTitleOnBroadcastStart,
broadcastId: data.id
}
);
}, 1000);
}
async function FetchBroadcasts() { async function FetchBroadcasts() {
// Fetch from Streamer.bot // Fetch from Streamer.bot
const response = await window.parent.sbClient.doAction({ id: sbActionFetchBroadcasts}); const response = await window.parent.sbClient.doAction({ id: sbActionFetchBroadcasts});
runningActionId = response.args.runningActionId; runningActionId = response.args.runningActionId;
} }
async function FetchKickInfo() {
// Fetch from Streamer.bot
const broadcasterInfo = await window.parent.sbClient.getBroadcaster();
if (broadcasterInfo.platforms.kick) {
const userLogin = broadcasterInfo.platforms.kick.broadcasterLogin;
let kickData = {
platform: 'kick',
id: 'kick',
streamUrl: `https://www.kick.com/${userLogin}`,
dashboardUrl: 'https://dashboard.kick.com/stream',
userLogin: userLogin
}
AddBroadcast(kickData);
}
else {
const kickBroadcastDiv = document.getElementById('id-kick');
if (kickBroadcastDiv)
kickBroadcastDiv.remove();
}
}
async function AddBroadcast(data) { async function AddBroadcast(data) {
// Get a reference to the template // Get a reference to the template
const template = document.getElementById('broadcast-template'); const template = document.getElementById('broadcast-template');
const existingDiv = broadcastList.querySelector(`#${data.id}`); const existingDiv = broadcastList.querySelector(`#id-${data.id}`);
// Create a new instance of the template // Create a new instance of the template
let instance; let instance;
@@ -112,7 +180,7 @@ async function AddBroadcast(data) {
instance = existingDiv; instance = existingDiv;
else { else {
instance = template.content.firstElementChild.cloneNode(true); instance = template.content.firstElementChild.cloneNode(true);
instance.id = data.id; instance.id = `id-${data.id}`;
broadcastList.appendChild(instance); broadcastList.appendChild(instance);
} }
@@ -284,6 +352,18 @@ async function UpdateAllSubmit() {
} }
); );
// Set the YouTube title for next broadcast start
if (includeYouTubeSetting.checked)
{
youtubeTitleOnBroadcastStart = document.getElementById('all-title-input').value;
if (youtubeTitleOnBroadcastStart)
youtubeTitleOnBroadcastStartLabel.textContent = `Title will be set to '${youtubeTitleOnBroadcastStart}' when broadcast starts.`;
}
else {
youtubeTitleOnBroadcastStart = '';
youtubeTitleOnBroadcastStartLabel.textContent = '';
}
CloseUpdateAllDialog(); CloseUpdateAllDialog();
} }
@@ -543,4 +623,4 @@ ValidateYouTubeDialog();
// REFRESH BROADCAST LIST // // REFRESH BROADCAST LIST //
//////////////////////////// ////////////////////////////
setInterval(FetchBroadcasts, 5000); setInterval(FetchKickInfo, 5000);
@@ -69,6 +69,13 @@ button {
color: yellow; color: yellow;
} }
.setting {
display: flex;
flex-direction: row;
align-items: center;
gap: 0.5em;
}
#kick-warning { #kick-warning {
display: none; display: none;
} }