const twilio = require("twilio"); const { phone } = require("phone"); const { INSERT_MESSAGE } = require("../graphql-client/queries"); const client = twilio(process.env.TWILIO_AUTH_TOKEN, process.env.TWILIO_AUTH_KEY); const gqlClient = require("../graphql-client/graphql-client").client; /** * Send an outbound SMS message * @param req * @param res * @returns {Promise} */ const send = async (req, res) => { const { to, messagingServiceSid, body, conversationid, selectedMedia, imexshopid } = req.body; const { ioRedis, logger, ioHelpers: { getBodyshopRoom, getBodyshopConversationRoom } } = req; logger.log("sms-outbound", "DEBUG", req.user.email, null, { messagingServiceSid, to: phone(to).phoneNumber, mediaUrl: selectedMedia.map((i) => i.src), text: body, conversationid, isoutbound: true, userid: req.user.email, image: selectedMedia.length > 0, image_path: selectedMedia.length > 0 ? selectedMedia.map((i) => i.src) : [] }); if (!to || !messagingServiceSid || (!body && selectedMedia.length === 0) || !conversationid) { logger.log("sms-outbound-error", "ERROR", req.user.email, null, { type: "missing-parameters", messagingServiceSid, to: phone(to).phoneNumber, text: body, conversationid, isoutbound: true, userid: req.user.email, image: selectedMedia.length > 0, image_path: selectedMedia.length > 0 ? selectedMedia.map((i) => i.src) : [] }); res.status(400).json({ success: false, message: "Missing required parameter(s)." }); return; } try { const message = await client.messages.create({ body, messagingServiceSid, to: phone(to).phoneNumber, mediaUrl: selectedMedia.map((i) => i.src) }); const newMessage = { msid: message.sid, text: body, conversationid, isoutbound: true, userid: req.user.email, image: selectedMedia.length > 0, image_path: selectedMedia.length > 0 ? selectedMedia.map((i) => i.src) : [] }; try { const gqlResponse = await gqlClient.request(INSERT_MESSAGE, { msg: newMessage, conversationid }); logger.log("sms-outbound-success", "DEBUG", req.user.email, null, { msid: message.sid, conversationid }); const insertedMessage = gqlResponse.insert_messages.returning[0]; const broadcastRoom = getBodyshopRoom(insertedMessage.conversation.bodyshop.id); const conversationRoom = getBodyshopConversationRoom({ bodyshopId: insertedMessage.conversation.bodyshop.id, conversationId: insertedMessage.conversation.id }); ioRedis.to(broadcastRoom).emit("new-message-summary", { isoutbound: true, conversationId: conversationid, updated_at: insertedMessage.updated_at, msid: message.sid, summary: true }); ioRedis.to(conversationRoom).emit("new-message-detailed", { newMessage: insertedMessage, conversationId: conversationid, summary: false }); res.sendStatus(200); } catch (gqlError) { logger.log("sms-outbound-error", "ERROR", req.user.email, null, { msid: message.sid, conversationid, error: gqlError.message, stack: gqlError.stack }); res.status(500).json({ success: false, message: "Failed to insert message into database." }); } } catch (twilioError) { logger.log("sms-outbound-error", "ERROR", req.user.email, null, { conversationid, error: twilioError.message, stack: twilioError.stack }); res.status(500).json({ success: false, message: "Failed to send message through Twilio." }); } }; module.exports = { send };