import { uploadFiles } from '../../../api/utils/storage' import * as SendbirdController from '../../controllers/sendbird' import * as UserController from '../../controllers/user' import { prismaClient as prisma } from '../../prismaClient' import GeneralUtils from '../general' import { logger } from '../logger' export const handleInboundParse = async (req, res) => { const { subject, text, envelope, attachments } = req.body try { const { from } = JSON.parse(envelope) let attachmentsUploaded = null if (parseInt(attachments) > 0) { try { const files = [] // Sendgrid send files like that: attachment1: {}, attachment2: {}, ... for (let index = 1; index <= parseInt(attachments); index++) { files.push(req.files[`attachment${index}`]) } attachmentsUploaded = await uploadFiles(files) } catch (error) { logger.error(error) } } // Find the user associated with the email const user = await UserController.querySingleUser({ email: from, }) // Someone might have forwared the email to someone that is not registered on Walter if (!user) { return } // Get fields for later const userWithData = await prisma.user.findOne({ where: { id: user.id }, include: { currentProject: true, projects: true, property: true, properties: true }, }) let projectAssociatedWithEmail = null const PROJECT_FRAGMENT = { id: true, name: true, building: { select: { id: true, properties: { select: { id: true, }, }, }, }, } const emailProjectName = subject .replace(/Re: /g, '') .replace(/RE: /g, '') .replace(/re: /g, '') .split('-')[0] .trim() // First try with only the name in subject projectAssociatedWithEmail = ( await prisma.project.findMany({ where: { name: { contains: emailProjectName, }, }, select: PROJECT_FRAGMENT, }) )[0] if (!projectAssociatedWithEmail) { projectAssociatedWithEmail = ( await prisma.project.findMany({ where: { id: { in: userWithData.currentProject ? [userWithData.currentProject.id] : userWithData.projects.map((p) => p.id), }, }, select: PROJECT_FRAGMENT, }) )[0] } if (!projectAssociatedWithEmail) { throw new Error(`Handle inbound parse. No project found for user ${userWithData.id}`) } const userProperties = GeneralUtils.uniq( [userWithData.property, ...userWithData.properties], 'id' ) const userPropertiesForProject = projectAssociatedWithEmail.building.properties.filter( (projectProperty) => userProperties.some((userProperty) => userProperty.id === projectProperty.id) ) if (!userPropertiesForProject) { throw new Error( `User ${userWithData.id} answered by email but we couldn't find any properties for him in the project ${projectAssociatedWithEmail.id}` ) } await Promise.all( userPropertiesForProject.map((property) => SendbirdController.sendMessage({ fromSendbirdUserId: userWithData.id, projectId: projectAssociatedWithEmail.id, propertyId: property.id, message: `SUBJECT: ${subject}\n\nBODY: ${text || ''}`, attachments: attachmentsUploaded, messageData: JSON.stringify({ email: true }), }) ) ) } catch (e) { logger.error(e) } return res.status(200).end() }