sms-validator
Version:
SMS validation utility for Africa's Talking SMS service. Supports GSM-7/Unicode detection, E.164 validation, segment count, and optional sanitization.
80 lines (67 loc) • 2.03 kB
JavaScript
// index.js
const { parsePhoneNumberFromString } = require("libphonenumber-js");
// GSM-7 charset
const GSM_CHARSET =
"@£$¥èéùìòÇ\nØø\rÅåΔ_ΦΓΛΩΠΨΣΘΞ\x1BÆæßÉ !\"#¤%&'()*+,-./0123456789:;<=>?" +
"¡ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑܧ¿abcdefghijklmnopqrstuvwxyzäöñüà";
// Max length per encoding type for AT SMS
const MAX_SEGMENTS = {
GSM7: 3 * 153,
UCS2: 3 * 67,
};
function isValidPhoneNumber(phone) {
const parsed = parsePhoneNumberFromString(phone);
return parsed?.isValid() || false;
}
function isGSM7(text) {
for (let char of text) {
if (!GSM_CHARSET.includes(char)) return false;
}
return true;
}
function detectEncoding(text) {
return isGSM7(text) ? "GSM-7" : "UCS-2";
}
function getSmsSegments(text) {
const encoding = detectEncoding(text);
const singleLimit = encoding === "GSM-7" ? 160 : 70;
const multiLimit = encoding === "GSM-7" ? 153 : 67;
if (text.length <= singleLimit) return 1;
return Math.ceil(text.length / multiLimit);
}
function sanitizeMessage(message) {
return message.replace(/[^\x00-\x7F]/g, "").trim();
}
function getMessageBreakdown(message, costPerSegment = 0) {
const encoding = detectEncoding(message);
const segments = getSmsSegments(message);
return {
encoding,
segments,
cost: segments * costPerSegment,
length: message.length,
};
}
function validateSms(phone, message, options = {}) {
const { sanitize = false, maxSegments = 3 } = options;
const cleanMessage = sanitize ? sanitizeMessage(message) : message;
const encoding = detectEncoding(cleanMessage);
const segments = getSmsSegments(cleanMessage);
const isLengthValid = segments <= maxSegments;
return {
isPhoneValid: isValidPhoneNumber(phone),
encoding,
segments,
messageLength: cleanMessage.length,
isLengthValid,
sanitized: sanitize ? cleanMessage : null,
};
}
module.exports = {
validateSms,
isValidPhoneNumber,
detectEncoding,
getSmsSegments,
getMessageBreakdown,
sanitizeMessage,
};