Skip to content

Swedish national number support #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"singleQuote": true,
"printWidth": 100,
"tabWidth": 2
"tabWidth": 2,
"trailingComma": "none"
}
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ A Google Tag Manager variable template that formats phone numbers to the E.164 s
- Automatic country code prefixing based on ISO 3166 country codes
- Support for 200+ country codes
- Special handling for Lithuanian numbers (8/0 prefix conversion)
- Special handling for Swedish national numbers (0 prefix conversion)

## Features

Expand Down
4 changes: 3 additions & 1 deletion metadata.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
homepage: "https://stape.io/"
homepage: 'https://stape.io/'
versions:
- sha: d88dd5d47b1bd74f3c02e01198946354d40069f9
changeNotes: Fix the Swedish national number bug (leading 0). Add tests. Refactor code.
- sha: 7bd52e81a7d2afcb37f2270558d7c73a832d18f6
changeNotes: Format code.
- sha: 654d908654e8b0fbb8de650fc1837e2569c6f0f1
Expand Down
41 changes: 28 additions & 13 deletions template.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const makeString = require('makeString');

return formatPhoneNumber(data.phoneNumber, data.country);

function formatPhoneNumber(phoneNum, countryCode) {
function formatPhoneNumber(phoneNum, country) {
if (!phoneNum || phoneNum === 'undefined') return undefined;

let phone = makeString(phoneNum);
Expand All @@ -13,9 +13,9 @@ function formatPhoneNumber(phoneNum, countryCode) {
phone = phone.split('(').join('');
phone = phone.split(')').join('');

// Mapping of country codes to their respective area codes
// Mapping of countries to their respective country codes
// prettier-ignore
const areaCodes = {
const countryCodes = {
'ca': '1', 'us': '1', 'kz': '7', 'ru': '7', 'eg': '20', 'za': '27', 'gr': '30', 'nl': '31',
'be': '32', 'fr': '33', 'es': '34', 'hu': '36', 'it': '39', 'ro': '40', 'ch': '41', 'at': '43',
'gb': '44', 'dk': '45', 'se': '46', 'no': '47', 'pl': '48', 'de': '49', 'pe': '51', 'mx': '52',
Expand Down Expand Up @@ -47,26 +47,41 @@ function formatPhoneNumber(phoneNum, countryCode) {
'tm': '993', 'az': '994', 'ge': '995', 'kg': '996', 'uz': '998'
};

countryCode = countryCode ? makeString(countryCode) : 'none';
const countrySpecificTransformation = {
// See: https://www.sent.dm/resources/lt#the-transition-from-8-to-0-what-you-need-to-know
lt: (phone) => {
if (phone[0] === '0' || phone[0] === '8') return phone.substring(1);
},
// Handle Swedish national phone number starting with 0 (but not 0046).
// See: https://dialaxy.com/blogs/sweden-phone-number-format/
se: (phone) => {
if (phone[0] === '0') return phone.substring(1);
}
};

country = country ? makeString(country).toLowerCase() : 'none';

const areaCode = areaCodes[countryCode.toLowerCase()];
const countryCode = countryCodes[country];

if (!areaCode) {
return phone.indexOf('+') === 0 ? phone : '+' + phone;
// Return phone if no area code found for the supplied country code.
if (!countryCode) {
return phone[0] === '+' ? phone : '+' + phone;
}

if (phone.indexOf('+' + areaCode) === 0) {
// If phone starts with +<countryCode>, return phone.
if (phone.indexOf('+' + countryCode) === 0) {
return phone;
}

if (phone.indexOf('00' + areaCode) === 0) {
// If phone start with 00<countryCode>, return phone.
if (phone.indexOf('00' + countryCode) === 0) {
return '+' + phone.substring(2);
}

// See: https://www.sent.dm/resources/LT#the-transition-from-8-to-0-what-you-need-to-know
if (countryCode === 'lt' && (phone[0] === '0' || phone[0] === '8')) {
phone = phone.substring(1);
const transformation = countrySpecificTransformation[country];
if (transformation) {
phone = transformation(phone);
}

return '+' + areaCode + phone;
return '+' + countryCode + phone;
}
81 changes: 57 additions & 24 deletions template.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const makeString = require('makeString');

return formatPhoneNumber(data.phoneNumber, data.country);

function formatPhoneNumber(phoneNum, countryCode) {
function formatPhoneNumber(phoneNum, country) {
if (!phoneNum || phoneNum === 'undefined') return undefined;

let phone = makeString(phoneNum);
Expand All @@ -62,9 +62,9 @@ function formatPhoneNumber(phoneNum, countryCode) {
phone = phone.split('(').join('');
phone = phone.split(')').join('');

// Mapping of country codes to their respective area codes
// Mapping of countries to their respective country codes
// prettier-ignore
const areaCodes = {
const countryCodes = {
'ca': '1', 'us': '1', 'kz': '7', 'ru': '7', 'eg': '20', 'za': '27', 'gr': '30', 'nl': '31',
'be': '32', 'fr': '33', 'es': '34', 'hu': '36', 'it': '39', 'ro': '40', 'ch': '41', 'at': '43',
'gb': '44', 'dk': '45', 'se': '46', 'no': '47', 'pl': '48', 'de': '49', 'pe': '51', 'mx': '52',
Expand Down Expand Up @@ -96,59 +96,74 @@ function formatPhoneNumber(phoneNum, countryCode) {
'tm': '993', 'az': '994', 'ge': '995', 'kg': '996', 'uz': '998'
};

countryCode = countryCode ? makeString(countryCode) : 'none';
const countrySpecificTransformation = {
// See: https://www.sent.dm/resources/lt#the-transition-from-8-to-0-what-you-need-to-know
lt: (phone) => {
if (phone[0] === '0' || phone[0] === '8') return phone.substring(1);
},
// Handle Swedish national phone number starting with 0 (but not 0046).
// See: https://dialaxy.com/blogs/sweden-phone-number-format/
se: (phone) => {
if (phone[0] === '0') return phone.substring(1);
}
};

country = country ? makeString(country).toLowerCase() : 'none';

const areaCode = areaCodes[countryCode.toLowerCase()];
const countryCode = countryCodes[country];

if (!areaCode) {
return phone.indexOf('+') === 0 ? phone : '+' + phone;
// Return phone if no area code found for the supplied country code.
if (!countryCode) {
return phone[0] === '+' ? phone : '+' + phone;
}

if (phone.indexOf('+' + areaCode) === 0) {
// If phone starts with +<countryCode>, return phone.
if (phone.indexOf('+' + countryCode) === 0) {
return phone;
}

if (phone.indexOf('00' + areaCode) === 0) {
// If phone start with 00<countryCode>, return phone.
if (phone.indexOf('00' + countryCode) === 0) {
return '+' + phone.substring(2);
}

// See: https://www.sent.dm/resources/LT#the-transition-from-8-to-0-what-you-need-to-know
if (countryCode === 'lt' && (phone[0] === '0' || phone[0] === '8')) {
phone = phone.substring(1);
const transformation = countrySpecificTransformation[country];
if (transformation) {
phone = transformation(phone);
}

return '+' + areaCode + phone;
return '+' + countryCode + phone;
}


___TESTS___

scenarios:
- name: Phone Number With Specials Characters, Without Added Country Code
- name: Phone Number With Specials Characters, Without Added Country
code: |-
const mockData = {
phoneNumber: '55 (12) 3456-7890',
};

const variableResult = runCode(mockData);
assertThat(variableResult).isEqualTo('+551234567890');
- name: Phone Number Without '+', Without Added Country Code
- name: Phone Number Without '+', Without Added Country
code: |-
const mockData = {
phoneNumber: '551234567890',
};

const variableResult = runCode(mockData);
assertThat(variableResult).isEqualTo('+551234567890');
- name: Phone Number With '+', Without Added Country Code
- name: Phone Number With '+', Without Added Country
code: |-
const mockData = {
phoneNumber: '+551234567890',
};

const variableResult = runCode(mockData);
assertThat(variableResult).isEqualTo('+551234567890');
- name: Phone Number Without '+' and Country Code, With Added Country Code
- name: Phone Number Without '+' and Country Code, With Added Country (Lower case)
code: |-
const mockData = {
phoneNumber: '1234567890',
Expand All @@ -157,7 +172,16 @@ scenarios:

const variableResult = runCode(mockData);
assertThat(variableResult).isEqualTo('+551234567890');
- name: Phone Number With '+' and Country Code, With Added Country Code
- name: Phone Number Without '+' and Country Code, With Added Country (Upper case)
code: |-
const mockData = {
phoneNumber: '1234567890',
country: 'BR'
};

const variableResult = runCode(mockData);
assertThat(variableResult).isEqualTo('+551234567890');
- name: Phone Number With '+' and Country Code, With Added Country
code: |-
const mockData = {
phoneNumber: '+551234567890',
Expand All @@ -166,7 +190,7 @@ scenarios:

const variableResult = runCode(mockData);
assertThat(variableResult).isEqualTo('+551234567890');
- name: Phone Number With '00' and Country Code, With Added Country Code
- name: Phone Number With '00' and Country Code, With Added Country
code: |-
const mockData = {
phoneNumber: '00551234567890',
Expand All @@ -175,8 +199,8 @@ scenarios:

const variableResult = runCode(mockData);
assertThat(variableResult).isEqualTo('+551234567890');
- name: Phone Number Without '+' and Country Code Starting with 0, With Added Country
Code (Lithuanian)
- name: Phone Number Without '+' and Country Code, Starting with 0, With Added Country
(Lithuanian)
code: |-
const mockData = {
phoneNumber: '061234567',
Expand All @@ -185,8 +209,8 @@ scenarios:

const variableResult = runCode(mockData);
assertThat(variableResult).isEqualTo('+37061234567');
- name: Phone Number Without '+' and Country Code Starting with 8, With Added Country
Code (Lithuanian)
- name: Phone Number Without '+' and Country Code, Starting with 8, With Added Country
(Lithuanian)
code: |-
const mockData = {
phoneNumber: '861234567',
Expand All @@ -195,11 +219,20 @@ scenarios:

const variableResult = runCode(mockData);
assertThat(variableResult).isEqualTo('+37061234567');
- name: Phone Number Without '+' and Country Code, Starting with 0, With Added Country
(Swedish)
code: |-
const mockData = {
phoneNumber: '030123456',
country: 'se'
};

const variableResult = runCode(mockData);
assertThat(variableResult).isEqualTo('+4630123456');
setup: ''


___NOTES___

Created on 9/4/2024, 2:44:04 PM