UNPKG

twilio-split-sms

Version:

Forked version of codesleuth's split-sms: An SMS message splitter with support for both GSM and Unicode.

714 lines (664 loc) 16.9 kB
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.splitter = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ var gsmvalidator = require('./gsmvalidator'); function isHighSurrogate(code) { return code >= 0xD800 && code <= 0xDBFF; } module.exports.split = function (message, options) { options = options || { summary: false }; if (message === '') { return { parts: [{ content: options.summary ? undefined : '', length: 0, bytes: 0 }], totalLength: 0, totalBytes: 0 }; } var messages = []; var length = 0; var bytes = 0; var totalBytes = 0; var totalLength = 0; var messagePart = ''; function bank() { var msg = { content: options.summary ? undefined : messagePart, length: length, bytes: bytes }; messages.push(msg); totalLength += length; length = 0; totalBytes += bytes; bytes = 0; messagePart = ''; } for (var i = 0, count = message.length; i < count; i++) { var c = message.charAt(i); if (!gsmvalidator.validateCharacter(c)) { if (isHighSurrogate(c.charCodeAt(0))) { i++; } c = '\u0020'; } else if (gsmvalidator.validateExtendedCharacter(c)) { if (bytes === 152) bank(); bytes++; } bytes++; length++; if (!options.summary) messagePart += c; if (bytes === 153) bank(); } if (bytes > 0) bank(); if (messages[1] && totalBytes <= 160) { return { parts: [{ content: options.summary ? undefined : messages[0].content + messages[1].content, length: totalLength, bytes: totalBytes }], totalLength: totalLength, totalBytes: totalBytes }; } return { parts: messages, totalLength: totalLength, totalBytes: totalBytes }; }; },{"./gsmvalidator":2}],2:[function(require,module,exports){ // TODO Add descriptions in comments for codes that cannot be represented with visible characters. var GSM_charCodes = [ 10, // 12, // 13, // 32, // 33, // ! 34, // " 35, // # 36, // $ 37, // % 38, // & 39, // ' 40, // ( 41, // ) 42, // * 43, // + 44, // , 45, // - 46, // . 47, // / 48, // 0 49, // 1 50, // 2 51, // 3 52, // 4 53, // 5 54, // 6 55, // 7 56, // 8 57, // 9 58, // : 59, // ; 60, // < 61, // = 62, // > 63, // ? 64, // @ 65, // A 66, // B 67, // C 68, // D 69, // E 70, // F 71, // G 72, // H 73, // I 74, // J 75, // K 76, // L 77, // M 78, // N 79, // O 80, // P 81, // Q 82, // R 83, // S 84, // T 85, // U 86, // V 87, // W 88, // X 89, // Y 90, // Z 91, // [ 92, // \ 93, // ] 94, // ^ 95, // _ 97, // a 98, // b 99, // c 100, // d 101, // e 102, // f 103, // g 104, // h 105, // i 106, // j 107, // k 108, // l 109, // m 110, // n 111, // o 112, // p 113, // q 114, // r 115, // s 116, // t 117, // u 118, // v 119, // w 120, // x 121, // y 122, // z 123, // { 124, // | 125, // } 126, // ~ 161, // ¡ 163, // £ 164, // ¤ 165, // ¥ 167, // § 191, // ¿ 196, // Ä 197, // Å 198, // Æ 199, // Ç 201, // É 209, // Ñ 214, // Ö 216, // Ø 220, // Ü 223, // ß 224, // à 228, // ä 229, // å 230, // æ 232, // è 233, // é 236, // ì 241, // ñ 242, // ò 246, // ö 248, // ø 249, // ù 252, // ü 915, // Γ 916, // Δ 920, // Θ 923, // Λ 926, // Ξ 928, // Π 931, // Σ 934, // Φ 936, // Ψ 937, // Ω 8364, // €, // Twilio Smart Encoded Characters 171, // « 187, // » 8220, // “ 8221, // ” 698, // ʺ 750, // ˮ 8223, // ‟ 10077, // ❝ 10078, // ❞ 12317, // 〝 12318, // 〞 65282, // " 8216, // ‘ 8217, // ’ 699, // ʻ 712, // ˈ 700, // ʼ 701, // ʽ 697, // ʹ 8219, // ‛ 65287, // ' 180, // ´ 714, // ˊ 96, // ` 715, // ˋ 10075, // ❛ 10076, // ❜ 787, // ̓ 788, // ̔ 65040, // ︐ 65041, // ︑ 247, // ÷ 188, // ¼ 189, // ½ 190, // ¾ 10744, // ⧸ 823, // ̷ 824, // ̸ 8260, // ⁄ 8725, // ∕ 65295, // / 10745, // ⧹ 10741, // ⧵ 8421, // ⃥ 65128, // ﹨ 65340, // \ 818, // ̲ 65343, // _ 8402, // ⃒ 8403, // ⃓ 8739, // ∣ 65372, // | 9144, // ⎸ 9145, // ⎹ 9168, // ⏐ 9116, // ⎜ 9119, // ⎟ 9148, // ⎼ 9149, // ⎽ 8213, // ― 65123, // ﹣ 65293, // - 8208, // ‐ 8259, // ⁃ 65131, // ﹫ 65312, // @ 65129, // ﹩ 65284, // $ 451, // ǃ 65045, // ︕ 65111, // ﹗ 65281, // ! 65119, // ﹟ 65283, // # 65130, // ﹪ 65285, // % 65120, // ﹠ 65286, // & 8218, // ‚ 806, // ̦ 65104, // ﹐ 65105, // ﹑ 65292, // , 65380, // 、 10088, // ❨ 10090, // ❪ 65113, // ﹙ 65288, // ( 10222, // ⟮ 10629, // ⦅ 10089, // ❩ 10091, // ❫ 65114, // ﹚ 65289, // ) 10223, // ⟯ 10630, // ⦆ 8270, // ⁎ 8727, // ∗ 8859, // ⊛ 10018, // ✢ 10019, // ✣ 10020, // ✤ 10021, // ✥ 10033, // ✱ 10034, // ✲ 10035, // ✳ 10042, // ✺ 10043, // ✻ 10044, // ✼ 10045, // ✽ 10051, // ❃ 10057, // ❉ 10058, // ❊ 10059, // ❋ 10694, // ⧆ 65121, // ﹡ 65290, // * 726, // ˖ 65122, // ﹢ 65291, // + 12290, // 。 65106, // ﹒ 65294, // . 65377, // 。 65296, // 0 65297, // 1 65298, // 2 65299, // 3 65300, // 4 65301, // 5 65302, // 6 65303, // 7 65304, // 8 65305, // 9 720, // ː 760, // ˸ 10626, // ⦂ 42889, // ꞉ 65043, // ︓ 65306, // : 8271, // ⁏ 65044, // ︔ 65108, // ﹔ 65307, // ; 65124, // ﹤ 65308, // < 839, // ͇ 42890, // ꞊ 65126, // ﹦ 65309, // = 65125, // ﹥ 65310, // > 65046, // ︖ 65110, // ﹖ 65311, // ? 65313, // A 7424, // ᴀ 65314, // B 665, // ʙ 65315, // C 7428, // ᴄ 65316, // D 7429, // ᴅ 65317, // E 7431, // ᴇ 65318, // F 42800, // ꜰ 65319, // G 610, // ɢ 65320, // H 668, // ʜ 65321, // I 618, // ɪ 65322, // J 7434, // ᴊ 65323, // K 7435, // ᴋ 65324, // L 671, // ʟ 65325, // M 7437, // ᴍ 65326, // N 628, // ɴ 65327, // O 7439, // ᴏ 65328, // P 7448, // ᴘ 65329, // Q 65330, // R 640, // ʀ 65331, // S 42801, // ꜱ 65332, // T 7451, // ᴛ 65333, // U 7452, // ᴜ 65334, // V 7456, // ᴠ 65335, // W 7457, // ᴡ 65336, // X 65337, // Y 655, // ʏ 65338, // Z 7458, // ᴢ 710, // ˆ 770, // ̂ 65342, // ^ 7629, // ᷍ 10100, // ❴ 65115, // ﹛ 65371, // { 10101, // ❵ 65116, // ﹜ 65373, // } 65339, // [ 65341, // ] 732, // ˜ 759, // ˷ 771, // ̃ 816, // ̰ 820, // ̴ 8764, // ∼ 65374, // ~ 160, // 8192, // 8193, // 8194, // 8195, // 8196, // 8197, // 8198, // 8199, // 8200, // 8201, // 8202, // 8239, // 8287, // 12288, // 141, //  159, // Ÿ 128, // € 144, //  155, // › 16, //  9, // 0, // 3, //  4, //  23, //  25, //  17, //  18, //  19, //  20, //  8215, // ‗ 8212, // — 8211, // – 8218, // ‚ 8239, // 8249, // ‹ 8250, // › 8252, // ‼ 8222, // „ 8221, // ” 8220, // “ 8219, // ‛ 8230, // … 8232, // 8233, // 8287, // 8288 // ]; // TODO Add descriptions in comments for codes that cannot be represented with visible characters. var GSMe_charCodes = [ 12, // 91, // [ 92, // \ 93, // ] 94, // ^ 123, // { 124, // | 125, // } 126, // ~ 8364, // € // Twilio smart encoded characters that transliterate to extended GSM 710, // ˆ 770, // ̂ 65342, // ^ 7629, // ᷍ 10100, // ❴ 65115, // ﹛ 65371, // { 8821, // ≵ 65116, // ﹜ 65373, // } 10745, // ⧹ 10741, // ⧵ 8421, // ⃥ 65128, // ﹨ 65340, // \ 65339, // [ 65341, // ] 732, // ˜ 759, // ˷ 771, // ̃ 816, // ̰ 820, // ̴ 8764, // ∼ 65374, // ~ 8402, // ⃒ 8403, // ⃓ 8739, // ∣ 65372, // | 9144, // ⎸ 9145, // ⎹ 9168, // ⏐ 9116, // ⎜ 9119 // ⎟ ]; function existsInArray(code, array) { var len = array.length; var i = 0; while (i < len) { var e = array[i]; if (code === e) return true; i++; } return false; } function validateCharacter(character) { var code = character.charCodeAt(0); return existsInArray(code, GSM_charCodes); } function validateMessage(message) { for (var i = 0; i < message.length; i++) { if (!validateCharacter(message.charAt(i))) return false; } return true; } function validateExtendedCharacter(character) { var code = character.charCodeAt(0); return existsInArray(code, GSMe_charCodes); } module.exports.validateCharacter = validateCharacter; module.exports.validateMessage = validateMessage; module.exports.validateExtendedCharacter = validateExtendedCharacter; },{}],3:[function(require,module,exports){ var gsmValidator = require('./gsmvalidator'), gsmSplitter = require('./gsmsplitter'), unicodeSplitter = require('./unicodesplitter'); function calculateRemaining(parts, singleBytes, multiBytes, charBytes) { var max = parts.length === 1 ? singleBytes : multiBytes; return (max - parts[parts.length - 1].bytes) / charBytes; } var UNICODE = module.exports.UNICODE = 'Unicode'; var GSM = module.exports.GSM = 'GSM'; module.exports.split = function (message, options) { var characterset = options && options.characterset; options = { summary: options && options.summary }; var isGsm = (characterset === undefined && gsmValidator.validateMessage(message)) || characterset === GSM; var splitResult, singleBytes, multiBytes, charBytes; if (isGsm) { splitResult = gsmSplitter.split(message, options); singleBytes = 160; multiBytes = 153; charBytes = 1; } else { splitResult = unicodeSplitter.split(message, options); singleBytes = 140; multiBytes = 134; charBytes = 2; } var remainingInPart = calculateRemaining(splitResult.parts, singleBytes, multiBytes, charBytes); return { characterSet: isGsm ? GSM : UNICODE, parts: splitResult.parts, bytes: splitResult.totalBytes, length: splitResult.totalLength, remainingInPart: remainingInPart }; }; },{"./gsmsplitter":1,"./gsmvalidator":2,"./unicodesplitter":4}],4:[function(require,module,exports){ function isHighSurrogate(code) { return code >= 0xD800 && code <= 0xDBFF; } module.exports.split = function (message, options) { options = options || { summary: false }; if (message === '') { return { parts: [{ content: options.summary ? undefined : '', length: 0, bytes: 0 }], totalLength: 0, totalBytes: 0 }; } var messages = []; var length = 0; var bytes = 0; var totalBytes = 0; var totalLength = 0; var partStart = 0; function bank(partEnd) { var msg = { content: options.summary ? undefined : (partEnd ? message.substring(partStart, partEnd + 1) : message.substring(partStart)), length: length, bytes: bytes }; messages.push(msg); partStart = partEnd + 1; totalLength += length; length = 0; totalBytes += bytes; bytes = 0; } for (var i = 0, count = message.length; i < count; i++) { var code = message.charCodeAt(i); var highSurrogate = isHighSurrogate(code); if (highSurrogate) { if (bytes === 132) bank(i - 1); bytes += 2; i++; } bytes += 2; length++; if (bytes === 134) bank(i); } if (bytes > 0) bank(); if (messages[1] && totalBytes <= 140) { return { parts: [{ content: options.summary ? undefined : message, length: totalLength, bytes: totalBytes }], totalLength: totalLength, totalBytes: totalBytes }; } return { parts: messages, totalLength: totalLength, totalBytes: totalBytes }; }; },{}]},{},[3])(3) });