136 lines
3.6 KiB
JavaScript
136 lines
3.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: 'classRegistered',
|
|
label: 'ثبتنام در کلاس',
|
|
envKey: 'SMS_TEMPLATE_CLASS_REGISTERED',
|
|
slots: [
|
|
{ key: 'className', label: 'نام کلاس', defaultName: 'className' }
|
|
]
|
|
},
|
|
{
|
|
key: 'classReminder',
|
|
label: 'یادآوری کلاس',
|
|
envKey: 'SMS_TEMPLATE_CLASS_REMINDER',
|
|
slots: [
|
|
{ key: 'className', label: 'نام کلاس', defaultName: 'className' },
|
|
{ key: 'time', label: 'ساعت', defaultName: 'time' },
|
|
{ key: 'place', label: 'مکان', defaultName: 'place' }
|
|
]
|
|
},
|
|
{
|
|
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' }
|
|
]
|
|
}
|
|
];
|
|
|
|
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 defaultVariableMap = (def) => {
|
|
const map = {};
|
|
(def.slots || []).forEach((slot) => {
|
|
map[slot.key] = slot.defaultName;
|
|
});
|
|
return map;
|
|
};
|
|
|
|
const emptyTemplateEntry = (def) => ({
|
|
templateId: '',
|
|
variables: defaultVariableMap(def)
|
|
});
|
|
|
|
const normalizeStoredEntry = (raw) => {
|
|
if (raw == null || raw === '') {
|
|
return { templateId: '', variables: {} };
|
|
}
|
|
if (typeof raw === 'string' || typeof raw === 'number') {
|
|
return { templateId: String(raw), variables: {} };
|
|
}
|
|
if (typeof raw !== 'object') {
|
|
return { templateId: '', variables: {} };
|
|
}
|
|
|
|
let variables = {};
|
|
if (raw.variables && typeof raw.variables === 'object' && !Array.isArray(raw.variables)) {
|
|
variables = { ...raw.variables };
|
|
} else if (Array.isArray(raw.variables)) {
|
|
raw.variables.forEach((item) => {
|
|
if (item?.slot) variables[item.slot] = item.name;
|
|
});
|
|
}
|
|
|
|
return {
|
|
templateId: raw.templateId != null ? String(raw.templateId) : '',
|
|
variables
|
|
};
|
|
};
|
|
|
|
const resolveVariableMap = (def, storedVariables = {}) => {
|
|
const map = {};
|
|
(def.slots || []).forEach((slot) => {
|
|
const sanitized = sanitizeVariableName(storedVariables[slot.key]);
|
|
map[slot.key] = sanitized || slot.defaultName;
|
|
});
|
|
return map;
|
|
};
|
|
|
|
const buildSmsParameters = (variableMap, valuesBySlot) => {
|
|
return Object.entries(valuesBySlot)
|
|
.map(([slot, value]) => {
|
|
const name = String(variableMap?.[slot] || '').trim();
|
|
if (!name) return null;
|
|
return { name, value: String(value ?? '') };
|
|
})
|
|
.filter(Boolean);
|
|
};
|
|
|
|
module.exports = {
|
|
SMS_TEMPLATE_DEFS,
|
|
SMS_TEMPLATE_KEYS,
|
|
envFallbackFor,
|
|
sanitizeTemplateId,
|
|
sanitizeVariableName,
|
|
defaultVariableMap,
|
|
emptyTemplateEntry,
|
|
normalizeStoredEntry,
|
|
resolveVariableMap,
|
|
buildSmsParameters
|
|
};
|