Surface env vs dashboard disable reasons in SMS logs so password reset and other sends are easier to diagnose when only one layer is enabled.
79 lines
2.2 KiB
JavaScript
79 lines
2.2 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');
|
|
|
|
logger.info('[SMS] About to send notification:', {
|
|
mobile,
|
|
templateId,
|
|
params: redactSmsParams(params),
|
|
SMS_ENABLED: channelState.envEnabled,
|
|
dashboardEnabled: channelState.dbEnabled,
|
|
});
|
|
|
|
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 };
|