From d37d24236ceac655f6a456259f809a6f7ab067ab Mon Sep 17 00:00:00 2001 From: Earnest Angel <57413115+earnestangel@users.noreply.github.com> Date: Wed, 31 Jan 2024 23:56:43 +0800 Subject: [PATCH] [FEAT] Dashboard + Fixes (#319) * Implement installer web interface, add privacy policy, terms and conditions * WIP: Copy and update config file with payloads sent from the installer. * [WIP] Dashboard * [WIP] Dashboard + Latest Changes * [FEAT] Dashboard + Fixes * 0.14.0 * [FEAT] Dashboard + Fixes --- index.js | 12 ++++ installer/assets/js/bd-wizard.js | 47 ++++++++------ installer/index.html | 2 + nodemon.json | 6 +- package-lock.json | 4 +- package.json | 6 +- .../Announcer/twitch-stream-notifier.js | 11 ++++ src/helpers/getconfig.js | 6 +- src/ririkoExpress.js | 11 +--- src/ririkoStreamChecker.js | 64 ++++++++++--------- 10 files changed, 105 insertions(+), 64 deletions(-) diff --git a/index.js b/index.js index b652b6b6..a1bba8be 100644 --- a/index.js +++ b/index.js @@ -17,6 +17,7 @@ function createLogDirectory() { } const { overrideLoggers } = require(`${buildDir}/helpers/logger`); +const { twitchClientId } = require("./src/helpers/getconfig"); overrideLoggers(); function handleUnhandledRejection(err, promise) { @@ -57,6 +58,17 @@ function startRirikoBotWorker() { } function startRirikoStreamCheckerWorker() { + if (twitchClientId()) { + console.log( + "Twitch Client ID found in environment variables. Starting stream checker." + ); + } else { + console.log( + "Twitch Client ID not found in environment variables. Not starting stream checker." + ); + return; + } + const worker_ririkoStreamChecker = new Worker( `./${buildDir}/ririkoStreamChecker` ); diff --git a/installer/assets/js/bd-wizard.js b/installer/assets/js/bd-wizard.js index d0a1d63a..1cb7cf99 100644 --- a/installer/assets/js/bd-wizard.js +++ b/installer/assets/js/bd-wizard.js @@ -75,25 +75,34 @@ form.children("#wizard").steps({ return form.valid(); }, onFinished: function (event, currentIndex) { - var formData = JSON.stringify($("#wizardForm").serializeArray()); // Serialize form data - - console.log("formData, ", formData); - - // Ajax request - $.ajax({ - type: "POST", - url: "submit_install", // Replace with your server-side script URL - data: formData, - contentType: "application/json", - success: function (response) { - // Handle success response - console.log(response); - }, - error: function (xhr, status, error) { - // Handle error response - console.log(error); - }, - }); + try { + var formData = JSON.stringify($("#wizardForm").serializeArray()); // Serialize form data + + console.log("formData, ", formData); + + // Ajax request + $.ajax({ + type: "POST", + url: "submit_install", // Replace with your server-side script URL + data: formData, + contentType: "application/json", + success: function (response) { + // Handle success response + console.log(response); + }, + error: function (xhr, status, error) { + // Handle error response + console.log(error); + }, + }); + alert( + "Installation complete! Please restart the bot and refresh the page." + ); + } catch (e) { + alert( + "An error occurred while submitting the form. Please try again, or contact the developer." + ); + } }, }); diff --git a/installer/index.html b/installer/index.html index 744ea97a..f66e1741 100644 --- a/installer/index.html +++ b/installer/index.html @@ -161,6 +161,8 @@

Configure AI Chatbot and Stable Diffusion

diff --git a/nodemon.json b/nodemon.json index 962209a7..d1159217 100644 --- a/nodemon.json +++ b/nodemon.json @@ -2,11 +2,13 @@ "watch": [ "index.js", "config.js", - "src/" + "src/", + "./config.js" ], "ignore": [ "*.test.js", "**/*.test.js" ], - "ext": "js, css" + "ext": "js, css", + "delay": 3500 } diff --git a/package-lock.json b/package-lock.json index 6a3473fb..20c28654 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ririko", - "version": "0.13.0", + "version": "0.14.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ririko", - "version": "0.13.0", + "version": "0.14.0", "license": "MIT", "dependencies": { "@discordjs/builders": "^1.6.3", diff --git a/package.json b/package.json index 3f02f4bc..e4549a0b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "name": "ririko", - "version": "0.13.0", + "version": "0.14.0", + "description": "Ririko - A powerful AI-powered general Discord bot that you can call your companion", "author": "Earnest Angel", "email": "me@angel.net.my", @@ -96,7 +97,8 @@ "save-dev": "^0.0.1-security", "semver": "^7.5.3", "source-map-support": "^0.5.21", - "sourcebin_js": "^0.0.3-ignore" + "sourcebin_js": "^0.0.3-ignore", + "body-parser": "^1.20.2" }, "devDependencies": { "@babel/cli": "^7.22.5", diff --git a/src/commands/prefix/Announcer/twitch-stream-notifier.js b/src/commands/prefix/Announcer/twitch-stream-notifier.js index 09bee498..cc786cb2 100644 --- a/src/commands/prefix/Announcer/twitch-stream-notifier.js +++ b/src/commands/prefix/Announcer/twitch-stream-notifier.js @@ -15,6 +15,7 @@ const { deleteSubscription, } = require("app/Schemas/StreamSubscribers"); const { addStreamersAndSubscribers } = require("app/RirikoTwitchManager"); +const { twitchClientId } = require("../../../helpers/getconfig"); module.exports = { config: { @@ -45,6 +46,16 @@ module.exports = { * @returns {Promise<*>} */ run: async (client, message, args, prefix, config, db) => { + if (!twitchClientId()) { + return message.reply({ + embeds: [ + new EmbedBuilder() + .setTitle("Missing Twitch Client ID") + .setDescription(`You need to add Twitch Client ID to the config`), + ], + }); + } + await updateGuildOwner(message.guild); let settings = await getSettings(message.guild.id); // console.log("settings", settings); diff --git a/src/helpers/getconfig.js b/src/helpers/getconfig.js index de3c9054..635fc579 100644 --- a/src/helpers/getconfig.js +++ b/src/helpers/getconfig.js @@ -1,4 +1,8 @@ -const config = require("config"); +let config; + +try { + config = require("../../config"); +} catch (e) {} /** * This section of code is proudly written by Ririko herself (up until a point) diff --git a/src/ririkoExpress.js b/src/ririkoExpress.js index 84205eaf..8633144d 100644 --- a/src/ririkoExpress.js +++ b/src/ririkoExpress.js @@ -174,8 +174,8 @@ async function writeConfigFile(payloads) { const twitchClientSecretRegex = stringRegex("TwitchClientSecret"); // Define the new values you want to set - const discordToken = getValueFromKey("application_id", payloads); - const discordBotID = getValueFromKey("bot_token", payloads); + const discordToken = getValueFromKey("bot_token", payloads); + const discordBotID = getValueFromKey("application_id", payloads); const replicateToken = getValueFromKey("replicate_token", payloads); const aiToken = getValueFromKey("ai_token", payloads); const accessURI = getValueFromKey("mongodb_uri", payloads); @@ -186,15 +186,8 @@ async function writeConfigFile(payloads) { console.log("discordTokenRegex", discordTokenRegex); - const portRegex = integerRegex("PORT"); - const languageRegex = stringRegex("LANGUAGE"); - const newPort = 8080; - const newLanguage = "fr"; - // Replace the values while preserving the data type and comments const modifiedContent = content - .replace(portRegex, `$1${newPort}`) - .replace(languageRegex, `$1${newLanguage}"`) .replace(discordTokenRegex, `$1${discordToken}"`) .replace(discordBotIDRegex, `$1${discordBotID}"`) .replace(replicateTokenRegex, `$1${replicateToken}"`) diff --git a/src/ririkoStreamChecker.js b/src/ririkoStreamChecker.js index ca549ffc..6883d06f 100644 --- a/src/ririkoStreamChecker.js +++ b/src/ririkoStreamChecker.js @@ -3,21 +3,21 @@ * @type {axios.AxiosStatic | axios | AxiosStatic | {all(values: Array | T>): Promise, AxiosInterceptorOptions: AxiosInterceptorOptions, AxiosResponse: AxiosResponse, Axios: Axios, ParamsSerializerOptions: ParamsSerializerOptions, ParamEncoder: ParamEncoder, AxiosDefaults: AxiosDefaults, AxiosInterceptorManager: AxiosInterceptorManager, ResponseType: "arraybuffer" | "blob" | "document" | "json" | "text" | "stream", AxiosBasicCredentials: AxiosBasicCredentials, AxiosProxyConfig: AxiosProxyConfig, RawAxiosRequestHeaders: RawAxiosRequestHeaders, Method: "get" | "GET" | "delete" | "DELETE" | "head" | "HEAD" | "options" | "OPTIONS" | "post" | "POST" | "put" | "PUT" | "patch" | "PATCH" | "purge" | "PURGE" | "link" | "LINK" | "unlink" | "UNLINK", FormDataVisitorHelpers: FormDataVisitorHelpers, AxiosRequestConfig: AxiosRequestConfig, SerializerVisitor: SerializerVisitor, AxiosAdapter: AxiosAdapter, CancelStatic: CancelStatic, AxiosStatic: AxiosStatic, AxiosRequestHeaders: RawAxiosRequestHeaders & AxiosHeaders, AxiosPromise: Promise>, InternalAxiosRequestConfig: InternalAxiosRequestConfig, GenericHTMLFormElement: GenericHTMLFormElement, CanceledError: CanceledError, RawAxiosRequestConfig: AxiosRequestConfig, HeadersDefaults: HeadersDefaults, GenericFormData: GenericFormData, AxiosHeaderValue: AxiosHeaders | string | string[] | number | boolean, CancelTokenStatic: CancelTokenStatic, Canceler: Canceler, FormSerializerOptions: FormSerializerOptions, spread(callback: (...args: T[]) => R): (array: T[]) => R, Cancel: Cancel, CancelTokenSource: CancelTokenSource, CancelToken: CancelToken, AxiosError: AxiosError, toFormData(sourceObj: object, targetFormData?: GenericFormData, options?: FormSerializerOptions): GenericFormData, AxiosProgressEvent: AxiosProgressEvent, responseEncoding: "ascii" | "ASCII" | "ansi" | "ANSI" | "binary" | "BINARY" | "base64" | "BASE64" | "base64url" | "BASE64URL" | "hex" | "HEX" | "latin1" | "LATIN1" | "ucs-2" | "UCS-2" | "ucs2" | "UCS2" | "utf-8" | "UTF-8" | "utf8" | "UTF8" | "utf16le" | "UTF16LE", isAxiosError(payload: any): payload is AxiosError, TransitionalOptions: TransitionalOptions, HttpStatusCode: HttpStatusCode, CustomParamsSerializer: CustomParamsSerializer, GenericAbortSignal: GenericAbortSignal, AxiosResponseHeaders: RawAxiosResponseHeaders & AxiosHeaders, CreateAxiosDefaults: CreateAxiosDefaults, formToJSON(form: (GenericFormData | GenericHTMLFormElement)): object, AxiosInstance: AxiosInstance, AxiosRequestTransformer: AxiosRequestTransformer, SerializerOptions: SerializerOptions, AxiosHeaders: AxiosHeaders, isCancel(value: any): value is Cancel, AxiosResponseTransformer: AxiosResponseTransformer, RawAxiosResponseHeaders: RawAxiosResponseHeaders, readonly default: AxiosStatic}} */ const axios = require("axios"); -const {getStreamers} = require("app/Schemas/Streamer"); +const { getStreamers } = require("app/Schemas/Streamer"); const { Subscriber, getSubscribersByUserId, getSubscribersByUserIdArray, } = require("app/Schemas/StreamSubscribers"); -const {overrideLoggers} = require("helpers/logger"); +const { overrideLoggers } = require("helpers/logger"); overrideLoggers(); -const {twitchClientId, twitchClientSecret} = require("helpers/getconfig"); -const {det} = require("mathjs"); -const {addQueueItems, deleteQueueItems} = require("./app/Schemas/QueueItem"); -const {getNotification} = require("./app/Schemas/StreamNotification"); -const {addStreamersAndSubscribers} = require("./app/RirikoTwitchManager"); -const {getAllSettings} = require("./app/Schemas/Guild"); -const {parentPort} = require("worker_threads"); +const { twitchClientId, twitchClientSecret } = require("helpers/getconfig"); +const { det } = require("mathjs"); +const { addQueueItems, deleteQueueItems } = require("./app/Schemas/QueueItem"); +const { getNotification } = require("./app/Schemas/StreamNotification"); +const { addStreamersAndSubscribers } = require("./app/RirikoTwitchManager"); +const { getAllSettings } = require("./app/Schemas/Guild"); +const { parentPort } = require("worker_threads"); const clientId = twitchClientId(); const clientSecret = twitchClientSecret(); @@ -61,27 +61,33 @@ async function run() { } async function twitchLogin() { - if (retries <= max_retries) { - // Get OAuth token - tokenResponse = await axios.post( - "https://id.twitch.tv/oauth2/token", - null, - { - params: { - client_id: clientId, - client_secret: clientSecret, - grant_type: "client_credentials", - }, + try { + if (retries <= max_retries) { + // Get OAuth token + tokenResponse = await axios.post( + "https://id.twitch.tv/oauth2/token", + null, + { + params: { + client_id: clientId, + client_secret: clientSecret, + grant_type: "client_credentials", + }, + } + ); + accessToken = tokenResponse.data.access_token; + retries++; + } else { + if (typeof parentPort !== "undefined") { + parentPort.postMessage({ + exit: true, + }); } - ); - accessToken = tokenResponse.data.access_token; - retries++; - } else { - if (typeof parentPort !== "undefined") { - parentPort.postMessage({ - exit: true - }); } + } catch (e) { + console.error( + "Something went wrong trying to login to Twitch: " + e.message + ); } } @@ -273,7 +279,7 @@ async function fetchStreamersInfo(streams) { const matchingItem = onlineStreamers.find((otherItem) => { return otherItem.user_id === item.user_id; }); - return {...item, ...matchingItem}; + return { ...item, ...matchingItem }; }); return onlineStreamers;