IO-3000 Adjusted first approach at messaging WS changes.
This commit is contained in:
@@ -11,7 +11,11 @@ const logger = require("../utils/logger");
|
||||
const InstanceManager = require("../utils/instanceMgr").default;
|
||||
|
||||
exports.receive = async (req, res) => {
|
||||
//Perform request validation
|
||||
// Perform request validation
|
||||
const {
|
||||
ioRedis,
|
||||
ioHelpers: { getBodyshopRoom, getBodyshopConversationRoom }
|
||||
} = req;
|
||||
|
||||
logger.log("sms-inbound", "DEBUG", "api", null, {
|
||||
msid: req.body.SmsMessageSid,
|
||||
@@ -20,7 +24,7 @@ exports.receive = async (req, res) => {
|
||||
image_path: generateMediaArray(req.body)
|
||||
});
|
||||
|
||||
if (!!!req.body || !!!req.body.MessagingServiceSid || !!!req.body.SmsMessageSid) {
|
||||
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,
|
||||
@@ -28,170 +32,195 @@ exports.receive = async (req, res) => {
|
||||
image_path: generateMediaArray(req.body),
|
||||
type: "malformed-request"
|
||||
});
|
||||
res.status(400);
|
||||
res.json({ success: false, error: "Malformed Request" });
|
||||
} else {
|
||||
try {
|
||||
const response = await client.request(queries.FIND_BODYSHOP_BY_MESSAGING_SERVICE_SID, {
|
||||
mssid: req.body.MessagingServiceSid,
|
||||
phone: phone(req.body.From).phoneNumber
|
||||
});
|
||||
res.status(400).json({ success: false, error: "Malformed Request" });
|
||||
return;
|
||||
}
|
||||
|
||||
let newMessage = {
|
||||
msid: req.body.SmsMessageSid,
|
||||
text: req.body.Body,
|
||||
image: !!req.body.MediaUrl0,
|
||||
image_path: generateMediaArray(req.body)
|
||||
};
|
||||
if (response.bodyshops[0]) {
|
||||
//Found a bodyshop - should always happen.
|
||||
if (response.bodyshops[0].conversations.length === 0) {
|
||||
//No conversation Found, create one.
|
||||
//console.log("[SMS Receive] No conversation found. Creating one.");
|
||||
newMessage.conversation = {
|
||||
data: {
|
||||
bodyshopid: response.bodyshops[0].id,
|
||||
phone_num: phone(req.body.From).phoneNumber
|
||||
}
|
||||
};
|
||||
} else if (response.bodyshops[0].conversations.length === 1) {
|
||||
//Just add it to the conversation
|
||||
//console.log("[SMS Receive] Conversation found. Added ID.");
|
||||
newMessage.conversationid = response.bodyshops[0].conversations[0].id;
|
||||
} else {
|
||||
//We should never get here.
|
||||
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"
|
||||
});
|
||||
}
|
||||
try {
|
||||
let insertresp;
|
||||
if (response.bodyshops[0].conversations[0]) {
|
||||
insertresp = await client.request(queries.INSERT_MESSAGE, {
|
||||
msg: newMessage,
|
||||
conversationid: response.bodyshops[0].conversations[0] && response.bodyshops[0].conversations[0].id
|
||||
});
|
||||
} else {
|
||||
insertresp = await client.request(queries.RECEIVE_MESSAGE, {
|
||||
msg: newMessage
|
||||
});
|
||||
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]) {
|
||||
if (response.bodyshops[0].conversations.length === 0) {
|
||||
// No conversation found, create one
|
||||
newMessage.conversation = {
|
||||
data: {
|
||||
bodyshopid: response.bodyshops[0].id,
|
||||
phone_num: phone(req.body.From).phoneNumber
|
||||
}
|
||||
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
|
||||
//imageUrl: "https://thinkimex.com/img/io-fcm.png", //TODO:AIO Resolve addresses for other instances
|
||||
},
|
||||
data
|
||||
try {
|
||||
// Insert new conversation and message
|
||||
const insertresp = await client.request(queries.RECEIVE_MESSAGE, { msg: newMessage });
|
||||
|
||||
// Safely access conversation and message
|
||||
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(r2.insert_messages.returning[0].conversation.bodyshop.id);
|
||||
const conversationRoom = getBodyshopConversationRoom({
|
||||
bodyshopId: message.conversation.bodyshop.id,
|
||||
conversationId: message.conversation.id
|
||||
});
|
||||
// Broadcast new message to the conversation room
|
||||
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,
|
||||
fcmresp
|
||||
createdConversation
|
||||
});
|
||||
|
||||
res.status(200).send("");
|
||||
} catch (e2) {
|
||||
return;
|
||||
} catch (e) {
|
||||
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,
|
||||
error: e2
|
||||
error: e
|
||||
});
|
||||
|
||||
res.sendStatus(500).json(e2);
|
||||
res.status(500).json(e);
|
||||
return;
|
||||
}
|
||||
} else if (response.bodyshops[0].conversations.length === 1) {
|
||||
// Add to the existing conversation
|
||||
// conversation UPDATED
|
||||
newMessage.conversationid = response.bodyshops[0].conversations[0].id;
|
||||
} else {
|
||||
// Duplicate phone error
|
||||
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 {
|
||||
// Insert message into an existing conversation
|
||||
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(r2.insert_messages.returning[0].conversation.bodyshop.id);
|
||||
const conversationRoom = getBodyshopConversationRoom({
|
||||
bodyshopId: message.conversation.bodyshop.id,
|
||||
conversationId: message.conversation.id
|
||||
});
|
||||
// Broadcast new message to the conversation room
|
||||
ioRedis.to(broadcastRoom).emit("new-message-summary", {
|
||||
isoutbound: false,
|
||||
existingConversation: true,
|
||||
conversationId: 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: conversationid,
|
||||
summary: false
|
||||
});
|
||||
|
||||
res.status(200).send("");
|
||||
} catch (e) {
|
||||
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,
|
||||
error: e
|
||||
});
|
||||
|
||||
res.status(500).json(e);
|
||||
}
|
||||
} catch (e1) {
|
||||
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,
|
||||
error: e1
|
||||
});
|
||||
res.sendStatus(500).json(e1);
|
||||
}
|
||||
} catch (e) {
|
||||
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,
|
||||
error: e
|
||||
});
|
||||
res.status(500).json(e);
|
||||
}
|
||||
};
|
||||
|
||||
// const sampleMessage: {
|
||||
// "ToCountry": "CA",
|
||||
// "ToState": "BC",
|
||||
// "SmsMessageSid": "SMad7bddaf3454c0904999d6018b1e8f49",
|
||||
// "NumMedia": "0",
|
||||
// "ToCity": "Vancouver",
|
||||
// "FromZip": "",
|
||||
// "SmsSid": "SMad7bddaf3454c0904999d6018b1e8f49",
|
||||
// "FromState": "BC",
|
||||
// "SmsStatus": "received",
|
||||
// "FromCity": "VANCOUVER",
|
||||
// "Body": "Hi",
|
||||
// "FromCountry": "CA",
|
||||
// "To": "+16043301606",
|
||||
// "MessagingServiceSid": "MG6e259e2add04ffa0d0aa355038670ee1",
|
||||
// "ToZip": "",
|
||||
// "NumSegments": "1",
|
||||
// "MessageSid": "SMad7bddaf3454c0904999d6018b1e8f49",
|
||||
// "AccountSid": "AC6c09d337d6b9c68ab6488c2052bd457c",
|
||||
// "From": "+16049992002",
|
||||
// "ApiVersion": "2010-04-01"
|
||||
// }
|
||||
// ] req.body {
|
||||
// [0] ToCountry: 'CA',
|
||||
// [0] MediaContentType0: 'image/jpeg',
|
||||
// [0] ToState: 'BC',
|
||||
// [0] SmsMessageSid: 'MM14fa2851ba26e0dc2b62073f8e7cdf27',
|
||||
// [0] NumMedia: '1',
|
||||
// [0] ToCity: 'Vancouver',
|
||||
// [0] FromZip: '',
|
||||
// [0] SmsSid: 'MM14fa2851ba26e0dc2b62073f8e7cdf27',
|
||||
// [0] FromState: 'BC',
|
||||
// [0] SmsStatus: 'received',
|
||||
// [0] FromCity: 'VANCOUVER',
|
||||
// [0] Body: '',
|
||||
// [0] FromCountry: 'CA',
|
||||
// [0] To: '+16043301606',
|
||||
// [0] MessagingServiceSid: 'MG6e259e2add04ffa0d0aa355038670ee1',
|
||||
// [0] ToZip: '',
|
||||
// [0] NumSegments: '1',
|
||||
// [0] MessageSid: 'MM14fa2851ba26e0dc2b62073f8e7cdf27',
|
||||
// [0] AccountSid: 'AC6c09d337d6b9c68ab6488c2052bd457c',
|
||||
// [0] From: '+16049992002',
|
||||
// [0] MediaUrl0: 'https://api.twilio.com/2010-04-01/Accounts/AC6c09d337d6b9c68ab6488c2052bd457c/Messages/MM14fa2851ba26e0dc2b62073f8e7cdf27/Media/MEf129dd37979852f395eb29ffb126e19e',
|
||||
// [0] ApiVersion: '2010-04-01'
|
||||
// [0] }
|
||||
|
||||
// [0] MediaContentType0: 'image/jpeg',
|
||||
// MediaContentType0: 'video/3gpp',
|
||||
|
||||
const generateMediaArray = (body) => {
|
||||
const { NumMedia } = body;
|
||||
if (parseInt(NumMedia) > 0) {
|
||||
//stuff
|
||||
const ret = [];
|
||||
for (var i = 0; i < parseInt(NumMedia); i++) {
|
||||
for (let i = 0; i < parseInt(NumMedia); i++) {
|
||||
ret.push(body[`MediaUrl${i}`]);
|
||||
}
|
||||
return ret;
|
||||
|
||||
@@ -9,11 +9,14 @@ const queries = require("../graphql-client/queries");
|
||||
const logger = require("../utils/logger");
|
||||
const client = twilio(process.env.TWILIO_AUTH_TOKEN, process.env.TWILIO_AUTH_KEY);
|
||||
const { admin } = require("../firebase/firebase-handler");
|
||||
|
||||
const gqlClient = require("../graphql-client/graphql-client").client;
|
||||
|
||||
exports.send = (req, res) => {
|
||||
const { to, messagingServiceSid, body, conversationid, selectedMedia, imexshopid } = req.body;
|
||||
const {
|
||||
ioRedis,
|
||||
ioHelpers: { getBodyshopRoom, getBodyshopConversationRoom }
|
||||
} = req;
|
||||
|
||||
logger.log("sms-outbound", "DEBUG", req.user.email, null, {
|
||||
messagingServiceSid: messagingServiceSid,
|
||||
@@ -59,18 +62,36 @@ exports.send = (req, res) => {
|
||||
conversationid: newMessage.conversationid || ""
|
||||
};
|
||||
|
||||
admin.messaging().send({
|
||||
topic: `${imexshopid}-messaging`,
|
||||
data
|
||||
// TODO Verify
|
||||
// const messageData = response.insert_messages.returning[0];
|
||||
|
||||
// Broadcast new message to conversation room
|
||||
const broadcastRoom = getBodyshopRoom(r2.insert_messages.returning[0].conversation.bodyshop.id);
|
||||
const conversationRoom = getBodyshopConversationRoom({
|
||||
bodyshopId: r2.insert_messages.returning[0].conversation.bodyshop.id,
|
||||
conversationId: r2.insert_messages.returning[0].conversation.id
|
||||
});
|
||||
|
||||
ioRedis.to(broadcastRoom).emit("new-message-summary", {
|
||||
isoutbound: true,
|
||||
conversationId: conversationid,
|
||||
updated_at: r2.insert_messages.returning[0].updated_at,
|
||||
msid: message.sid,
|
||||
summary: true
|
||||
});
|
||||
ioRedis.to(conversationRoom).emit("new-message-detailed", {
|
||||
newMessage: r2.insert_messages.returning[0],
|
||||
conversationId: conversationid,
|
||||
summary: false
|
||||
});
|
||||
res.sendStatus(200);
|
||||
})
|
||||
.catch((e2) => {
|
||||
logger.log("sms-outbound-error", "ERROR", req.user.email, null, {
|
||||
msid: message.sid,
|
||||
conversationid,
|
||||
error: e2
|
||||
error: e2.message,
|
||||
stack: e2.stack
|
||||
});
|
||||
|
||||
//res.json({ success: false, message: e2 });
|
||||
@@ -80,7 +101,8 @@ exports.send = (req, res) => {
|
||||
//res.json({ success: false, message: error });
|
||||
logger.log("sms-outbound-error", "ERROR", req.user.email, null, {
|
||||
conversationid,
|
||||
error: e1
|
||||
error: e1.message,
|
||||
stack: e1.stack
|
||||
});
|
||||
});
|
||||
} else {
|
||||
|
||||
@@ -11,6 +11,10 @@ const { admin } = require("../firebase/firebase-handler");
|
||||
|
||||
exports.status = (req, res) => {
|
||||
const { SmsSid, SmsStatus } = req.body;
|
||||
const {
|
||||
ioRedis,
|
||||
ioHelpers: { getBodyshopRoom, getBodyshopConversationRoom }
|
||||
} = req;
|
||||
client
|
||||
.request(queries.UPDATE_MESSAGE_STATUS, {
|
||||
msid: SmsSid,
|
||||
@@ -21,6 +25,17 @@ exports.status = (req, res) => {
|
||||
msid: SmsSid,
|
||||
fields: { status: SmsStatus }
|
||||
});
|
||||
// TODO Verify
|
||||
const message = response.update_messages.returning[0];
|
||||
|
||||
const conversationRoom = getBodyshopConversationRoom({
|
||||
bodyshopId: message.conversation.bodyshopid,
|
||||
conversationId: message.conversationid
|
||||
});
|
||||
|
||||
ioRedis.to(conversationRoom).emit("message-changed", {
|
||||
message
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.log("sms-status-update-error", "ERROR", "api", null, {
|
||||
@@ -34,18 +49,44 @@ exports.status = (req, res) => {
|
||||
|
||||
exports.markConversationRead = async (req, res) => {
|
||||
const { conversationid, imexshopid } = req.body;
|
||||
admin.messaging().send({
|
||||
topic: `${imexshopid}-messaging`,
|
||||
// notification: {
|
||||
// title: `ImEX Online Message - ${data.phone_num}`,
|
||||
// body: message.image_path ? `Image ${message.text}` : message.text,
|
||||
// imageUrl: "https://thinkimex.com/img/logo512.png",
|
||||
// },
|
||||
data: {
|
||||
type: "messaging-mark-conversation-read",
|
||||
conversationid: conversationid || ""
|
||||
}
|
||||
const {
|
||||
ioRedis,
|
||||
ioHelpers: { getBodyshopRoom, getBodyshopConversationRoom }
|
||||
} = req;
|
||||
|
||||
//Server side, mark the conversation as read
|
||||
|
||||
//TODO: Convert this to run on server side. Stolen from chat-conversation.container.jsx
|
||||
// const [markConversationRead] = useMutation(MARK_MESSAGES_AS_READ_BY_CONVERSATION, {
|
||||
// variables: { conversationId: selectedConversation },
|
||||
// refetchQueries: ["UNREAD_CONVERSATION_COUNT"],
|
||||
//
|
||||
// update(cache) {
|
||||
// cache.modify({
|
||||
// id: cache.identify({
|
||||
// __typename: "conversations",
|
||||
// id: selectedConversation
|
||||
// }),
|
||||
// fields: {
|
||||
// messages_aggregate(cached) {
|
||||
// return { aggregate: { count: 0 } };
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
|
||||
const broadcastRoom = getBodyshopRoom(r2.insert_messages.returning[0].conversation.bodyshop.id);
|
||||
|
||||
ioRedis.to(broadcastRoom).emit("conversation-changed", {
|
||||
//type: "conversation-marked-unread" //TODO: Flush out what this looks like.
|
||||
// isoutbound: true,
|
||||
// conversationId: conversationid,
|
||||
// updated_at: r2.insert_messages.returning[0].updated_at,
|
||||
// msid: message.sid,
|
||||
// summary: true
|
||||
});
|
||||
|
||||
res.send(200);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user