From fad947d25eaa3e049fca75ffc7d3b1faa7b871cc Mon Sep 17 00:00:00 2001 From: Miroslav Pejic Date: Thu, 24 Oct 2024 22:37:09 +0200 Subject: [PATCH] [mirotalksfu] - add Discord bot, update dep --- README.md | 1 + app/src/Discord.js | 73 ++++++++++++++++++++++++++++++++++++++ app/src/Server.js | 13 +++++-- app/src/config.template.js | 22 ++++++++++++ package.json | 3 +- public/js/Room.js | 4 +-- public/js/RoomClient.js | 2 +- 7 files changed, 112 insertions(+), 6 deletions(-) create mode 100644 app/src/Discord.js diff --git a/README.md b/README.md index f2791293..faada0a3 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,7 @@ - Right-click options on video elements for additional controls. - Supports [REST API](app/api/README.md) (Application Programming Interface). - Integration with [Slack](https://api.slack.com/apps/) for enhanced communication. +- Integration with [Discord](https://discord.com) for enhanced communication. - Utilizes [Sentry](https://sentry.io/) for error reporting. - And much more... diff --git a/app/src/Discord.js b/app/src/Discord.js new file mode 100644 index 00000000..1665ff57 --- /dev/null +++ b/app/src/Discord.js @@ -0,0 +1,73 @@ +'use strict'; + +const { Client, GatewayIntentBits } = require('discord.js'); + +const Logger = require('./Logger'); + +const log = new Logger('Discord'); + +// Discord Bot Class Implementation +class Discord { + constructor(token, commands) { + this.token = token; + this.commands = commands; + this.discordClient = new Client({ + intents: [ + GatewayIntentBits.Guilds, + GatewayIntentBits.GuildMessages, + GatewayIntentBits.MessageContent, // Make sure this is enabled in your Discord Developer Portal + ], + }); + + this.setupEventHandlers(); + + this.discordClient.login(this.token).catch((error) => { + log.error('Failed to login to Discord:', error); + }); + } + + setupEventHandlers() { + this.discordClient.once('ready', () => { + log.info(`Discord Bot Logged in as ${this.discordClient.user.tag}!`, '😎'); + }); + + this.discordClient.on('error', (error) => { + log.error(`Discord Client Error: ${error.message}`, { stack: error.stack }); + }); + + this.discordClient.on('messageCreate', async (message) => { + if (message.author.bot) return; + + for (const command of this.commands) { + if (message.content.startsWith(command.name)) { + switch (command.name) { + case '/sfu': + const roomId = this.generateMeetingRoom(command.baseUrl); + await this.sendMessage(message.channel, `${command.message} ${roomId}`); + break; + //.... + default: + await this.sendMessage(message.channel, command.message); + break; + } + break; // Exit the loop after finding the command + } + } + }); + } + + generateMeetingRoom(baseUrl) { + const roomId = Math.random().toString(36).substring(2, 10); + return `${baseUrl}${roomId}`; + } + + async sendMessage(channel, content) { + try { + await channel.send(content); + } catch (error) { + log.error(`Failed to send message: ${error.message}`); + } + } +} + +module.exports = Discord; diff --git a/app/src/Server.js b/app/src/Server.js index d1d80614..fa3dbb5b 100644 --- a/app/src/Server.js +++ b/app/src/Server.js @@ -55,7 +55,7 @@ dev dependencies: { * @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon * @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970 * @author Miroslav Pejic - miroslav.pejic.85@gmail.com - * @version 1.5.99 + * @version 1.6.00 * */ @@ -86,6 +86,7 @@ const yaml = require('js-yaml'); const swaggerUi = require('swagger-ui-express'); const swaggerDocument = yaml.load(fs.readFileSync(path.join(__dirname, '/../api/swagger.yaml'), 'utf8')); const Sentry = require('@sentry/node'); +const Discord = require('./Discord.js'); const restrictAccessByIP = require('./middleware/IpWhitelist.js'); const packageJson = require('../../package.json'); @@ -180,6 +181,14 @@ if (sentryEnabled) { */ } +// Discord Bot +const { enabled, commands, token } = config.discord || {}; + +if (enabled && commands.length > 0 && token) { + const discordBot = new Discord(token, commands); + log.info('Discord bot is enabled and starting'); +} + // Stats const defaultStats = { enabled: true, @@ -2236,7 +2245,7 @@ function startServer() { // https://docs.heygen.com/reference/new-session socket.on('streamingNew', async ({ quality, avatar_id, voice_id }, cb) => { if (!roomExists(socket)) return; - + if (!config.videoAI.enabled || !config.videoAI.apiKey) return cb({ error: 'Video AI seems disabled, try later!' }); try { diff --git a/app/src/config.template.js b/app/src/config.template.js index 909df2d6..92980937 100644 --- a/app/src/config.template.js +++ b/app/src/config.template.js @@ -284,6 +284,28 @@ module.exports = { enabled: false, signingSecret: '', }, + discord: { + /* + Discord + 1. Go to the Discord Developer Portal: https://discord.com/developers/. + 2. Create a new application and name it whatever you like. + 3. Under the Bot section, click Add Bot and confirm. + 4. Copy your bot token (this will be used later). + 5. Under OAuth2 -> URL Generator, select bot scope, and under Bot Permissions, select the permissions you need (e.g., Send Messages and Read Messages). + 6. Copy the generated invite URL, open it in a browser, and invite the bot to your Discord server. + 7. Add the Bot in the Server channel permissions + 8. Type /sfu (commands.name) in the channel, the response will return a URL for the meeting + */ + enabled: false, + token: '', + commands: [ + { + name: '/sfu', + message: 'Here is your SFU meeting room:', + baseUrl: 'https://sfu.mirotalk.com/join/', + }, + ], + }, IPLookup: { /* GeoJS diff --git a/package.json b/package.json index 59964c10..4f25bac0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mirotalksfu", - "version": "1.5.99", + "version": "1.6.00", "description": "WebRTC SFU browser-based video calls", "main": "Server.js", "scripts": { @@ -64,6 +64,7 @@ "compression": "1.7.4", "cors": "2.8.5", "crypto-js": "4.2.0", + "discord.js": "^14.16.3", "dompurify": "^3.1.7", "express": "4.21.1", "express-openid-connect": "^2.17.1", diff --git a/public/js/Room.js b/public/js/Room.js index abcc617b..efe7c088 100644 --- a/public/js/Room.js +++ b/public/js/Room.js @@ -11,7 +11,7 @@ if (location.href.substr(0, 5) !== 'https') location.href = 'https' + location.h * @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon * @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970 * @author Miroslav Pejic - miroslav.pejic.85@gmail.com - * @version 1.5.99 + * @version 1.6.00 * */ @@ -4500,7 +4500,7 @@ function showAbout() { imageUrl: image.about, customClass: { image: 'img-about' }, position: 'center', - title: 'WebRTC SFU v1.5.99', + title: 'WebRTC SFU v1.6.00', html: `
diff --git a/public/js/RoomClient.js b/public/js/RoomClient.js index bb285ce3..ac66fda3 100644 --- a/public/js/RoomClient.js +++ b/public/js/RoomClient.js @@ -9,7 +9,7 @@ * @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon * @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970 * @author Miroslav Pejic - miroslav.pejic.85@gmail.com - * @version 1.5.99 + * @version 1.6.00 * */