import htmlToText from 'html-to-text'
import moment from 'moment'
import {
NotificationGetPayload,
NotificationPreference,
NOTIFICATION_DELIVERY_PLATFORM,
NOTIFICATION_TYPE,
} from 'nexus-plugin-prisma/client'
import { performance } from 'perf_hooks'
import Constants from '../../constants/general'
import { generateUnsubscribeToken } from '../../controllers/email/helpers'
import * as UserController from '../../controllers/user'
import { prismaClient as prisma } from '../../prismaClient'
import * as EmailUtils from '../../utils/email'
import ExpoNotification from '../../utils/expoNotification'
import GeneralUtils from '../../utils/general'
import { notificationLogger } from '../../utils/logger'
import { MANAGER_NOTIFICATION_TYPES, NotificationType } from '../../utils/notification'
import * as PusherUtils from '../../utils/pusher'
import Roles from '../../utils/roles'
import * as Twilio from '../../utils/twilio'
const NOTIFICATION_SELECT = {
id: true,
sent: true,
}
// Not sure of this and the name...
// Had to do this because below we initialize the notification before using prisma
// "let notification" will have the type any which is not what we want...
// Need to find a cleaner way to do this later to not have
// the "NOTIFICATION_SELECT" above + this "NotificationSelectType"...
type NotificationSelectType = NotificationGetPayload<{
select: {
id: true
sent: true
}
}>
function userHasEnableNotificationForPlatform(
user: {
hasAppNotificationEnable: boolean
hasEmailNotificationEnable: boolean
hasSMSNotificationEnable: boolean
},
platform: NOTIFICATION_DELIVERY_PLATFORM
) {
if (platform === 'APP') return user.hasAppNotificationEnable
if (platform === 'EMAIL') return user.hasEmailNotificationEnable
if (platform === 'SMS') return user.hasSMSNotificationEnable
}
function managerEnabledNotificationType(
user: {
id: string
notificationPreferences: NotificationPreference[]
hasAppNotificationEnable: boolean
hasEmailNotificationEnable: boolean
hasSMSNotificationEnable: boolean
},
type: NOTIFICATION_TYPE,
platform: NOTIFICATION_DELIVERY_PLATFORM
) {
const notificationTypeIsValid = MANAGER_NOTIFICATION_TYPES.includes(type)
if (!notificationTypeIsValid) {
notificationLogger.error(
`Notification type: ${type} is not included in the default notification types`
)
return userHasEnableNotificationForPlatform(user, platform)
}
const notificationPreference = user.notificationPreferences.find(
(notificationPreference) =>
notificationPreference.type === type && notificationPreference.platform === platform
)
if (!notificationPreference) {
notificationLogger.error(
`Can't find notification preference for type ${type} and platform ${platform} and user id ${user.id}`
)
return userHasEnableNotificationForPlatform(user, platform)
}
return notificationPreference.isEnable
}
// Probably can import something from @types/Bull instead...
type JobDataType = {
data: NotificationType & {
userId: string
}
}
export default async ({ data: jobData }: JobDataType) => {
const startTime = performance.now()
const {
userId,
title,
titleFr,
subtitle,
subtitleFr,
message,
messageFr,
data,
serviceProjectId,
projectId,
noAppNotification,
forceSMS,
noSMS,
smsData,
forceEmail,
forceApp,
noEmail,
emailData,
type,
forceSend,
sender,
isFromWalter,
skipValidating, // Use with precaution
} = jobData
try {
const project = projectId
? await prisma.project.findOne({
where: { id: projectId },
select: {
id: true,
name: true,
colorHex: true,
logo: {
select: {
url: true,
},
},
managingCompany: {
select: {
id: true,
longName: true,
shortName: true,
logo: { select: { url: true } },
phone: { select: { number: true, nationalFormat: true } },
address: {
select: {
address1: true,
apartmentNumber: true,
zip: true,
city: true,
state: true,
country: true,
countryCode: true,
provinceCode: true,
},
},
},
},
},
})
: null
const serviceProject = serviceProjectId
? await prisma.serviceProject.findOne({ where: { id: serviceProjectId } })
: null
// const notificationLogs = {
// title,
// titleFr,
// subtitle,
// subtitleFr,
// message,
// messageFr,
// notificationType: type,
// app: null,
// email: null,
// sms: null,
// error: null,
// pusher: null,
// userId: null,
// userName: null,
// }
const notificationErrors = {
errorMessage: null,
sentErrorMessage: null,
sentByAppErrorMessage: null,
sentByEmailErrorMessage: null,
sentBySMSErrorMessage: null,
}
let notification: NotificationSelectType
try {
let user = await prisma.user.findOne({
where: { id: userId },
include: {
phone: true,
homePhone: true,
officePhone: true,
managingCompanyRole: {
include: {
projects: {
select: {
id: true,
},
},
},
},
currentProject: {
select: {
id: true,
name: true,
},
},
notificationPreferences: true,
},
})
// notificationLogs.userId = user.id
// notificationLogs.userName = GeneralUtils.getUserName(user)
// Format because Property manager might put user information at the wrong place in Condo Manager
user = {
...user,
email: user.email || user.secondaryEmail,
phone: user.phone || user.homePhone || user.officePhone,
}
const userIsFrench = user.preferedLanguage === 'fr'
// Did that in case we want to resend a post for example
// We will send notification but we want to take the same notifcaitions created and just update them
// Did that to fix a bug where Tommy from Griffin sent a post
const existingNotification =
process.env.NODE_ENV === 'development'
? (
await prisma.notification.findMany({
take: 1,
where: {
user: {
id: user.id,
},
post: {
id: data.id,
},
},
select: NOTIFICATION_SELECT,
})
)[0]
: null
// Create the Walter notification for each user
notification =
existingNotification ||
(await prisma.notification // @ts-ignore
.create({
data: {
// @ts-ignore
type,
title,
subtitle,
message,
forceSend,
noEmail,
noSMS,
forceEmail,
forceApp,
noApp: noAppNotification,
forceSMS,
user: { connect: { id: user.id } },
...(data && { data: { id: data.id } }), // Just the id, passing all data is useless for now.
...(project?.id && { project: { connect: { id: project.id } } }),
...(serviceProject?.id && {
serviceProject: { connect: { id: serviceProject.id } },
}),
// Link notification with post
...((type === 'NEW_POST' || type === 'NEW_PROXY') &&
data?.id && {
post: {
connect: {
id: data.id,
},
},
}),
},
select: NOTIFICATION_SELECT,
}))
// Only resend if it wasn't sent... we don't want to spam the person too
if (existingNotification?.sent) {
return
}
// Make sure user can receive notification
if (!skipValidating) {
// ACTIVE
if (!user.active) {
notificationErrors.errorMessage =
"User can't receive notification because he/she is not active."
notificationErrors.sentErrorMessage =
"User can't receive notification because he/she is not active."
// notificationLogs.error = "❌ Can't receive notification because user is not active"
}
// WAITING FOR APPROVAL
if (user.waitingForApproval) {
notificationErrors.errorMessage =
"User can't receive notification because he/she is waiting for approval."
notificationErrors.sentErrorMessage =
"User can't receive notification because he/she is waiting for approval."
// notificationLogs.error = "❌ Can't receive notification: needs to be approved"
}
// RECEIVED INVITATION / INSTALLED
if (user.role === 'RESIDENT' && !user.hasReceivedInvitation && !user.hasInstalledApp) {
notificationErrors.errorMessage =
"User can't receive notification because he/she didn't receive the invitation to use Walter yet."
notificationErrors.sentErrorMessage =
"User can't receive notification because he/she didn't receive the invitation to use Walter yet."
// notificationLogs.error =
// "❌ Can't receive notification: Haven't received invitation or installed the app"
}
// MANAGER ROLE
if (user.role === 'MANAGER' && user.managingCompanyRole) {
if (!Roles.userCanReceiveNotificationForNotificationType(user, type)) {
notificationErrors.errorMessage =
"User can't receive notification because he/she doesn't have the right role."
notificationErrors.sentErrorMessage =
"User can't receive notification because he/she doesn't have the right role."
// notificationLogs.error = "❌ Can't receive notification: Doesn't have the right role"
} else if (!Roles.hasAccessToProject(project?.id, user)) {
notificationErrors.errorMessage = 'User role is not associated with this project'
notificationErrors.sentErrorMessage = 'User role is not associated with this project'
// notificationLogs.error =
// "❌ Can't receive notification: Role is not associated to this project"
}
}
}
if (!notificationErrors.errorMessage) {
// PUSHER
// Only send to managers for now because resident show local notification when new notification created
if (user.hasInstalledApp && (user.role === 'MANAGER' || user.role === 'PROVIDER')) {
try {
await PusherUtils.sendEvent(
'notification-channel',
`${user.role.toLowerCase()}-${user.id}`,
{
id: notification.id,
title: user.preferedLanguage === 'fr' && titleFr ? titleFr : title,
subtitle: user.preferedLanguage === 'fr' && subtitleFr ? subtitleFr : subtitle,
message: htmlToText.fromString(
user.preferedLanguage === 'fr' && messageFr ? messageFr : message
),
type,
...(project?.id && {
project: {
id: project.id,
},
}),
...(serviceProject?.id && {
serviceProject: {
id: serviceProject.id,
},
}),
...(data && {
data: {
id: data.id,
// For sendbird notification
...(data.channel && {
channel_url: data.channel.channel_url,
channel: {
channel_url: data.channel.channel_url,
},
}),
},
}),
}
)
// notificationLogs.pusher = '✅ Pusher notification sent'
} catch (error) {
notificationLogger.error(error)
// notificationLogs.pusher = error?.message || error
}
}
// Will be use later to send email/sms in case we absolutely need a notifciation to be sent
let receivedNotification = false
const userHasAppNotification =
user.role === 'MANAGER' && type
? managerEnabledNotificationType(user, type, 'APP')
: user.hasAppNotificationEnable
// APP notifications
if (
process.env.SEND_NOTIFICATION === 'true' &&
(userHasAppNotification || forceApp) &&
(user.oneSignalUserId || user.expoNotificationToken) &&
!noAppNotification
) {
try {
const newNumberOfBadges = user.appNotificationsBadgesNumber
? user.appNotificationsBadgesNumber + 1
: 1
if (
(user.role === 'MANAGER' || user.role === 'PROVIDER') &&
user.expoNotificationToken
) {
await ExpoNotification.sendNotification({
title: htmlToText.fromString(title || 'New notification'),
subtitle: htmlToText.fromString(
project?.name
? subtitle
? `${project.name} - ${subtitle}`
: project.name
: subtitle || ''
),
body: htmlToText.fromString(
GeneralUtils.truncate({
str: message,
})
),
token: user.expoNotificationToken,
badgeNumber: user.appNotificationsBadgesNumber
? user.appNotificationsBadgesNumber + 1
: 1,
data,
})
}
// RESIDENT
else if (user.role === 'RESIDENT') {
let residentIsUsingExpoNotification = false
if (user.role === 'RESIDENT') {
if (user.operatingSystem === 'ANDROID') {
residentIsUsingExpoNotification = parseInt(user.currentAppVersion) >= 29
} else if (!user.currentAppVersion) {
residentIsUsingExpoNotification = true
} else {
const [major, minor, revision] = user.currentAppVersion.split('.')
residentIsUsingExpoNotification =
parseInt(major) >= 3 && parseInt(minor) >= 1 && parseInt(revision) >= 1
}
}
if (residentIsUsingExpoNotification && user.expoNotificationToken) {
await ExpoNotification.sendNotification({
title: userIsFrench
? htmlToText.fromString(titleFr || title || 'Notification')
: htmlToText.fromString(title || 'Notification'),
...(!!subtitle && {
subtitle: userIsFrench
? htmlToText.fromString(subtitleFr || subtitle || 'Notification')
: htmlToText.fromString(subtitle || 'Notification'),
}),
...(message && {
body: htmlToText.fromString(
GeneralUtils.truncate({
str: userIsFrench ? messageFr || message : message,
})
),
}),
token: user.expoNotificationToken,
badgeNumber: user.appNotificationsBadgesNumber
? user.appNotificationsBadgesNumber + 1
: 1,
data,
})
}
}
// notificationLogs.app = '✅ APP notification sent'
receivedNotification = true
await prisma.notification.update({
where: {
id: notification.id,
},
data: {
sent: true,
sentAt: moment().toDate(),
sentByApp: true,
sentByAppAt: moment().toDate(),
delivered: true,
deliveredAt: moment().toDate(),
deliveredByApp: true,
deliveredByAppAt: moment().toDate(),
},
select: NOTIFICATION_SELECT,
})
await prisma.user.update({
where: {
id: user.id,
},
data: {
appNotificationsBadgesNumber: newNumberOfBadges,
},
})
} catch (error) {
notificationLogger.error(error)
// notificationLogs.app = error?.message || error
notificationErrors.sentByAppErrorMessage =
"Couldn't send app push notification. Permission might be refused."
}
} else if (process.env.SEND_NOTIFICATION !== 'true') {
// notificationLogs.app =
// '❌ Couldn\'t send because "process.env.SEND_NOTIFICATION" is not true'
} else if (!userHasAppNotification) {
// notificationLogs.app = "❌ Couldn't send because user has not enabled it"
notificationErrors.sentByAppErrorMessage =
"Couldn't send because user has not enabled app notifications"
} else if (!user.oneSignalUserId && !user.expoNotificationToken && user.hasInstalledApp) {
// notificationLogs.app =
// "❌ Couldn't send because user doesn't have oneSignal or expo notification token"
notificationErrors.sentByAppErrorMessage =
"Couldn't send because user didn't accept notifications permissions"
} else if (noAppNotification) {
// notificationLogs.app =
// "❌ Couldn't send because we said to not send this notification by app"
notificationErrors.sentByAppErrorMessage =
"Couldn't send because we said to not send this notification by app"
}
let receivedEmail = false
const userHasEmailNotification =
user.role === 'MANAGER' && type
? managerEnabledNotificationType(user, type, 'EMAIL')
: user.hasEmailNotificationEnable
const needToSendEmail = forceSend && !receivedNotification
// EMAIL notification
if (user.email && !noEmail && (userHasEmailNotification || forceEmail || needToSendEmail)) {
try {
const template: EmailUtils.TemplateNameTypes =
emailData?.template ||
(user.role === 'MANAGER'
? 'MANAGER_GENERAL_NOTIFICATION'
: user.preferedLanguage === 'fr'
? 'RESIDENT_GENERAL_NOTIFICATION_FR'
: 'RESIDENT_GENERAL_NOTIFICATION')
const from =
emailData?.from ||
(isFromWalter || serviceProject
? {
email: Constants.EMAIL_COMMUNICATION_WALTER_FROM_EMAIL,
name: Constants.EMAIL_COMMUNICATION_WALTER_FROM_NAME,
}
: {
email: Constants.EMAIL_COMMUNICATION_PARSE_FROM_EMAIL,
name: project
? project.managingCompany.shortName || project.managingCompany.longName
: Constants.EMAIL_COMMUNICATION_WALTER_FROM_NAME,
})
const customArgs = {
notificationId: notification.id,
emailTemplate: template,
...(emailData?.customArgs || {}),
}
const subject =
emailData?.subject ||
(isFromWalter || serviceProject || user.role === 'MANAGER'
? `${title || ''}${project && project.name ? ` - ${project.name}` : ''}`
: `${project && project.name ? `${project.name} - ` : ''}${
!user.preferedLanguage
? titleFr && title
? `${titleFr} / ${title}`
: title
: user.preferedLanguage === 'fr'
? titleFr || title
: title
}`)
const customVariables = {
unsubscribeToken: generateUnsubscribeToken(user.id),
preferedLanguage: user.preferedLanguage,
hasInstalledApp: user.hasInstalledApp,
isResident: user.role === 'RESIDENT',
title: !user.preferedLanguage
? titleFr && title
? `${titleFr} / ${title}`
: title
: user.preferedLanguage === 'fr'
? titleFr || title
: title,
subtitle: !user.preferedLanguage
? subtitleFr && subtitle
? `${subtitleFr} / ${subtitle}`
: subtitle
: user.preferedLanguage === 'fr'
? subtitleFr || subtitle
: subtitle,
body: !user.preferedLanguage
? messageFr && message
? `${messageFr} / ${message}`
: message
: user.preferedLanguage === 'fr'
? messageFr || message
: message,
bodySplitted: !user.preferedLanguage
? messageFr && message
? [
...GeneralUtils.splitTextWithLineBreak(`${messageFr}\n\n`),
...GeneralUtils.splitTextWithLineBreak(message),
]
: GeneralUtils.splitTextWithLineBreak(message)
: user.preferedLanguage === 'fr' && messageFr
? GeneralUtils.splitTextWithLineBreak(messageFr)
: GeneralUtils.splitTextWithLineBreak(message),
// NOT USED ANYMORE
logoText:
isFromWalter || serviceProject || user.role === 'MANAGER'
? Constants.WALTER_LOGO_BLACK
: project && project.managingCompany
? project.managingCompany.shortName ||
project.managingCompany.longName ||
'Walter'
: 'Walter',
// NOT USED ANYMORE
logo:
isFromWalter || serviceProject || user.role === 'MANAGER'
? Constants.WALTER_LOGO_BLACK
: project && project.managingCompany && project.managingCompany.logo
? project.managingCompany.logo.url
: null,
managingCompanyLogoUrl:
isFromWalter || serviceProject || user.role === 'MANAGER'
? Constants.WALTER_LOGO_BLACK
: project && project.managingCompany && project.managingCompany.logo
? project.managingCompany.logo.url
: null,
projectLogoUrl: project && project.logo ? project.logo.url : null,
projectColor: project && project.colorHex ? project.colorHex : '#000000',
projectName: project ? project.name || '' : '',
buildingName: project ? project.name || '' : '',
preheader:
user.preferedLanguage === 'fr'
? messageFr || subtitleFr || titleFr
: message || subtitle || title,
...(isFromWalter || serviceProject
? {
senderName: 'Walter',
senderTitle: 'Smart building technology',
senderEmail: 'info@usewalter.com',
senderPhoneNumber: '1 800-881-2629',
senderAddress: '2365 St-Patrick street, H3K 1B3, Montreal, Quebec, Canada',
projectName: user.currentProject ? user.currentProject.name : null,
}
: {
senderName:
project.managingCompany.longName || project.managingCompany.shortName,
senderTitle: '',
// senderEmail: project.managingCompany.email, // FOR NOW, DON'T PUT EMAIL
senderPhoneNumber: project.managingCompany.phone
? project.managingCompany.phone.nationalFormat ||
GeneralUtils.formatPhoneNumber(project.managingCompany.phone.number)
: '',
senderAddress: GeneralUtils.getFormattedAddress(
project.managingCompany.address
),
projectName: project.name,
}),
// In case we send sender data and want to overwrite default value
// ...(sender && sender.name && { senderName: sender.name }),
...(sender && sender.title && { senderTitle: sender.title }),
// ...(sender && sender.email && { senderEmail: sender.email }), // FOR NOW, DON'T PUT EMAIL
...(sender && sender.phoneNumber && { senderPhoneNumber: sender.phoneNumber }),
...(sender && sender.address && { senderAddress: sender.address }),
// Install the app message info
...(!user.hasInstalledApp && user.role === 'RESIDENT'
? {
showEnglishInstallText:
user.preferedLanguage === 'en' || user.preferedLanguage === null,
showFrenchInstallText: user.preferedLanguage === 'fr',
userPhoneNumber: user.phone
? user.phone.nationalFormat ||
GeneralUtils.formatPhoneNumber(user.phone.number)
: null,
userEmail: user.email,
}
: null),
...(emailData?.customVariables || {}),
}
const data = {
...emailData,
to: [{ email: user.email }],
template,
from,
customArgs,
subject,
customVariables,
}
await EmailUtils.send(data)
// notificationLogs.email = '✅ Email notification sent'
await prisma.notification.update({
where: {
id: notification.id,
},
data: {
sent: true,
sentAt: moment().toDate(),
sentByEmail: true,
sentByEmailAt: moment().toDate(),
},
select: NOTIFICATION_SELECT,
})
receivedEmail = true
} catch (error) {
notificationLogger.error(error)
// notificationLogs.email = error?.message || error
notificationErrors.sentByEmailErrorMessage = "Couldn't send email notification."
}
}
// else if (user.cantDeliverEmail) {
// notificationLogs.email = `❌ Couldn't send because user cant be delivered emails`
// notificationErrors.sentByEmailErrorMessage = `Couldn't send because user has an invalid email`
// }
else if (noEmail) {
// notificationLogs.email = "❌ Couldn't send because we don't want to"
notificationErrors.sentByEmailErrorMessage =
"Couldn't send by email because notification was not allowed by Walter to be sent by email"
} else if (!user.email) {
// notificationLogs.email = "❌ Couldn't send because user has no email"
notificationErrors.sentByEmailErrorMessage =
"Couldn't send by email because user doesn't have one."
} else if (!userHasEmailNotification) {
// notificationLogs.email = "❌ Couldn't send because user has not enabled it"
notificationErrors.sentByEmailErrorMessage =
"Couldn't send because user has not enabled email notifications"
} else if (user.role === 'RESIDENT' && receivedNotification) {
// notificationLogs.email =
// "❌ Couldn't send because it was already send by app notification"
notificationErrors.sentByEmailErrorMessage =
"Couldn't send because it was already sent by app notification and user don't want to receive an email if the app notification was delivered"
}
const userHasSMSNotification =
user.role === 'MANAGER' && type
? managerEnabledNotificationType(user, type, 'SMS')
: user.hasSMSNotificationEnable
const needToSendSMS = forceSend && !receivedNotification && !receivedEmail
// SMS notification
if ((forceSMS || userHasSMSNotification || needToSendSMS) && user.phone?.number && !noSMS) {
try {
let bodySMSMessage = ''
if (project && project.name) {
bodySMSMessage += `${project.name}`
}
if (title) {
if (!user.preferedLanguage && titleFr) {
bodySMSMessage += `\n\n${titleFr} / ${title}`
} else if (user.preferedLanguage === 'fr') {
bodySMSMessage += `\n\n${titleFr || title}`
} else {
bodySMSMessage += `\n\n${title}`
}
}
if (subtitle) {
if (!user.preferedLanguage && subtitleFr) {
bodySMSMessage += `\n\n${subtitleFr} / ${subtitle}`
} else if (user.preferedLanguage === 'fr') {
bodySMSMessage += `\n\n${subtitleFr || subtitle}`
} else {
bodySMSMessage += `\n\n${subtitle}`
}
}
if (message) {
if (!user.preferedLanguage && messageFr) {
bodySMSMessage += `\n\n${GeneralUtils.truncate({
str: messageFr,
maxChars: 30,
})} / ${GeneralUtils.truncate({
str: htmlToText.fromString(message),
maxChars: 30,
})}`
} else if (user.preferedLanguage === 'fr') {
bodySMSMessage += `\n\n${
GeneralUtils.truncate({
str: messageFr,
maxChars: 30,
}) ||
GeneralUtils.truncate({
str: htmlToText.fromString(message),
maxChars: 30,
})
}`
} else {
bodySMSMessage += `\n\n${GeneralUtils.truncate({
str: htmlToText.fromString(message),
maxChars: 30,
})}`
}
// ? `*Le message contient trop de charactère. Veuillez utilisez l'application Walter pour avoir plus de détails.*`
// : `*The message has too many characters. Please use Walter's application to see more the details.*`
}
if (sender) {
bodySMSMessage += `\n\n-\n${GeneralUtils.renderWithLineBreak(Object.values(sender))}`
}
if (user.role === 'RESIDENT') {
if (user.hasInstalledApp) {
bodySMSMessage += `\n\n${UserController.getMoreDetailsInWalterAppMessage({
language: user.preferedLanguage,
})}`
} else {
bodySMSMessage += `\n\n${await UserController.getDownloadWalterMessage({
user,
projectId: project ? project.id : null,
})}`
}
}
if (forceSMS && user.role === 'RESIDENT' && !user.hasSMSNotificationEnable) {
bodySMSMessage += `\n\n${
user.preferedLanguage === 'fr'
? "Vous recevez ce SMS car votre gestionnaire a forcé l'envoie par message texte afin de s'assurer que vous receviez bien le message."
: "You've received this SMS because your manager forced it to make sure you receive the message."
}`
}
const result = await Twilio.sendSMS({
to: user.phone.number,
body: bodySMSMessage,
itemId: notification.id,
...smsData,
})
// notificationLogs.sms = '✅ SMS notifications sent'
if (result?.sid) {
await prisma.notification.update({
where: {
id: notification.id,
},
data: {
twilioMessageSid: result.sid,
sent: true,
sentAt: moment().toDate(),
sentBySMS: true,
sentBySMSAt: moment().toDate(),
},
select: NOTIFICATION_SELECT,
})
}
} catch (error) {
notificationLogger.error(error)
// notificationLogs.sms = error?.message || error
notificationErrors.sentBySMSErrorMessage = "Couldn't send SMS notification."
}
} else if (process.env.SEND_SMS !== 'true') {
notificationErrors.sentBySMSErrorMessage =
"Couldn't send because there's no more SMS credit for this month"
// notificationLogs.sms = "❌ Couldn't send because SEND_SMS is not true"
} else if (!user.phone) {
// notificationLogs.sms = "❌ Couldn't send because user has no mobile phone number"
}
// else if (user.cantDeliverSMS) {
// notificationLogs.sms = `❌ Couldn't send because user cant be delivered SMS`
// notificationErrors.sentBySMSErrorMessage = `Couldn't send because user has an invalid mobile phone number`
// }
else if (noSMS) {
// notificationLogs.sms = "❌ Couldn't send because we don't want to"
notificationErrors.sentBySMSErrorMessage =
"Couldn't send by SMS because notification was not allowed to be sent by SMS"
} else if (!userHasSMSNotification) {
// notificationLogs.sms = "❌ Couldn't send because user has not enabled it"
notificationErrors.sentBySMSErrorMessage =
"Couldn't send because user has not enabled SMS notifications"
} else if (user.role === 'RESIDENT' && (receivedNotification || receivedEmail)) {
// notificationLogs.sms =
// "❌ Couldn't send because it was already sent with app notification OR email notification"
notificationErrors.sentBySMSErrorMessage =
"Couldn't send because it was already sent by app notification or email and user don't want to receive an email or SMS if the app notification was delivered"
}
}
} catch (error) {
notificationLogger.error(error)
if (!notificationErrors.errorMessage) {
notificationErrors.errorMessage = 'Something went wrong'
notificationErrors.sentErrorMessage = 'Something went wrong'
}
// notificationLogs.error = error?.message || error
}
if (notification?.id) {
await prisma.notification.update({
where: { id: notification.id },
data: notificationErrors,
})
}
const seconds = moment.duration(Math.floor(performance.now() - startTime)).asSeconds()
// notificationLogger.info(notificationLogs)
notificationLogger.info(`Notification processed in ${seconds} seconds`)
} catch (error) {
notificationLogger.error(error)
}
}