betterttv, send translated message.

This commit is contained in:
Khyretos 2024-01-05 04:14:49 +01:00
parent 0efb495339
commit ccda0a7736
10 changed files with 265 additions and 41 deletions

1
.gitignore vendored
View file

@ -108,3 +108,4 @@ backend/*
backend/loquendoBot_backend.exe backend/loquendoBot_backend.exe
src/config/twitch-emotes.json src/config/twitch-emotes.json
dist/* dist/*
src/config/betterttv-emotes.json

View file

@ -236,11 +236,14 @@ def get_translation():
request_data = request.json request_data = request.json
message = request_data.get("message", "") message = request_data.get("message", "")
detectedLanguage = request_data.get("language", "") detectedLanguage = request_data.get("language", "")
translated = MyMemoryTranslator( try:
source=detectedLanguage, target=settings["LANGUAGE"]["TRANSLATE_TO"] translated = MyMemoryTranslator(
).translate(message) source=detectedLanguage, target=settings["LANGUAGE"]["TRANSLATE_TO"]
).translate(message)
except Exception as e:
return jsonify({"error": str(e), "code":429 }), 429
except Exception as e: except Exception as e:
return jsonify({"error": "Could not translate, continuing with next language"}), 500 return jsonify({"error": str(e), "code":500 }), 500
return jsonify({"translation": translated}), 200 return jsonify({"translation": translated}), 200

View file

@ -541,6 +541,10 @@ h1 {
margin: 20px 0px 0px 0px; margin: 20px 0px 0px 0px;
} }
.translation-message.user {
margin: -20px 0px 0px 0px;
}
.translation-icon { .translation-icon {
position: relative; position: relative;
padding: 0px 0px 0px 0px; padding: 0px 0px 0px 0px;
@ -558,3 +562,14 @@ h1 {
height: 20px !important; height: 20px !important;
left: 18px; left: 18px;
} }
.flag-icon.user {
left: -18px;
top: -15px;
}
.user-flag {
left: unset;
right: 18px;
top: -65px;
}

View file

@ -294,6 +294,16 @@
tip="All translated messages will be send to primary TTS voice but if message is detected in Secondary TTS language it will output it to the Secondary TTS voice" tip="All translated messages will be send to primary TTS voice but if message is detected in Secondary TTS language it will output it to the Secondary TTS voice"
></i> ></i>
</div> </div>
<div class="AdvancedMenuRow languageDetectionInput">
<div class="AdvancedMenuLabel">Send translated messages</div>
<input type="checkbox" id="SEND_TRANSLATION" class="checkbox" />
<label for="SEND_TRANSLATION" class="toggle-small" style="margin-right: 260px"></label>
<i
class="fa fa-question-circle fa-2x SmallButton option-icon-container"
id="Info_SEND_TRANSLATION"
tip="Enable sending translated messages to the chat."
></i>
</div>
</fieldset> </fieldset>
<fieldset id="NotificationMenu" class="AdvancedMenu"> <fieldset id="NotificationMenu" class="AdvancedMenu">
@ -371,6 +381,17 @@
tip="Test Twitch credentials" tip="Test Twitch credentials"
></i> ></i>
</div> </div>
<div class="AdvancedMenuRow inputTwitch">
<div class="AdvancedMenuLabel">Get BetterTTV emotes</div>
<button type="text" class="AdvancedMenuButton" id="GetBetterTtvEmotes">
<img src="https://cdn.betterttv.net/emote/5f1b0186cf6d2144653d2970/3x.webp" width="30px" height="30px" />
</button>
<i
class="fa fa-question-circle fa-2x SmallButton option-icon-container"
id="Info_BETTERTTV_EMOTES"
tip="Test Twitch credentials"
></i>
</div>
</fieldset> </fieldset>
<fieldset id="AdvancedMenuServer" class="AdvancedMenu"> <fieldset id="AdvancedMenuServer" class="AdvancedMenu">
@ -583,19 +604,19 @@
</button> </button>
<emoji-picker class="dark"></emoji-picker> <emoji-picker class="dark"></emoji-picker>
</div> </div>
<div class="pop in"> <div class="pop in send-translation">
<div class="miniText">In</div> <div class="miniText">In</div>
<button class="SmallButton"> <button class="SmallButton">
<i class="fa-solid fa-globe fa-2x" aria-hidden="true"></i> <i class="fa-solid fa-globe fa-2x" aria-hidden="true"></i>
</button> </button>
<div class="pop-content"></div> <div class="pop-content" id="SEND_TRANSLATION_IN"></div>
</div> </div>
<div class="pop out"> <div class="pop out send-translation">
<div class="miniText">Out</div> <div class="miniText">Out</div>
<button class="SmallButton"> <button class="SmallButton">
<i class="fa-solid fa-globe fa-2x" aria-hidden="true"></i> <i class="fa-solid fa-globe fa-2x" aria-hidden="true"></i>
</button> </button>
<div class="pop-content"></div> <div class="pop-content" id="SEND_TRANSLATION_OUT"></div>
</div> </div>
<!-- User text input--> <!-- User text input-->
<input id="textInput" class="input-box" type="text" name="msg" placeholder="Tap 'Enter' to send a message" /> <input id="textInput" class="input-box" type="text" name="msg" placeholder="Tap 'Enter' to send a message" />

View file

@ -44,10 +44,46 @@ async function getInstalledVoices() {
secondaryVoice.value = settings.TTS.SECONDARY_VOICE; secondaryVoice.value = settings.TTS.SECONDARY_VOICE;
} }
// TODO: refactor
function setTranslatedUserMessage(message) {
const userMessage = document.getElementById(message.messageId);
const messageBox = userMessage.getElementsByClassName('msg-box')[0];
const languageElement = document.createElement('span');
languageElement.classList = `fi fi-${message.language.selectedLanguage.ISO3166} fis flag-icon user-flag`;
languageElement.setAttribute('tip', message.language.selectedLanguage.name);
userMessage.appendChild(languageElement);
addSingleTooltip(languageElement);
const translationHeader = document.createElement('div');
translationHeader.className = 'translation-header user';
translationHeader.innerText = 'Translation';
messageBox.appendChild(translationHeader);
const languageElement2 = document.createElement('span');
languageElement2.classList = `fi fi-${message.language.detectedLanguage.ISO3166} fis flag-icon user`;
languageElement2.setAttribute('tip', message.language.detectedLanguage.name);
addSingleTooltip(languageElement2);
messageBox.appendChild(languageElement2);
const translationMessage = document.createElement('div');
translationMessage.className = 'translation-message user';
translationMessage.innerText = message.translation;
messageBox.appendChild(translationMessage);
}
function setTranslatedMessage(message) { function setTranslatedMessage(message) {
// this determines if it is a message that is send by a user
const languageBox = document.getElementById(message.messageId).getElementsByClassName('language-icon flag-icon')[0];
if (!languageBox) {
twitch.sendMessage(
`[${message.language.detectedLanguage.name} ${message.language.detectedLanguage.ISO639} > ${message.language.selectedLanguage.name} ${message.language.selectedLanguage.ISO639}] @${message.username}: ${message.translation}`
);
return setTranslatedUserMessage(message);
}
if (message.language.selectedLanguage.ISO639 !== message.language.detectedLanguage.ISO639) { if (message.language.selectedLanguage.ISO639 !== message.language.detectedLanguage.ISO639) {
const messageBox = document.getElementById(message.messageId).getElementsByClassName('msg-box')[0]; const messageBox = document.getElementById(message.messageId).getElementsByClassName('msg-box')[0];
const languageBox = document.getElementById(message.messageId).getElementsByClassName('language-icon flag-icon')[0];
languageBox.classList = `fi fi-${message.language.detectedLanguage.ISO3166} fis language-icon flag-icon`; languageBox.classList = `fi fi-${message.language.detectedLanguage.ISO3166} fis language-icon flag-icon`;
languageBox.setAttribute('tip', message.language.detectedLanguage.name); languageBox.setAttribute('tip', message.language.detectedLanguage.name);
@ -60,7 +96,6 @@ function setTranslatedMessage(message) {
const translationIcon = document.createElement('div'); const translationIcon = document.createElement('div');
translationIcon.className = 'translation-icon'; translationIcon.className = 'translation-icon';
const languageElement = document.createElement('span'); const languageElement = document.createElement('span');
const language = getLanguageProperties(settings.LANGUAGE.TRANSLATE_TO);
languageElement.classList = `fi fi-${message.language.selectedLanguage.ISO3166} fis flag-icon`; languageElement.classList = `fi fi-${message.language.selectedLanguage.ISO3166} fis flag-icon`;
languageElement.setAttribute('tip', message.language.selectedLanguage.name); languageElement.setAttribute('tip', message.language.selectedLanguage.name);
addSingleTooltip(languageElement); addSingleTooltip(languageElement);
@ -95,7 +130,6 @@ async function getTranslatedMessage(message) {
}, },
body: JSON.stringify({ body: JSON.stringify({
message: message.message, message: message.message,
remainder: message.remainingDetectedLanguages,
language: message.language.detectedLanguage.IETF language: message.language.detectedLanguage.IETF
}) // Convert the data to JSON and include it in the request body }) // Convert the data to JSON and include it in the request body
}; };
@ -111,7 +145,6 @@ async function getTranslatedMessage(message) {
`[${message.language.detectedLanguage.name} ${message.language.detectedLanguage.ISO639} > ${message.language.selectedLanguage.name} ${message.language.selectedLanguage.ISO639}] @${message.username}: ${responseData.translation}` `[${message.language.detectedLanguage.name} ${message.language.detectedLanguage.ISO639} > ${message.language.selectedLanguage.name} ${message.language.selectedLanguage.ISO639}] @${message.username}: ${responseData.translation}`
); );
} }
setTranslatedMessage({ setTranslatedMessage({
originalMessage: message.message, originalMessage: message.message,
translation: responseData.translation, translation: responseData.translation,
@ -124,21 +157,42 @@ async function getTranslatedMessage(message) {
return message.language.detectedLanguage; return message.language.detectedLanguage;
} else { } else {
console.error(responseData); console.error(responseData);
if (message.remainingDetectedLanguages.length > 0) { if (responseData.code === 500) {
message.language.detectedLanguage = getLanguageProperties(message.remainingDetectedLanguages[0]); if (message.remainingDetectedLanguages.length > 0) {
message.remainingDetectedLanguages.shift(); message.language.detectedLanguage = getLanguageProperties(message.remainingDetectedLanguages[0]);
return getTranslatedMessage(message); message.remainingDetectedLanguages.shift();
} else { return getTranslatedMessage(message);
message.message = 'Error, Could not translate message'; } else {
message.message = 'Error, Could not translate message';
message.language.detectedLanguage = getLanguageProperties('en-GB');
return getTranslatedMessage(message);
}
}
if (responseData.code === 429) {
message.language.detectedLanguage = getLanguageProperties('en-GB'); message.language.detectedLanguage = getLanguageProperties('en-GB');
return getTranslatedMessage(message); setTranslatedMessage({
originalMessage: message.message,
translation: 'Rate limit exceeded, please change translation service.',
messageId: message.messageId,
language: message.language,
formattedMessage: message.formattedMessage,
username: message.username,
logoUrl: message.logoUrl
});
} }
} }
} catch (error) { } catch (error) {
console.error('Error sending termination signal:', error); console.error('Error sending termination signal:', error);
message.message = 'Error, Could not translate message';
message.language.detectedLanguage = getLanguageProperties('en-GB'); message.language.detectedLanguage = getLanguageProperties('en-GB');
getTranslatedMessage(message); setTranslatedMessage({
originalMessage: message.message,
translation: 'Error, could not translate message.',
messageId: message.messageId,
language: message.language,
formattedMessage: message.formattedMessage,
username: message.username,
logoUrl: message.logoUrl
});
} }
} }
@ -363,4 +417,4 @@ ipcRenderer.on('quit-event', async () => {
} }
}); });
module.exports = { getInternalTTSAudio, getDetectedLanguage }; module.exports = { getInternalTTSAudio, getDetectedLanguage, getTranslatedMessage };

View file

@ -1,4 +1,4 @@
/* global messageTemplates, emojiPicker, settings, getPostTime, showChatMessage, twitch */ /* global messageTemplates,getLanguageProperties, backend, messageId emojiPicker, settings, getPostTime, showChatMessage, twitch */
async function getResponse() { async function getResponse() {
const userText = document.querySelector('#textInput').value; const userText = document.querySelector('#textInput').value;
@ -8,8 +8,11 @@ async function getResponse() {
return; return;
} }
messageId++;
// Create chat message from received data // Create chat message from received data
const article = document.createElement('article'); const article = document.createElement('article');
article.setAttribute('id', messageId);
article.className = 'msg-container user'; article.className = 'msg-container user';
article.innerHTML = messageTemplates.userTemplate; article.innerHTML = messageTemplates.userTemplate;
@ -29,9 +32,7 @@ async function getResponse() {
const msg = article.querySelector('.msg-box'); const msg = article.querySelector('.msg-box');
if (msg) { if (msg) {
console.log(0);
await replaceChatMessageWithCustomEmojis(userText).then(data => { await replaceChatMessageWithCustomEmojis(userText).then(data => {
// console.log(data);
msg.innerHTML = data; msg.innerHTML = data;
// Appends the message to the main chat box (shows the message) // Appends the message to the main chat box (shows the message)
@ -39,6 +40,23 @@ async function getResponse() {
twitch.sendMessage(userText); twitch.sendMessage(userText);
if (settings.LANGUAGE.SEND_TRANSLATION) {
const selectedLanguage = getLanguageProperties(settings.LANGUAGE.SEND_TRANSLATION_IN);
const detectedLanguage = getLanguageProperties(settings.LANGUAGE.SEND_TRANSLATION_OUT);
backend.getTranslatedMessage({
message: data,
messageId: messageId,
remainingDetectedLanguages: [],
language: {
selectedLanguage,
detectedLanguage
},
formattedMessage: data,
username: 'You',
logoUrl: settings.TWITCH.USER_LOGO_URL
});
}
// Empty input box after sending message // Empty input box after sending message
document.body.querySelector('#textInput').value = ''; document.body.querySelector('#textInput').value = '';
}); });
@ -167,3 +185,7 @@ displayPanelX('.item', '#btnChatCreator', '#btnChatCreator');
// #region Show/Hide Theme Creator // #region Show/Hide Theme Creator
// #endregion // #endregion
module.exports = {
replaceChatMessageWithCustomEmojis
};

View file

@ -23,8 +23,12 @@ const settings = main.settings;
const googleVoices = fs.readFileSync(path.join(__dirname, './config/googleVoices.txt')).toString().split('\r\n'); const googleVoices = fs.readFileSync(path.join(__dirname, './config/googleVoices.txt')).toString().split('\r\n');
// TODO: remove amazon voices txt and use api instead (sakura project has it) // TODO: remove amazon voices txt and use api instead (sakura project has it)
const amazonVoices = fs.readFileSync(path.join(__dirname, './config/amazonVoices.txt')).toString().split('\r\n'); const amazonVoices = fs.readFileSync(path.join(__dirname, './config/amazonVoices.txt')).toString().split('\r\n');
const emoteListSavePath = const twitchEmoteListSavePath =
main.isPackaged === true ? path.join(resourcesPath, './twitch-emotes.json') : path.join(resourcesPath, './config/twitch-emotes.json'); main.isPackaged === true ? path.join(resourcesPath, './twitch-emotes.json') : path.join(resourcesPath, './config/twitch-emotes.json');
const betterTtvEmoteListSavePath =
main.isPackaged === true
? path.join(resourcesPath, './betterttv-emotes.json')
: path.join(resourcesPath, './config/betterttv-emotes.json');
// html elements // html elements
const root = document.documentElement; const root = document.documentElement;
@ -178,8 +182,16 @@ function setLanguagesinSelectx(languageSelector, language) {
const languageSelectContent = languageSelect.querySelector('.pop-content'); const languageSelectContent = languageSelect.querySelector('.pop-content');
languageSelectContent.addEventListener('click', e => { languageSelectContent.addEventListener('click', e => {
console.log(e.target); const parent = e.target.parentElement.id;
language = getLanguageProperties(e.target.getAttribute('value')); language = getLanguageProperties(e.target.getAttribute('value'));
if (parent === 'SEND_TRANSLATION_IN') {
settings.LANGUAGE.SEND_TRANSLATION_IN = language.IETF;
} else {
settings.LANGUAGE.SEND_TRANSLATION_OUT = language.IETF;
}
fs.writeFileSync(settingsPath, ini.stringify(settings));
setSelectedLanguageinSelect(languageSelect, language); setSelectedLanguageinSelect(languageSelect, language);
}); });
@ -378,15 +390,22 @@ function setZoomLevel(currentZoom, zoomIn) {
document.body.querySelector('#ZOOMLEVEL').value = (settings.GENERAL.ZOOMLEVEL * 100).toFixed(0); document.body.querySelector('#ZOOMLEVEL').value = (settings.GENERAL.ZOOMLEVEL * 100).toFixed(0);
} }
if (fs.existsSync(emoteListSavePath)) { // TODO: refactor
fs.readFile(emoteListSavePath, 'utf8', (error, data) => { let twitchEmotes = null;
if (error) { if (fs.existsSync(twitchEmoteListSavePath)) {
console.log(error); const xxx = fs.readFileSync(twitchEmoteListSavePath);
return; twitchEmotes = JSON.parse(xxx);
} emojiPicker.customEmoji = [...twitchEmotes];
const emotes = JSON.parse(data); }
emojiPicker.customEmoji = emotes; let betterTtvEmotes = null;
}); if (fs.existsSync(betterTtvEmoteListSavePath)) {
const xxx = fs.readFileSync(betterTtvEmoteListSavePath);
betterTtvEmotes = JSON.parse(xxx);
emojiPicker.customEmoji = [...betterTtvEmotes];
}
if (twitchEmotes && betterTtvEmotes) {
emojiPicker.customEmoji = [...twitchEmotes, ...betterTtvEmotes];
} }
function getLanguageProperties(languageToDetect) { function getLanguageProperties(languageToDetect) {

View file

@ -16,6 +16,7 @@ function getGeneralSettings() {
// Language detection // Language detection
document.body.querySelector('#USE_DETECTION').checked = settings.LANGUAGE.USE_DETECTION; document.body.querySelector('#USE_DETECTION').checked = settings.LANGUAGE.USE_DETECTION;
document.body.querySelector('#OUTPUT_TO_TTS').checked = settings.LANGUAGE.OUTPUT_TO_TTS; document.body.querySelector('#OUTPUT_TO_TTS').checked = settings.LANGUAGE.OUTPUT_TO_TTS;
document.body.querySelector('#SEND_TRANSLATION').checked = settings.LANGUAGE.SEND_TRANSLATION;
document.body.querySelector('#BROADCAST_TRANSLATION').checked = settings.LANGUAGE.BROADCAST_TRANSLATION; document.body.querySelector('#BROADCAST_TRANSLATION').checked = settings.LANGUAGE.BROADCAST_TRANSLATION;
// TTS // TTS
@ -323,6 +324,11 @@ document.body.querySelector('#Info_USERNAME').addEventListener('click', async ()
createNotification('Saved OAuth token!', 'success'); createNotification('Saved OAuth token!', 'success');
}); });
document.body.querySelector('#GetBetterTtvEmotes').addEventListener('click', async () => {
twitch.getBetterTtvGLobalEmotes();
createNotification('Saved BetterTTV emotes!', 'success');
});
const hideInputToggleButton = document.body.querySelectorAll('.password-toggle-btn .password-toggle-icon .fa-eye-slash'); const hideInputToggleButton = document.body.querySelectorAll('.password-toggle-btn .password-toggle-icon .fa-eye-slash');
hideInputToggleButton.forEach(item => { hideInputToggleButton.forEach(item => {
item.addEventListener('click', () => { item.addEventListener('click', () => {
@ -518,6 +524,23 @@ document.body.querySelector('#USE_STT').addEventListener('change', () => {
createNotification(`${toggle ? 'Enabled' : 'Disabled'} speech to text!`, 'success'); createNotification(`${toggle ? 'Enabled' : 'Disabled'} speech to text!`, 'success');
}); });
function toggleSendTranslation() {
const toggle = settings.LANGUAGE.SEND_TRANSLATION;
const inputs = document.getElementsByClassName('send-translation');
toggleRadio(toggle, inputs);
}
toggleSendTranslation();
document.body.querySelector('#SEND_TRANSLATION').addEventListener('change', () => {
const toggle = document.getElementById('SEND_TRANSLATION').checked;
settings.LANGUAGE.SEND_TRANSLATION = toggle;
fs.writeFileSync(settingsPath, ini.stringify(settings));
const inputs = document.getElementsByClassName('send-translation');
toggleRadio(toggle, inputs);
createNotification(`${toggle ? 'Enabled' : 'Disabled'} Sending translations!`, 'success');
});
document.body.querySelector('#OUTPUT_TO_TTS').addEventListener('change', () => { document.body.querySelector('#OUTPUT_TO_TTS').addEventListener('change', () => {
let toggle = document.getElementById('OUTPUT_TO_TTS').checked; let toggle = document.getElementById('OUTPUT_TO_TTS').checked;
if (!settings.TTS.USE_TTS) { if (!settings.TTS.USE_TTS) {

View file

@ -1,4 +1,4 @@
/* global client, playNotificationSound, messageId, addSingleTooltip, settingsPath, fs, ini, backend, main, path, resourcesPath, customEmojis, emojiPicker,config, settings, options, sound, showChatMessage, messageTemplates, getPostTime */ /* global client, playNotificationSound, chat, replaceChatMessageWithCustomEmojis, messageId, addSingleTooltip, settingsPath, fs, ini, backend, main, path, resourcesPath, customEmojis, emojiPicker,config, settings, options, sound, showChatMessage, messageTemplates, getPostTime */
const tmi = require('tmi.js'); const tmi = require('tmi.js');
const axios = require('axios'); const axios = require('axios');
@ -134,11 +134,13 @@ async function displayTwitchMessage(logoUrl, username, messageObject, filteredMe
}); });
} }
showChatMessage(article); await chat.replaceChatMessageWithCustomEmojis(formattedMessage.innerHTML).then(data => {
formattedMessage.innerHTML = data;
showChatMessage(article);
});
if (settings.LANGUAGE.USE_DETECTION) { if (settings.LANGUAGE.USE_DETECTION) {
await backend.getDetectedLanguage({ message: filteredMessage, messageId, username, logoUrl, formattedMessage }).then(language => { await backend.getDetectedLanguage({ message: filteredMessage, messageId, username, logoUrl, formattedMessage }).then(language => {
console.log(language);
const languageElement = document.createElement('span'); const languageElement = document.createElement('span');
languageElement.classList = `fi fi-${language.ISO3166} fis language-icon flag-icon`; languageElement.classList = `fi fi-${language.ISO3166} fis language-icon flag-icon`;
languageElement.setAttribute('tip', language.name); languageElement.setAttribute('tip', language.name);
@ -250,6 +252,57 @@ function formatTwitchEmotes(channel) {
saveTwitchEmotesToFile(customEmojis); saveTwitchEmotesToFile(customEmojis);
} }
function saveBetterTtvEmotesToFile(BetterTtvEmotes) {
const data = JSON.stringify(BetterTtvEmotes);
const savePath =
main.isPackaged === true
? path.join(resourcesPath, './betterttv-emotes.json')
: path.join(resourcesPath, './config/betterttv-emotes.json');
fs.writeFile(savePath, data, error => {
if (error) {
console.error(error);
throw error;
}
});
}
function formatBetterTtvEmotes(data) {
if (data.emotes.length === 0) {
return;
}
data.emotes.forEach(emote => {
const emojiToBeAdded = {
name: emote.code,
shortcodes: [emote.code],
url: `https://cdn.betterttv.net/emote/${emote.id}/1x.webp`,
category: data.name
};
customEmojis.push(emojiToBeAdded);
});
emojiPicker.customEmoji = customEmojis;
saveBetterTtvEmotesToFile(customEmojis);
}
function getBetterTtvGLobalEmotes() {
// Get user Logo with access token
options = {
method: 'GET',
url: 'https://api.betterttv.net/3/cached/emotes/global',
headers: {}
};
axios
.request(options)
.then(response => {
formatBetterTtvEmotes({ name: 'BetterTTV Global', emotes: response.data });
})
.catch(error => {
console.error(error);
});
}
function getTwitchUserFollows(paginationToken) { function getTwitchUserFollows(paginationToken) {
let url = ''; let url = '';
if (!paginationToken) { if (!paginationToken) {
@ -449,4 +502,13 @@ function getTwitchUserId() {
// Reconnect 10s later // Reconnect 10s later
// setTimeout(ws.reconnect, 10e3); // setTimeout(ws.reconnect, 10e3);
module.exports = { sendMessage, ping, client, getUserAvailableTwitchEmotes, getTwitchChannelId, getTwitchUserId, checkIfTokenIsValid }; module.exports = {
sendMessage,
ping,
client,
getBetterTtvGLobalEmotes,
getUserAvailableTwitchEmotes,
getTwitchChannelId,
getTwitchUserId,
checkIfTokenIsValid
};

View file

@ -143,7 +143,11 @@ async function createIniFile() {
TRANSLATE_TO: 'none', TRANSLATE_TO: 'none',
LANGUAGE_INDEX: '0', LANGUAGE_INDEX: '0',
BROADCAST_TRANSLATION: false, BROADCAST_TRANSLATION: false,
OUTPUT_TO: false OUTPUT_TO_TTS: false,
TRANSLATE_TO_INDEX: 0,
SEND_TRANSLATION: true,
SEND_TRANSLATION_IN: 'none',
SEND_TRANSLATION_OUT: 'none'
}, },
TTS: { TTS: {
USE_TTS: false, USE_TTS: false,