80 lines
2.3 KiB
JavaScript
80 lines
2.3 KiB
JavaScript
// /utils/senders/sms.base.js
|
|
'use strict';
|
|
|
|
const axios = require('axios');
|
|
const config = require('../../config/config');
|
|
const logger = require('../logger');
|
|
const { getMessagingChannelState } = require('../../components/settings/messagingFlags');
|
|
|
|
const toBoolean = (value) => {
|
|
if (typeof value === 'boolean') return value;
|
|
if (value == null) return false;
|
|
const normalized = String(value).trim().toLowerCase();
|
|
return ['true', '1', 'yes', 'on'].includes(normalized);
|
|
};
|
|
|
|
const redactSmsParams = (params = []) => (
|
|
params.map((param) => (
|
|
String(param?.name || '').toLowerCase() === 'password'
|
|
? { ...param, value: '[redacted]' }
|
|
: param
|
|
))
|
|
);
|
|
|
|
const sendSingleSms = async (mobile, templateId, params = []) => {
|
|
const channelState = await getMessagingChannelState('sms', mobile);
|
|
|
|
logger.info('[SMS] About to send notification:', {
|
|
mobile,
|
|
templateId,
|
|
params: redactSmsParams(params),
|
|
SMS_ENABLED: channelState.envEnabled,
|
|
dashboardEnabled: channelState.dbEnabled,
|
|
bypassActive: Boolean(channelState.bypass)
|
|
});
|
|
|
|
if (!channelState.enabled) {
|
|
const reason = channelState.blockReason || 'channel_disabled';
|
|
const detail = reason === 'dashboard_disabled'
|
|
? 'dashboard smsEnabled=false'
|
|
: 'SMS_ENABLED env flag is false';
|
|
logger.info(`[SMS] Skipped (${detail}) → ${mobile} template=${templateId}`);
|
|
return { skipped: true, reason };
|
|
}
|
|
|
|
if (!templateId) {
|
|
logger.warn(`[SMS] Missing templateId for ${mobile}`);
|
|
return { skipped: true, reason: 'missing_template' };
|
|
}
|
|
|
|
if (!mobile) {
|
|
logger.warn('[SMS] Missing mobile number');
|
|
return { skipped: true, reason: 'missing_mobile' };
|
|
}
|
|
|
|
const request = {
|
|
method: 'POST',
|
|
url: 'https://api.sms.ir/v1/send/verify',
|
|
headers: {
|
|
'X-API-KEY': config.SMS_PANEL_TOKEN,
|
|
Accept: 'application/json',
|
|
},
|
|
data: {
|
|
mobile,
|
|
templateId: Number(templateId) || templateId,
|
|
parameters: params,
|
|
},
|
|
};
|
|
|
|
try {
|
|
const result = await axios(request);
|
|
logger.info(`[SMS] Sent to ${mobile} template=${templateId}`);
|
|
return result.data;
|
|
} catch (err) {
|
|
logger.error(`[SMS] Failed to ${mobile}: ${err.response?.data?.message || err.message}`);
|
|
throw err;
|
|
}
|
|
};
|
|
|
|
module.exports = { sendSingleSms, toBoolean };
|