+
+ {
+ res.status(500);
+ res.json({
+ success: false,
+ message: err
+ });
+ return;
+ });
+ if (!system) {
+ console.error("[contact_system] The Short Name does not exist: " + req.params.shortName.toLowerCase());
+ res.status(500);
+ res.json({
+ success: false,
+ message: "That Short Name does not exist."
+ });
+ return;
+ }
+ if (!system.allowContact) {
+ console.error("[contact_system] This System does not allow user to contact the owner: " + req.params.shortName.toLowerCase());
+ res.status(500);
+ res.json({
+ success: false,
+ message: "This System does not allow user to contact the owner."
+ });
+ return;
+ }
+ const user = await User.findById(system.userId).exec();
+ if (!user) {
+ console.error("[contact_system] System User does not exist: " + req.params.shortName.toLowerCase());
+ res.status(500);
+ res.json({
+ success: false,
+ message: "System User does not exist."
+ });
+ return;
+ }
+
+ console.log(user);
+ let message = "Thank you for contributing a feed to OpenMHz. A user has sent in a message about this feed:\n\n-------------------------------\n"
+ message = message + "User Name: " + req.body.name + "\n";
+ message = message + "User Email: " + req.body.email + "\n-------------------------------\n";
+ message = message + "Message:\n" + req.body.message + "\n-------------------------------\n\n";
+ message = message + "If you wish to stop receiving User Messages for this System:\n - goto the Admin for " + site_name + ": " + admin_server + "\n - find this System\n - Update it and turn off this Allow Contact option."
+ const request = mailjet.post("send", {
+ version: "v3.1"
+ }).request({
+ Messages: [{
+ From: {
+ Email: admin_email,
+ Name: site_name + " Admin"
+ },
+ To: [{
+ Email: user.email,
+ Name: user.firstName + " " + user.lastName
+ },{
+ Email: admin_email,
+ Name: site_name + " Admin"
+ }],
+ Subject: site_name + " - " + system.shortName + " - " + " User Comment",
+ TextPart: message
+ }]
+ });
+ request.then(result => {
+ console.log(`User Comment sent to: ${user.email} for shortName: ${system.shortName}`)
+ res.json({
+ success: true
+ });
+ })
+ .catch(err => {
+ console.error(err.statusCode);
+ console.error(err);
+ res.status(500);
+ res.json({
+ success: false,
+ message: err
+ });
+ return;
+ });
+
+
+}
exports.get_systems = async function (req, res) {
let fromDate = new Date(Date.now() - 60 * 60 * 24 * 30 * 1000);
const results = await System.find({lastActive: {$gte: fromDate}}).populate('userId', "screenName").catch( err => {
console.error("Error - get_systems: " + err.message);
+ res.status(500);
res.json({
success: false,
message: err
@@ -31,6 +127,7 @@ exports.get_systems = async function (req, res) {
lastActive: results[result].lastActive,
callAvg: results[result].callAvg,
description: results[result].description,
+ allowContact: results[result].allowContact,
clientCount: clientCount
}
if (results[result].showScreenName && results[result].userId) {
diff --git a/backend/index.js b/backend/index.js
index b167f77..5cd0877 100644
--- a/backend/index.js
+++ b/backend/index.js
@@ -116,6 +116,7 @@ app.post('/:shortName/upload', upload.single('call'), uploads.upload, async func
/*------ SYSTEMS ----------*/
app.get('/systems', addSystemClients, systems.get_systems);
+app.post('/:shortName/contact', systems.contact_system);
/*------ TALKGROUPS ----------*/
app.get('/:shortName/talkgroups', talkgroups.get_talkgroups);
@@ -249,6 +250,13 @@ io.sockets.on('connection', function (client) {
clients[client.id].filterType = String(data.filterType);
clients[client.id].talkgroupNums = [];
clients[client.id].timestamp = new Date();
+
+ if (typeof clients[client.id].filterCode != "string") {
+ console.error("Error - Socket - Invalid filterCode: " + data.filterCode + " ShortName: " + data.shortName.toLowerCase());
+ delete clients[client.id];
+ return;
+ }
+
if ((data.filterType == "group") && (data.filterCode.indexOf(',') == -1)) {
if (!ObjectId.isValid(data.filterCode)) {
console.error("Error - Socket - Invalid Group ID: " + data.filterCode);
diff --git a/backend/models/system.js b/backend/models/system.js
index 1ebaed4..a22127f 100644
--- a/backend/models/system.js
+++ b/backend/models/system.js
@@ -12,6 +12,10 @@ var systemSchema = mongoose.Schema({
state: String,
description: String,
showScreenName: Boolean,
+ allowContact: {
+ type: Boolean,
+ default: true
+ },
callAvg: Number,
callCount: Number,
ignoreUnknownTalkgroup : Boolean,
diff --git a/backend/package.json b/backend/package.json
index cb0ed81..580af82 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -22,6 +22,7 @@
"ffprobe-static": "3.1.0",
"find-remove": "4.1.0",
"get-folder-size": "^4.0.0",
+ "node-mailjet": "6.0.2",
"mkdirp": "^2.1.6",
"mongodb": "5.2.0",
"mongoose": "7.0.3",
diff --git a/docker-compose.yml b/docker-compose.yml
index e4d128a..157ee44 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -51,6 +51,10 @@ services:
pid: "host"
environment:
- MONGO_NODE_DRIVER_HOST=mongo
+ - MAILJET_KEY
+ - MAILJET_SECRET
+ - REACT_APP_ADMIN_EMAIL
+ - REACT_APP_SITE_NAME
- NODE_ENV
- REACT_APP_BACKEND_SERVER
- REACT_APP_ADMIN_SERVER
diff --git a/frontend/src/System/ContactModal.js b/frontend/src/System/ContactModal.js
new file mode 100644
index 0000000..c606a8e
--- /dev/null
+++ b/frontend/src/System/ContactModal.js
@@ -0,0 +1,97 @@
+import {useState} from 'react';
+import {
+ Modal,
+ Button,
+ Icon,
+ List,
+ Form,
+ Grid
+} from "semantic-ui-react";
+import { useContactSystemMutation } from '../features/api/apiSlice'
+
+function ContactModal(props) {
+
+ const [contactSystem, { isLoading }] = useContactSystemMutation()
+ const {system, onClose} = props;
+ const [email, setEmail] = useState(false);
+ const [name, setName] = useState(false);
+ const [error, setError] = useState(false);
+ const [message, setMessage] = useState(false);
+
+ const handleSubmit = async () => {
+ if ((!name || name.length < 3) || (!email || email.length < 3) || (!message || message.length < 3)) {
+ setError("Please fill out your Name, Email and a Message with something useful");
+ } else {
+
+ const body = {
+ name,
+ email,
+ message
+ }
+ try {
+ const shortName = system.shortName;
+ const returned = await contactSystem({body,shortName}).unwrap();
+ console.log(returned);
+ setName(false);
+ setEmail(false);
+ setMessage(false);
+ onClose();
+ } catch (submitError) {
+ console.error(error)
+ setError(submitError);
+ // you can handle errors here if you want to
+ }
+
+
+ }
+ }
+
+
+ return (
+
+ Contact Feed Contributer
+
+
+
+
+
+
The radio systems on OpenMHz are contributed by people from around the world.
Use this form to contact the contributer for the {system.name} system regarding:
+
+ Outages
+ Audio quality
+ Talkgroup updates
+ Thanks & appreciation
+
+
+
If you have general questions about OpenMHz send me an email,