Files
gameno-api/utils/senders/smsMessages.js
T
kavehhn 72be01fee3 feat: add messaging toggles, password reset SMS, and payment discounts
Allow SuperAdmin to disable SMS, email, and bot from dashboard settings on top of env flags. Add admin password reset with credentials SMS, plus payment discounts, notes, and payable amount handling.
2026-08-16 06:58:08 +03:30

183 lines
6.0 KiB
JavaScript

// /utils/senders/smsMessages.js
'use strict';
const { sendSingleSms } = require('./sms.base');
const { recordAndSend } = require('./notificationRecorder');
const { getSmsTemplate } = require('../../components/settings/settingService');
const { buildSmsParameters } = require('../../components/settings/smsTemplates');
const User = require('../../components/users/userModel');
const resolveUserIdByPhone = async (phoneNumber) => {
if (!phoneNumber) return null;
const user = await User.findOne({ phoneNumber: String(phoneNumber) }).select('_id').lean();
return user?._id || null;
};
const sendAccountCredentialsSms = async ({
receiver,
username,
password,
userId = null,
subject,
body,
relatedEvent
}) => {
const resolvedUserId = userId || await resolveUserIdByPhone(receiver);
let fullName = '';
if (resolvedUserId) {
const user = await User.findById(resolvedUserId).select('name').lean();
if (user?.name) fullName = user.name;
}
const { templateId, variables } = await getSmsTemplate('accountCreated');
return recordAndSend({
userId: resolvedUserId,
channel: 'sms',
subject,
body,
relatedEvent,
sendFn: () => sendSingleSms(receiver, templateId, buildSmsParameters(variables, {
username,
password,
fullName: fullName || username,
name: fullName || username,
phoneNumber: receiver,
mobile: receiver
}))
});
};
const sendAccountCreatedSms = async (receiver, username, password, userId = null) => {
return sendAccountCredentialsSms({
receiver,
username,
password,
userId,
subject: 'ایجاد حساب کاربری',
body: `حساب کاربری شما ایجاد شد. نام کاربری: ${username}`,
relatedEvent: 'user.created'
});
};
const sendPasswordResetSms = async (receiver, username, password, userId = null) => {
return sendAccountCredentialsSms({
receiver,
username,
password,
userId,
subject: 'بازنشانی رمز عبور',
body: `رمز عبور شما بازنشانی شد. نام کاربری: ${username}`,
relatedEvent: 'user.password_reset'
});
};
const sendClassRegisteredSms = async (receiver, className, userId = null, extraContext = {}) => {
const resolvedUserId = userId || await resolveUserIdByPhone(receiver);
let fullName = extraContext.fullName || '';
if (!fullName && resolvedUserId) {
const user = await User.findById(resolvedUserId).select('name').lean();
if (user?.name) fullName = user.name;
}
const { templateId, variables } = await getSmsTemplate('classRegistered');
return recordAndSend({
userId: resolvedUserId,
channel: 'sms',
subject: 'ثبت‌نام در کلاس',
body: `ثبت‌نام شما در کلاس «${className}» انجام شد.`,
relatedEvent: 'user.enrolled',
sendFn: () => sendSingleSms(receiver, templateId, buildSmsParameters(variables, {
className,
courseName: extraContext.courseName || className,
fullName: fullName || 'کارآموز',
phoneNumber: receiver,
mobile: receiver,
classStartDate: extraContext.classStartDate || '',
classDays: extraContext.classDays || '',
courseTime: extraContext.courseTime || '',
...extraContext
}))
});
};
const sendClassReminderSms = async (receiver, className, time, place = '', userId = null, extraContext = {}) => {
const resolvedUserId = userId || await resolveUserIdByPhone(receiver);
let fullName = extraContext.fullName || '';
if (!fullName && resolvedUserId) {
const user = await User.findById(resolvedUserId).select('name').lean();
if (user?.name) fullName = user.name;
}
const { templateId, variables } = await getSmsTemplate('classReminder');
return recordAndSend({
userId: resolvedUserId,
channel: 'sms',
subject: 'یادآوری کلاس',
body: `یادآوری کلاس «${className}» ساعت ${time} — مکان: ${place || '-'}`,
relatedEvent: 'session.reminder',
sendFn: () => sendSingleSms(receiver, templateId, buildSmsParameters(variables, {
className,
courseName: extraContext.courseName || className,
time,
place: place || '-',
fullName: fullName || 'کارآموز',
phoneNumber: receiver,
mobile: receiver,
classStartDate: extraContext.classStartDate || '',
classDays: extraContext.classDays || '',
courseTime: extraContext.courseTime || extraContext.time || time || '',
...extraContext
}))
});
};
const sendInvoiceCreatedSms = async (receiver, payload, userId = null) => {
const resolvedUserId = userId || await resolveUserIdByPhone(receiver);
const { templateId, variables } = await getSmsTemplate('invoiceCreated');
let fullName = '';
let amount = '';
let course = '';
let classStartDate = '';
let classDays = '';
let courseTime = '';
if (typeof payload === 'object' && payload !== null) {
fullName = payload.fullName || '';
amount = payload.amount != null ? String(payload.amount) : '';
course = payload.course || '';
classStartDate = payload.classStartDate || '';
classDays = payload.classDays || '';
courseTime = payload.courseTime || '';
} else {
amount = String(payload || '');
}
const amountLabel = String(amount);
const courseLabel = course || '-';
const fullNameLabel = fullName || 'کارآموز';
return recordAndSend({
userId: resolvedUserId,
channel: 'sms',
subject: 'ایجاد صورتحساب',
body: `کارآموز عزیز، ${fullNameLabel}، یک صورتحساب به مبلغ ${amountLabel} تومان بابت دوره «${courseLabel}» برای شما ایجاد شد.`,
relatedEvent: 'payment.created',
sendFn: () => sendSingleSms(receiver, templateId, buildSmsParameters(variables, {
fullName: fullNameLabel,
amount: amountLabel,
course: courseLabel,
phoneNumber: receiver,
mobile: receiver,
classStartDate,
classDays,
courseTime
}))
});
};
module.exports = {
sendAccountCreatedSms,
sendPasswordResetSms,
sendClassRegisteredSms,
sendClassReminderSms,
sendInvoiceCreatedSms
};