214 lines
6.8 KiB
JavaScript
214 lines
6.8 KiB
JavaScript
const path = require("path");
|
|
require("dotenv").config({
|
|
path: path.resolve(process.cwd(), `.env.${process.env.NODE_ENV || "development"}`)
|
|
});
|
|
|
|
const client = require("../graphql-client/graphql-client").client;
|
|
const queries = require("../graphql-client/queries");
|
|
const { phone } = require("phone");
|
|
const { admin } = require("../firebase/firebase-handler");
|
|
const logger = require("../utils/logger");
|
|
const InstanceManager = require("../utils/instanceMgr").default;
|
|
|
|
exports.receive = async (req, res) => {
|
|
const {
|
|
ioRedis,
|
|
ioHelpers: { getBodyshopRoom, getBodyshopConversationRoom }
|
|
} = req;
|
|
|
|
logger.log("sms-inbound", "DEBUG", "api", null, {
|
|
msid: req.body.SmsMessageSid,
|
|
text: req.body.Body,
|
|
image: !!req.body.MediaUrl0,
|
|
image_path: generateMediaArray(req.body)
|
|
});
|
|
|
|
if (!req.body || !req.body.MessagingServiceSid || !req.body.SmsMessageSid) {
|
|
logger.log("sms-inbound-error", "ERROR", "api", null, {
|
|
msid: req.body.SmsMessageSid,
|
|
text: req.body.Body,
|
|
image: !!req.body.MediaUrl0,
|
|
image_path: generateMediaArray(req.body),
|
|
type: "malformed-request"
|
|
});
|
|
res.status(400).json({ success: false, error: "Malformed Request" });
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const response = await client.request(queries.FIND_BODYSHOP_BY_MESSAGING_SERVICE_SID, {
|
|
mssid: req.body.MessagingServiceSid,
|
|
phone: phone(req.body.From).phoneNumber
|
|
});
|
|
|
|
let newMessage = {
|
|
msid: req.body.SmsMessageSid,
|
|
text: req.body.Body,
|
|
image: !!req.body.MediaUrl0,
|
|
image_path: generateMediaArray(req.body)
|
|
};
|
|
|
|
if (response.bodyshops[0]) {
|
|
const bodyshop = response.bodyshops[0];
|
|
if (bodyshop.conversations.length === 0) {
|
|
newMessage.conversation = {
|
|
data: {
|
|
bodyshopid: bodyshop.id,
|
|
phone_num: phone(req.body.From).phoneNumber,
|
|
archived: false
|
|
}
|
|
};
|
|
|
|
try {
|
|
const insertresp = await client.request(queries.RECEIVE_MESSAGE, { msg: newMessage });
|
|
const createdConversation = insertresp?.insert_messages?.returning?.[0]?.conversation || null;
|
|
const message = insertresp?.insert_messages?.returning?.[0];
|
|
|
|
if (!createdConversation) {
|
|
throw new Error("Conversation data is missing from the response.");
|
|
}
|
|
|
|
const broadcastRoom = getBodyshopRoom(createdConversation.bodyshop.id);
|
|
const conversationRoom = getBodyshopConversationRoom({
|
|
bodyshopId: message.conversation.bodyshop.id,
|
|
conversationId: message.conversation.id
|
|
});
|
|
|
|
ioRedis.to(broadcastRoom).emit("new-message-summary", {
|
|
isoutbound: false,
|
|
existingConversation: false,
|
|
newConversation: createdConversation,
|
|
conversationId: createdConversation.id,
|
|
updated_at: message.updated_at,
|
|
msid: message.sid,
|
|
summary: true
|
|
});
|
|
|
|
ioRedis.to(conversationRoom).emit("new-message-detailed", {
|
|
newMessage: message,
|
|
isoutbound: false,
|
|
newConversation: createdConversation,
|
|
existingConversation: false,
|
|
conversationId: createdConversation.id,
|
|
summary: false
|
|
});
|
|
|
|
logger.log("sms-inbound-success", "DEBUG", "api", null, {
|
|
newMessage,
|
|
createdConversation
|
|
});
|
|
|
|
res.status(200).send("");
|
|
return;
|
|
} catch (e) {
|
|
handleError(req, e, res, "RECEIVE_MESSAGE");
|
|
return;
|
|
}
|
|
} else if (bodyshop.conversations.length === 1) {
|
|
newMessage.conversationid = bodyshop.conversations[0].id;
|
|
} else {
|
|
logger.log("sms-inbound-error", "ERROR", "api", null, {
|
|
msid: req.body.SmsMessageSid,
|
|
text: req.body.Body,
|
|
image: !!req.body.MediaUrl0,
|
|
image_path: generateMediaArray(req.body),
|
|
messagingServiceSid: req.body.MessagingServiceSid,
|
|
type: "duplicate-phone"
|
|
});
|
|
res.status(400).json({ success: false, error: "Duplicate phone number" });
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const insertresp = await client.request(queries.INSERT_MESSAGE, {
|
|
msg: newMessage,
|
|
conversationid: newMessage.conversationid
|
|
});
|
|
|
|
const message = insertresp.insert_messages.returning[0];
|
|
const data = {
|
|
type: "messaging-inbound",
|
|
conversationid: message.conversationid || "",
|
|
text: message.text || "",
|
|
messageid: message.id || "",
|
|
phone_num: message.conversation.phone_num || ""
|
|
};
|
|
|
|
const fcmresp = await admin.messaging().send({
|
|
topic: `${message.conversation.bodyshop.imexshopid}-messaging`,
|
|
notification: {
|
|
title: InstanceManager({
|
|
imex: `ImEX Online Message - ${data.phone_num}`,
|
|
rome: `Rome Online Message - ${data.phone_num}`,
|
|
promanager: `ProManager Message - ${data.phone_num}`
|
|
}),
|
|
body: message.image_path ? `Image ${message.text}` : message.text
|
|
},
|
|
data
|
|
});
|
|
|
|
logger.log("sms-inbound-success", "DEBUG", "api", null, {
|
|
newMessage,
|
|
fcmresp
|
|
});
|
|
|
|
const broadcastRoom = getBodyshopRoom(message.conversation.bodyshop.id);
|
|
const conversationRoom = getBodyshopConversationRoom({
|
|
bodyshopId: message.conversation.bodyshop.id,
|
|
conversationId: message.conversation.id
|
|
});
|
|
|
|
ioRedis.to(broadcastRoom).emit("new-message-summary", {
|
|
isoutbound: false,
|
|
existingConversation: true,
|
|
conversationId: message.conversationid,
|
|
updated_at: message.updated_at,
|
|
msid: message.sid,
|
|
summary: true
|
|
});
|
|
|
|
ioRedis.to(conversationRoom).emit("new-message-detailed", {
|
|
newMessage: message,
|
|
isoutbound: false,
|
|
existingConversation: true,
|
|
conversationId: message.conversationid,
|
|
summary: false
|
|
});
|
|
|
|
res.status(200).send("");
|
|
} catch (e) {
|
|
handleError(req, e, res, "INSERT_MESSAGE");
|
|
}
|
|
}
|
|
} catch (e) {
|
|
handleError(req, e, res, "FIND_BODYSHOP_BY_MESSAGING_SERVICE_SID");
|
|
}
|
|
};
|
|
|
|
const generateMediaArray = (body) => {
|
|
const { NumMedia } = body;
|
|
if (parseInt(NumMedia) > 0) {
|
|
const ret = [];
|
|
for (let i = 0; i < parseInt(NumMedia); i++) {
|
|
ret.push(body[`MediaUrl${i}`]);
|
|
}
|
|
return ret;
|
|
} else {
|
|
return null;
|
|
}
|
|
};
|
|
|
|
const handleError = (req, error, res, context) => {
|
|
logger.log("sms-inbound-error", "ERROR", "api", null, {
|
|
msid: req.body.SmsMessageSid,
|
|
text: req.body.Body,
|
|
image: !!req.body.MediaUrl0,
|
|
image_path: generateMediaArray(req.body),
|
|
messagingServiceSid: req.body.MessagingServiceSid,
|
|
context,
|
|
error
|
|
});
|
|
|
|
res.status(500).json({ error: error.message || "Internal Server Error" });
|
|
};
|