From bc89937ea0df530f1e1450aa6d78dd48f17211a9 Mon Sep 17 00:00:00 2001 From: Miroslav Pejic Date: Fri, 25 Oct 2024 22:36:15 +0200 Subject: [PATCH] [mirotalk] - #243 add mattermost integration --- .env.template | 19 +++++++++++- app/src/server.js | 72 +++++++++++++++++++++++++++++++++++++++++++-- package.json | 9 +++--- public/js/client.js | 4 +-- 4 files changed, 95 insertions(+), 9 deletions(-) diff --git a/.env.template b/.env.template index f059198e..16da516e 100644 --- a/.env.template +++ b/.env.template @@ -138,12 +138,29 @@ SENTRY_TRACES_SAMPLE_RATE=1.0 SLACK_ENABLED=false # true or false SLACK_SIGNING_SECRET=YourSlackSigningSecret +# Mettermost Integration (optional) +# 1. Navigate to Main Menu > Integrations > Slash Commands in Mattermost. +# 2. Click on **Add Slash Command** and configure the following settings: +# - Title: Enter a descriptive title (e.g., `P2P Command`). +# - Command Trigger Word**: Set the trigger word to `p2p`. +# - Callback URLs: Enter the URL for your Express server (e.g., `https://yourserver.com/mattermost`). +# - Request Method: Select POST. +# - Enable Autocomplete: Check the box for **Autocomplete**. +# - Autocomplete Description: Provide a brief description (e.g., `Get MiroTalk P2P meeting room`). +# 3. Save the slash command and copy the generated token here as MATTERMOST_TOKEN. + +MATTERMOST_ENABLED=false # true or false +MATTERMOST_SERVER_URL=YourMattermostServerUrl +MATTERMOST_USERNAME=YourMattermostUsername +MATTERMOST_PASSWORD=YourMattermostPassword +MATTERMOST_TOKEN=YourMettarmostToken + # ChatGPT/OpenAI # 1. Goto https://platform.openai.com/ # 2. Create your account # 3. Generate your APIKey https://platform.openai.com/account/api-keys -CHATGPT_ENABLED=false +CHATGPT_ENABLED=false # true or false CHATGPT_BASE_PATH=https://api.openai.com/v1/ CHATGPT_APIKEY=YourOpenAiApiKey CHATGPT_MODEL=gpt-3.5-turbo diff --git a/app/src/server.js b/app/src/server.js index 1229f769..eb1eefba 100755 --- a/app/src/server.js +++ b/app/src/server.js @@ -39,7 +39,7 @@ dependencies: { * @license For commercial use or closed source, contact us at license.mirotalk@gmail.com or purchase directly from CodeCanyon * @license CodeCanyon: https://codecanyon.net/item/mirotalk-p2p-webrtc-realtime-video-conferences/38376661 * @author Miroslav Pejic - miroslav.pejic.85@gmail.com - * @version 1.3.81 + * @version 1.3.82 * */ @@ -232,6 +232,30 @@ const slackEnabled = getEnvBoolean(process.env.SLACK_ENABLED); const slackSigningSecret = process.env.SLACK_SIGNING_SECRET; const bodyParser = require('body-parser'); +// Mattermost +const { Client4 } = require('@mattermost/client'); +const mattermostEnabled = getEnvBoolean(process.env.MATTERMOST_ENABLED); +const mattermostToken = process.env.MATTERMOST_TOKEN; +const mattermostServerUrl = process.env.MATTERMOST_SERVER_URL; +const mattermostUsername = process.env.MATTERMOST_USERNAME; +const mattermostPassword = process.env.MATTERMOST_PASSWORD; + +if (mattermostEnabled) { + const client = new Client4(); + + client.setUrl(mattermostServerUrl); + + async function authenticate() { + try { + const user = await client.login(mattermostUsername, mattermostPassword); + log.debug('-----------> Mattermost Logged in as:', user.username); + } catch (error) { + log.error('Mattermost client Failed to log in', error.message); + } + } + authenticate(); +} + // Setup sentry client if (sentryEnabled) { Sentry.init({ @@ -365,6 +389,7 @@ app.use(compression()); // Compress all HTTP responses using GZip app.use(express.json()); // Api parse body data as json app.use(express.static(dir.public)); // Use all static files from the public folder app.use(bodyParser.urlencoded({ extended: true })); // Need for Slack API body parser +app.use(bodyParser.json()); app.use(apiBasePath + '/docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument)); // api docs // Restrict access to specified IP @@ -787,7 +812,7 @@ app.post([`${apiBasePath}/join`], (req, res) => { https://api.slack.com/authentication/verifying-requests-from-slack */ -//Slack request meeting room endpoint +// Slack request meeting room endpoint app.post('/slack', (req, res) => { if (!slackEnabled) return res.end('`Under maintenance` - Please check back soon.'); @@ -823,6 +848,49 @@ app.post('/slack', (req, res) => { return res.end('`Wrong signature` - Verification failed!'); }); +/* + MiroTalk Mattermost app v1 + https://api.slack.com/authentication/verifying-requests-from-slack +*/ + +// Mattermost request meeting room endpoint +app.post('/mattermost', (req, res) => { + // + if (!mattermostEnabled) { + return res.end('`Under maintenance` - Please check back soon.'); + } + + // Check if endpoint allowed + if (api_disabled.includes('mattermost')) { + return res.end('`This endpoint has been disabled`. Please contact the administrator for further information.'); + } + + log.debug('Mattermost', req.body); + + const { token, text, command, channel_id } = req.body; + + // Validate the token + if (token !== mattermostToken) { + return res.status(403).send('Invalid token'); + } + + // Check if the command (slash-commands) or text (outgoing-webhook) matches "/p2p" + if (command.trim() === '/p2p' || text.trim() === '/p2p') { + // Generate or retrieve your meeting URL + const host = req.headers.host; + const meetingUrl = getMeetingURL(host); + + // Send the response back to Mattermost + return res.json({ + text: `Here is your meeting room: ${meetingUrl}`, + channel_id: channel_id, + }); + } + + // If the command is not recognized + return res.status(200).send('Command not recognized'); +}); + /** * Request meeting room endpoint * @returns entrypoint / Room URL for your meeting. diff --git a/package.json b/package.json index 3d96f4a2..3cdcd45f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mirotalk", - "version": "1.3.81", + "version": "1.3.82", "description": "A free WebRTC browser-based video call", "main": "server.js", "scripts": { @@ -41,7 +41,8 @@ "license": "AGPL-3.0", "homepage": "https://github.com/miroslavpejic85/mirotalk", "dependencies": { - "@sentry/node": "^8.34.0", + "@mattermost/client": "^10.0.0", + "@sentry/node": "^8.35.0", "axios": "^1.7.7", "body-parser": "^1.20.3", "colors": "^1.4.0", @@ -55,9 +56,9 @@ "js-yaml": "^4.1.0", "ngrok": "^5.0.0-beta.2", "nodemailer": "^6.9.15", - "openai": "^4.68.1", + "openai": "^4.68.4", "qs": "^6.13.0", - "socket.io": "^4.8.0", + "socket.io": "^4.8.1", "swagger-ui-express": "^5.0.1", "uuid": "10.0.0", "xss": "^1.0.15" diff --git a/public/js/client.js b/public/js/client.js index b48314ca..df8d15a6 100644 --- a/public/js/client.js +++ b/public/js/client.js @@ -15,7 +15,7 @@ * @license For commercial use or closed source, contact us at license.mirotalk@gmail.com or purchase directly from CodeCanyon * @license CodeCanyon: https://codecanyon.net/item/mirotalk-p2p-webrtc-realtime-video-conferences/38376661 * @author Miroslav Pejic - miroslav.pejic.85@gmail.com - * @version 1.3.81 + * @version 1.3.82 * */ @@ -10569,7 +10569,7 @@ function showAbout() { Swal.fire({ background: swBg, position: 'center', - title: 'WebRTC P2P v1.3.81', + title: 'WebRTC P2P v1.3.82', imageAlt: 'mirotalk-about', imageUrl: images.about, customClass: { image: 'img-about' },