Files
gameno-api/components/settings/smsTemplates.js
T

191 lines
5.6 KiB
JavaScript

'use strict';
const SMS_TEMPLATE_DEFS = [
{
key: 'accountCreated',
label: 'ایجاد حساب کاربری',
envKey: 'SMS_TEMPLATE_ACCOUNT_CREATED',
slots: [
{ key: 'username', label: 'نام کاربری', defaultName: 'user' },
{ key: 'password', label: 'رمز عبور', defaultName: 'password' },
{ key: 'fullName', label: 'نام کاربر', defaultName: 'name' },
{ key: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' }
]
},
{
key: 'classRegistered',
label: 'ثبت‌نام در کلاس',
envKey: 'SMS_TEMPLATE_CLASS_REGISTERED',
slots: [
{ key: 'className', label: 'نام کلاس', defaultName: 'className' },
{ key: 'courseName', label: 'نام دوره', defaultName: 'courseName' },
{ key: 'fullName', label: 'نام کارآموز', defaultName: 'fullName' },
{ key: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' }
]
},
{
key: 'classReminder',
label: 'یادآوری کلاس',
envKey: 'SMS_TEMPLATE_CLASS_REMINDER',
slots: [
{ key: 'className', label: 'نام کلاس', defaultName: 'className' },
{ key: 'courseName', label: 'نام دوره', defaultName: 'courseName' },
{ key: 'time', label: 'ساعت', defaultName: 'time' },
{ key: 'place', label: 'مکان', defaultName: 'place' },
{ key: 'fullName', label: 'نام کاربر', defaultName: 'fullName' },
{ key: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' }
]
},
{
key: 'invoiceCreated',
label: 'ایجاد صورتحساب',
envKey: 'SMS_TEMPLATE_INVOICE_CREATED',
slots: [
{ key: 'fullName', label: 'نام کارآموز', defaultName: 'FULLNAME' },
{ key: 'amount', label: 'مبلغ', defaultName: 'PAYMENT_PRICE' },
{ key: 'course', label: 'نام دوره', defaultName: 'COURSE' },
{ key: 'phoneNumber', label: 'شماره همراه', defaultName: 'MOBILE' }
]
}
];
const SMS_TEMPLATE_KEYS = SMS_TEMPLATE_DEFS.map((def) => def.key);
const envFallbackFor = (def) => {
if (!def?.envKey) return '';
return String(process.env[def.envKey] || '').trim();
};
const sanitizeTemplateId = (value) => {
if (value == null) return '';
const digits = String(value).trim();
if (!digits) return '';
if (!/^\d{1,20}$/.test(digits)) return null;
return digits;
};
const sanitizeVariableName = (value) => {
if (value == null) return '';
const name = String(value).trim().replace(/^#+|#+$/g, '');
if (!name) return '';
if (!/^[A-Za-z][A-Za-z0-9_]{0,49}$/.test(name)) return null;
return name;
};
const defaultVariablesList = (def) => {
return (def?.slots || []).map((slot) => ({
slot: slot.key,
name: slot.defaultName
}));
};
const emptyTemplateEntry = (def) => ({
templateId: '',
variables: defaultVariablesList(def)
});
const normalizeStoredEntry = (raw, def) => {
if (raw == null || raw === '') {
return {
templateId: '',
variables: def ? defaultVariablesList(def) : []
};
}
if (typeof raw === 'string' || typeof raw === 'number') {
return {
templateId: String(raw),
variables: def ? defaultVariablesList(def) : []
};
}
if (typeof raw !== 'object') {
return {
templateId: '',
variables: def ? defaultVariablesList(def) : []
};
}
let variables = [];
if (Array.isArray(raw.variables)) {
variables = raw.variables
.filter((item) => item && typeof item === 'object' && item.slot)
.map((item) => ({
slot: String(item.slot).trim(),
name: String(item.name || '').trim()
}));
} else if (raw.variables && typeof raw.variables === 'object') {
variables = Object.entries(raw.variables).map(([slot, name]) => ({
slot: String(slot).trim(),
name: String(name || '').trim()
}));
} else if (def) {
variables = defaultVariablesList(def);
}
return {
templateId: raw.templateId != null ? String(raw.templateId) : '',
variables
};
};
const resolveVariablesList = (def, storedVariables) => {
if (!storedVariables) {
return defaultVariablesList(def);
}
let list = [];
if (Array.isArray(storedVariables)) {
list = storedVariables;
} else if (typeof storedVariables === 'object') {
list = Object.entries(storedVariables).map(([slot, name]) => ({ slot, name }));
}
return list
.map((item) => {
const slot = String(item.slot || '').trim();
if (!slot) return null;
const slotDef = (def?.slots || []).find((s) => s.key === slot);
const rawName = item.name !== undefined ? item.name : slotDef?.defaultName || '';
const sanitized = sanitizeVariableName(rawName);
return {
slot,
name: sanitized || slotDef?.defaultName || slot
};
})
.filter(Boolean);
};
const buildSmsParameters = (variables, valuesBySlot = {}) => {
let list = [];
if (Array.isArray(variables)) {
list = variables;
} else if (variables && typeof variables === 'object') {
list = Object.entries(variables).map(([slot, name]) => ({ slot, name }));
}
return list
.map((item) => {
const name = sanitizeVariableName(item?.name);
if (!name) return null;
const slot = item?.slot;
const value = slot ? valuesBySlot?.[slot] : '';
return {
name,
value: String(value ?? '')
};
})
.filter(Boolean);
};
module.exports = {
SMS_TEMPLATE_DEFS,
SMS_TEMPLATE_KEYS,
envFallbackFor,
sanitizeTemplateId,
sanitizeVariableName,
defaultVariablesList,
emptyTemplateEntry,
normalizeStoredEntry,
resolveVariablesList,
buildSmsParameters
};