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;