Skip to content

Commit

Permalink
[mirotalksfu] - #170 add Mattermost integration, update dep
Browse files Browse the repository at this point in the history
  • Loading branch information
miroslavpejic85 committed Oct 25, 2024
1 parent ca93835 commit 8c5ace0
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 13 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
- 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.
- Integration with [Mattermost](https://mattermost.com/) for enhanced communication.
- Utilizes [Sentry](https://sentry.io/) for error reporting.
- And much more...

Expand Down
99 changes: 99 additions & 0 deletions app/src/Mattermost.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
'use strict';

const { Client4 } = require('@mattermost/client');

const { v4: uuidV4 } = require('uuid');

const config = require('./config');

const Logger = require('./Logger');

const log = new Logger('Mattermost');

class Mattermost {
constructor(app) {
const {
enabled,
token,
serverUrl,
username,
password,
commands = '/sfu',
texts = '/sfu',
} = config.mattermost || {};

if (!enabled) return; // Check if Mattermost integration is enabled

this.app = app;
this.allowed = config.api.allowed && config.api.allowed.mattermost;
this.token = token;
this.serverUrl = serverUrl;
this.username = username;
this.password = password;
this.commands = commands;
this.texts = texts;

this.client = new Client4();
this.client.setUrl(this.serverUrl);
this.authenticate();
this.setupEventHandlers();
}

async authenticate() {
try {
const user = await this.client.login(this.username, this.password);
log.debug('--------> Logged into Mattermost as', user.username);
} catch (error) {
log.error('Failed to log into Mattermost:', error);
}
}

setupEventHandlers() {
this.app.post('/mattermost', (req, res) => {
//
if (!this.allowed) {
return res
.status(403)
.send('This endpoint has been disabled. Please contact the administrator for further information.');
}

log.debug('Mattermost request received:', { header: req.header, body: req.body });

const { token, text, command, channel_id } = req.body;
if (token !== this.token) {
return res.status(403).send('Invalid token');
}

const payload = { text: '', channel_id };
if (this.processInput(command, payload, req) || this.processInput(text, payload, req)) {
return res.json(payload);
}

return res.status(200).send('Command not recognized');
});
}

processInput(input, payload, req) {
for (const cmd of [...this.commands, ...this.texts]) {
if (input.trim() === cmd.name) {
switch (cmd.name) {
case '/sfu':
payload.text = `${cmd.message} ${this.getMeetingURL(req)}`;
break;
default:
break;
}
return true;
}
}
return false;
}

getMeetingURL(req) {
const host = req.headers.host;
const protocol = host.includes('localhost') ? 'http' : 'https';
return `${protocol}://${host}/join/${uuidV4()}`;
}
}

module.exports = Mattermost;
17 changes: 10 additions & 7 deletions app/src/Server.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
███████ ███████ ██  ██   ████   ███████ ██  ██                                       
prod dependencies: {
@ffmpeg-installer/ffmpeg: https://www.npmjs.com/package/@ffmpeg-installer/ffmpeg
@mattermost/client : https://www.npmjs.com/package/@mattermost/client
@sentry/node : https://www.npmjs.com/package/@sentry/node
axios : https://www.npmjs.com/package/axios
body-parser : https://www.npmjs.com/package/body-parser
Expand Down Expand Up @@ -56,7 +56,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.6.00
* @version 1.6.10
*
*/

Expand Down Expand Up @@ -88,6 +88,7 @@ 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 Mattermost = require('./Mattermost.js');
const restrictAccessByIP = require('./middleware/IpWhitelist.js');
const packageJson = require('../../package.json');

Expand All @@ -110,7 +111,6 @@ const CryptoJS = require('crypto-js');
const qS = require('qs');
const slackEnabled = config.slack.enabled;
const slackSigningSecret = config.slack.signingSecret;
const bodyParser = require('body-parser');

const app = express();

Expand Down Expand Up @@ -328,12 +328,12 @@ function OIDCAuth(req, res, next) {

function startServer() {
// Start the app
app.use(express.static(dir.public));
app.use(cors(corsOptions));
app.use(compression());
app.use(express.json({ limit: '50mb' })); // Ensure the body parser can handle large files
app.use(express.static(dir.public));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.raw({ type: 'video/webm', limit: '50mb' })); // handle raw binary data
app.use(express.json({ limit: '50mb' })); // Handles JSON payloads
app.use(express.urlencoded({ extended: true, limit: '50mb' })); // Handles URL-encoded payloads
app.use(express.raw({ type: 'video/webm', limit: '50mb' })); // Handles raw binary data
app.use(restApi.basePath + '/docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument)); // api docs

// IP Whitelist check ...
Expand All @@ -352,6 +352,9 @@ function startServer() {
});
*/

// Mattermost
const mattermost = new Mattermost(app);

// POST start from here...
app.post('*', function (next) {
next();
Expand Down
34 changes: 34 additions & 0 deletions app/src/config.template.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ module.exports = {
join: true,
token: false,
slack: true,
mattermost: true,
//...
},
},
Expand Down Expand Up @@ -273,6 +274,39 @@ module.exports = {
DSN: '',
tracesSampleRate: 0.5,
},
mattermost: {
/*
Mattermost: https://mattermost.com
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.
*/
enabled: false,
serverUrl: 'YourMattermostServerUrl',
username: 'YourMattermostUsername',
password: 'YourMattermostPassword',
token: 'YourMattermostToken',
commands: [
{
name: '/sfu',
message: 'Here is your meeting room:',
},
//....
],
texts: [
{
name: '/sfu',
message: 'Here is your meeting room:',
},
//....
],
},
slack: {
/*
Slack
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mirotalksfu",
"version": "1.6.00",
"version": "1.6.10",
"description": "WebRTC SFU browser-based video calls",
"main": "Server.js",
"scripts": {
Expand Down Expand Up @@ -57,9 +57,9 @@
"node": ">=18"
},
"dependencies": {
"@mattermost/client": "^10.0.0",
"@sentry/node": "^8.35.0",
"axios": "^1.7.7",
"body-parser": "1.20.3",
"colors": "1.4.0",
"compression": "1.7.4",
"cors": "2.8.5",
Expand All @@ -80,7 +80,7 @@
"nodemailer": "^6.9.15",
"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"
},
Expand Down
4 changes: 2 additions & 2 deletions public/js/Room.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.6.00
* @version 1.6.10
*
*/

Expand Down Expand Up @@ -4500,7 +4500,7 @@ function showAbout() {
imageUrl: image.about,
customClass: { image: 'img-about' },
position: 'center',
title: 'WebRTC SFU v1.6.00',
title: 'WebRTC SFU v1.6.10',
html: `
<br />
<div id="about">
Expand Down
2 changes: 1 addition & 1 deletion public/js/RoomClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.6.00
* @version 1.6.10
*
*/

Expand Down

0 comments on commit 8c5ace0

Please sign in to comment.