From 6f172f9cdc29af8791ed1f18ecc029da24acff18 Mon Sep 17 00:00:00 2001 From: Kasmar Date: Thu, 28 Apr 2022 11:24:16 -0400 Subject: [PATCH 1/2] Add missing keys to readme --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index b1cc0fd..91b7c24 100644 --- a/README.md +++ b/README.md @@ -34,12 +34,16 @@ RDMDeviceMonitor is a simple discord bot to monitor device status for RDM. # SETTINGS ``` token: Mandator, discord bot token, bot should have send message and manage message permissions in the designated channel + channel: Default channel ID of where to post device/instance status deviceStatusChannel: Specific channel ID of where to post device status instanceStatusChannel: Specific channel ID of where to post instance status deviceSummaryChannel: Specific channel ID of where to post the device summary +deviceDetailedSummaryChannel: Specific channel ID of where to post the device detailed summary +questChannel: Specific channel ID of where to post the quest instance details userAlerts: an array of user IDs to DM upon device going offline + url: URL of your RDM website, by default IP:9000 but can use actual URL if you have a properly configured reverse proxy websiteLogin: Username to login with websitePassword: Password for the username @@ -49,6 +53,8 @@ The above user must have admin access to the website postIndividualDevices: true/false - Bool to post each device individually postInstanceStatus: true/false - Bool to post instance status postDeviceSummary: true/false - Bool to post device status in a single block by current status +postDeviceDetailedSummary: true/false - Bool to post device detailed status in a single block by current status +postQuestSummary: true/false - Bool to post quest instance status in a single block by current status showInstance: Show which instance a device is assigned to on the individual device post showAccount: Show account assigned on device post @@ -61,6 +67,8 @@ clearMessagesOnStartup: Will delete all messages in the channel it is going to p ignoredDevices: An array of strings for the overall device blacklist ignoredInstances: An array of strings for the instance blacklist +ignoredQuestInstances: An array of strings for the quest instance blacklist + postingDelay: The time in minutes to delay different posting triggers warningTime: The time in minutes to consider a device in warning state From 3ad5753c94943cdd6845eda892df4304973b1547 Mon Sep 17 00:00:00 2001 From: Kasmar Date: Sun, 15 May 2022 13:48:17 -0400 Subject: [PATCH 2/2] Support remote commands --- RDMMonitor.js | 74 +++++++++++++++++++++++++++++++---- RDMMonitorConfig.example.json | 3 ++ README.md | 4 ++ 3 files changed, 74 insertions(+), 7 deletions(-) diff --git a/RDMMonitor.js b/RDMMonitor.js index 14433d4..0788941 100644 --- a/RDMMonitor.js +++ b/RDMMonitor.js @@ -43,6 +43,7 @@ const WEBSITE_AUTH = { }, 'jar': true }; +const wait = async ms => new Promise(done => setTimeout(done, ms)); var postingDelay = config.postingDelay * 60000; var devices = {}; var instances = {}; @@ -113,11 +114,12 @@ bot.on('messageCreate', async message => { if(member.roles.cache.has(AdminR.id)) { if(command === "help") { message.delete(); - cmds = "`" + config.cmdPrefix + "restart` \\\u00BB to manually restart the whole bot.\n" + - "`" + config.cmdPrefix + "reopen ` \\\u00BB to reopen the game on specific devices.\n" + - "`" + config.cmdPrefix + "reboot ` \\\u00BB to reboot the specific devices.\n" + - "`" + config.cmdPrefix + "sam ` \\\u00BB to reapply the SAM profile to the specific devices\n" + - "`" + config.cmdPrefix + "brightness , ` \\\u00BB to change the brightness on the specific devices\n" + + var cmds = "`" + config.cmdPrefix + "restart` \\\u00BB to manually restart the whole bot.\n" + if(config.allowCMD) {cmds = cmds + "`" + config.cmdPrefix + "cmd ` \\\u00BB to execute a pre-defined command on the listening server.\n"} + if(config.allowReopenGame) {cmds = cmds + "`" + config.cmdPrefix + "reopen ` \\\u00BB to reopen the game on specific devices.\n"} + if(config.allowWarnReboots) {cmds = cmds + "`" + config.cmdPrefix + "reboot ` \\\u00BB to reboot the specific devices.\n"} + if(config.allowReapplySAM) {cmds = cmds + "`" + config.cmdPrefix + "sam ` \\\u00BB to reapply the SAM profile to the specific devices\n"} + cmds = cmds + "`" + config.cmdPrefix + "brightness , ` \\\u00BB to change the brightness on the specific devices\n" + "The commands with `` accept multiple names separated by commas.\n" + "They can be used to skip the exclusion list if you specify a name on the list.\n" + "They can accept `all`, `allwarn`, or `alloff` to apply to groups but will omit devices on the exclude lists." @@ -139,11 +141,17 @@ bot.on('messageCreate', async message => { } } + if(command === "cmd") { + CommandHandler(args) + return; + } + if(!args[0]) { message.delete(); message.reply("Please enter a device name after the command like `" + config.cmdPrefix + "reboot 001-SE`"); return; } + if(command === "brightness") { let temp = parseInt(args[0]); if (temp >= 0 && temp <= 100) { @@ -873,7 +881,7 @@ function ReopenWarnGame(manDevices) { console.info(GetTimestamp() + `Sending reopen game request for ${devices[reopenDevices[i]].name} to remote listener ${config.reopenMonitorURL[ii]}`); if (manDevices) { bot.channels.cache.get(config.channel).send(`Sending reopen game request for ${devices[reopenDevices[i]].name} to remote listener`); } request(options, (err, res, body) => { - if(err) { + if(err || body.status == 'error') { console.error(GetTimestamp() + `Failed to send reopen game request to remote listener for ${options.body.device}`); if (manDevices) { bot.channels.cache.get(config.channel).send(`Failed to send reopen game request to remote listener for ${options.body.device}`); } } @@ -941,7 +949,7 @@ function ReapplySAM(manDevices) { console.info(GetTimestamp() + `Sending a request to reapply the SAM profile for ${devices[reapplyDevices[i]].name} to remote listener ${config.reapplySAMMonitorURL[ii]}`); if (manDevices) { bot.channels.cache.get(config.channel).send(`Sending a request to reapply the SAM profile for ${devices[reapplyDevices[i]].name} to remote listener`); } request(options, (err, res, body) => { - if(err) { + if(err || body.status == 'error') { console.error(GetTimestamp() + `Failed to send request to reapply the SAM profile to remote listener for ${options.body.device}`); if (manDevices) { bot.channels.cache.get(config.channel).send(`Failed to send request to reapply the SAM profile to remote listener for ${options.body.device}`); } } @@ -1727,6 +1735,58 @@ function GetIVQueue(instanceName) { }); } +function CommandHandler(args) { + if(!config.allowCMD) { + return; + } + for(var ii = 0; ii < config.cmdMonitorURL.length; ii++) { + const options = { + url: config.cmdMonitorURL[ii], + json: true, + method: 'POST', + body: { + 'type': 'cmd', + 'cmdID': args[0] + }, + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + }; + console.info(GetTimestamp() + `Sending request to execute command \`${args[0]}\` to remote listener ${config.cmdMonitorURL[ii]}.`); + bot.channels.cache.get(config.channel).send(`Sending request to execute command ${args[0]} to remote listener ${config.cmdMonitorURL[ii]}.`); + request(options, async (err, res, body) => { + if(err) { + console.error(GetTimestamp() + `Failed to execute command \`${args[0]}\` on remote listener ${options.url}. Error: \n${err}`); + bot.channels.cache.get(config.channel).send(`Failed to execute command ${args[0]} on remote listener ${options.url}. Error: \n${err}`); + } + else if (body.status == 'error') { + console.error(GetTimestamp() + `Failed to execute command \`${args[0]}\` on remote listener ${body.node}. Error: \n${body.message}`); + bot.channels.cache.get(config.channel).send(`Failed to execute command ${args[0]} on remote listener ${body.node}. Error: \n${body.message}`); + } + else { + // Need to check that the character limit is maintained. + // Loop to create the message that is 2000 chars + // First has to include the starting text + // Send if the length is less than 2000 + console.info(GetTimestamp() + `Message from ${body.node} at ${options.url}.`); + bot.channels.cache.get(config.channel).send(`Message from ${body.node} at ${options.url}.`); + if (body.message.length <= 2000) { + console.info(GetTimestamp() + body.message); + bot.channels.cache.get(config.channel).send(body.message); + } + else { + var m_array = body.message.match(/(.|[\r\n]){1,2000}/g); + for (i = 0; i < m_array.length; i++) { + console.info(GetTimestamp() + m_array[i]); + bot.channels.cache.get(config.channel).send(m_array[i]); + await wait(4000); // Wait 4 seconds between messages to be under the rate limit + } + } + } + }); + } +} process.on('uncaughtException', function(err) { if(typeof err == 'object') { err = JSON.stringify(err); diff --git a/RDMMonitorConfig.example.json b/RDMMonitorConfig.example.json index 5bfb945..baed1b5 100644 --- a/RDMMonitorConfig.example.json +++ b/RDMMonitorConfig.example.json @@ -59,6 +59,9 @@ "excludeFromReboots": ["Device01","Device02"], "brightnessMonitorURL": ["http://192.168.0.1:6542","http://192.168.0.1:6543"], + + "allowCMD": false, + "cmdMonitorURL": ["http://192.168.0.1:6542","http://192.168.0.1:6543"], "cmdPrefix": ".", "adminRoleName": "ADMIN-ROLE-NAME" diff --git a/README.md b/README.md index 91b7c24..768791d 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,9 @@ excludeFromReboots: An array of strings that are the unique names of the devices brightnessMonitorURL: An array of strings for the URLs of the brightness monitors you are using like iPhone Controller or DCM Listener +allowCMD: true/false - Bool to enable RDMDeviceMonitor to send a request to execute a predefined command on the monitor server +cmdMonitorURL: An array of strings for the URLs of the monitors you want to send command requests to + cmdPrefix: A single character used to identify commands that the bot should react to adminRoleName: This is a string for the name of the main role that will admin the bot ``` @@ -118,6 +121,7 @@ Instead, add it to PM2 with `pm2 start ecosystem.config.js` --`.reboot ` » to reboot the specific devices
--`.sam ` » to reapply the SAM profile to the specific devices
--`.brightness , ` » to change the brightness on the specific devices
+--`.cmd ` » to execute a pre-defined command on the listening server
The commands with `` accept multiple names separated by commas.
They can be used to skip the exclusion list if you specify a name on the list.