[mirotalksfu] - #170 add Mattermost integration, update dep
هذا الالتزام موجود في:
99
app/src/Mattermost.js
Normal file
99
app/src/Mattermost.js
Normal file
@@ -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;
|
||||
@@ -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
|
||||
@@ -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
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 ...
|
||||
@@ -352,6 +352,9 @@ function startServer() {
|
||||
});
|
||||
*/
|
||||
|
||||
// Mattermost
|
||||
const mattermost = new Mattermost(app);
|
||||
|
||||
// POST start from here...
|
||||
app.post('*', function (next) {
|
||||
next();
|
||||
|
||||
@@ -121,6 +121,7 @@ module.exports = {
|
||||
join: true,
|
||||
token: false,
|
||||
slack: true,
|
||||
mattermost: true,
|
||||
//...
|
||||
},
|
||||
},
|
||||
@@ -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
|
||||
|
||||
المرجع في مشكلة جديدة
حظر مستخدم