Skip to content

Instantly share code, notes, and snippets.

@nakayuki805
Last active September 16, 2020 02:17
Show Gist options
  • Save nakayuki805/9781696 to your computer and use it in GitHub Desktop.
Save nakayuki805/9781696 to your computer and use it in GitHub Desktop.
User agent parser for node.js
/* global __dirname console exports process require */
// useragent parser for PC,tablet,smartphone,featurephone
/*
usage:
UAparser = require('./useragent');//require this file
result = UAparser('Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/31.0.1650.63 Chrome/31.0.1650.63 Safari/537.36');
console.log(result);
{ device: 'PC',
os: 'Linux',
osVersion: '',
browser: 'Chrome',
browserVersion: '31.0', //only A.B of A.B.C.D
androidDeviceName: '',
androidBuild: '',
cpuType: 'x86_64',
isPC: true,
isSmartphone: false, // including all android
isTablet: false, // iPad only
isAndroidiOS: false,
isFeaturePhone: false,
isJapaneseFeaturePhone: false,
isGlobalFeaturePhone: false,
isGame: false,
isTextBrowser: false,
is64bitversion: true,
isUnixLike: true }
*/
var unknownArr = ['unknown','unknown','unknown','unknown'];
function genericBrowser(UAstr) {
var browserName = 'unknown';
var browserVersion = 'unknown';
if (UAstr.indexOf('Chrome')!==-1) {
browserName = 'Chrome';
browserVersion = (/Chrome\/(\d+\.\d+)/g.exec(UAstr)||unknownArr)[1];
}else if (UAstr.indexOf('Firefox')!==-1) {
browserName = 'Firefox';
browserVersion = (/Firefox\/(\d+\.\d+)/g.exec(UAstr)||unknownArr)[1];
}else if (UAstr.indexOf('Opera')!==-1) {
browserName = 'Opera';
browserVersion = (/Opera[\s\/](\d+\.\d+)/g.exec(UAstr)||unknownArr)[1];
}else if (UAstr.indexOf('Lunascape')!==-1) {
browserName = 'Opera';
browserVersion = (/Lunascape (\d+\.\d+)/g.exec(UAstr)||unknownArr)[1];
}else if (UAstr.indexOf('Firefox')!==-1) {
browserName = 'Konqueror';
browserVersion = (/Konqueror\/(\d+\.\d+)/g.exec(UAstr)||unknownArr)[1];
}else if (UAstr.indexOf('Sleipnir')!==-1) {
browserName = 'Sleipnir';
browserVersion = (/Sleipnir\/(\d+\.\d+)/g.exec(UAstr)||unknownArr)[1];
}else if (UAstr.indexOf('Safari')!==-1) {
browserName = 'Safari';
browserVersion = 'unknown';
}else if (UAstr.indexOf('MSIE')!==-1) {
browserName = 'IE';
browserVersion = (/MSIE (\d+\.\d+);/.exec(UAstr)||unknownArr)[1];
}else if (UAstr.indexOf('Trident/7')!==-1) {
browserName = 'IE';
browserVersion = '11';
}else if (UAstr.indexOf('NetFront')!==-1) {
browserName = 'NetFront';
browserVersion = (/NetFront\/(\d+\.\d+)/g.exec(UAstr)||unknownArr)[1];
}
return [browserName,browserVersion];
}
function detectWindowsOS(UAstr) {
var windowsVer = 'unknown';
if (UAstr.indexOf('Windows 95')!==-1) {
windowsVer = '95';
}else if (UAstr.indexOf('Windows 98')!==-1) {
windowsVer = '98';
}else if (UAstr.indexOf('Windows ME')!==-1) {
windowsVer = 'Me';
}else if (UAstr.indexOf('Windows 2000')!==-1) {
windowsVer = '2000';
}else if (UAstr.indexOf('NT 5.0')!==-1) {
windowsVer = '2000';
}else if (UAstr.indexOf('Windows XP')!==-1) {
windowsVer = 'XP';
}else if (UAstr.indexOf('NT 5.1')!==-1) {
windowsVer = 'XP';
}else if (UAstr.indexOf('NT 6.0')!==-1) {
windowsVer = 'Vista';
}else if (UAstr.indexOf('NT 6.1')!==-1) {
windowsVer = '7';
}else if (UAstr.indexOf('NT 6.2')!==-1) {
windowsVer = '8';
}
return windowsVer;
}
function UAparse(UAstr) {
var ret = {
device:'unknown',//PC/Android/iPhone/iPad/iPod/
os:'unknown',
osVersion:'unknown',
browser:'unknown',
browserVersion:'unknown',
androidDeviceName:'',
androidBuild: '',
cpuType:'unknown',
isPC:false,
isSmartphone:false,//including iPod touch, all android, etc...
isTablet:false,//iPad only
isAndroidiOS:false,
isFeaturePhone:false,
isJapaneseFeaturePhone:false,//docomo,au,softbank,willcom,emobile
isGlobalFeaturePhone:false,
isGame:false,
isTextBrowser:false,
is64bitversion:false,
isUnixLike:false
};
var genericBrowserRet = genericBrowser(UAstr);
ret.browser = genericBrowserRet[0];
ret.browserVersion = genericBrowserRet[1];
//Android
if (UAstr.indexOf('Android')!==-1) {
var deviceNameReg = /Android (\d+\.\d+[^ ^;]*);\s? (.+?) Build\/([^)]+)/;
var deviceNameRet = deviceNameReg.exec(UAstr);
ret.device = 'Android';
ret.os = 'Android';
if (deviceNameRet) {
ret.osVersion = deviceNameRet[1];
ret.androidDeviceName = deviceNameRet[2].split(' ')[deviceNameRet[2].split(' ').length-1];
ret.androidBuild = deviceNameRet[3];
}
if(ret.browser === 'Safari'){
ret.browser = 'Default';
}
ret.isSmartphone = true;
ret.isAndroidiOS = true;
//console.log(ret);
}else if (UAstr.indexOf('iPhone OS')!==-1) {//iPhone & iPod
ret.device = UAstr.indexOf('iPod')!==-1 ? 'iPod' : 'iPhone';
ret.os = 'iOS';
ret.osVersion = (/iPhone OS (\w+){1,3}/g.exec(UAstr)||unknownArr)[1].replace(/_/g,'.');
ret.isSmartphone = true;
//if () {//Chrome
}else if (UAstr.indexOf('iPad')!==-1) {//iPad
ret.device = 'iPad';
ret.os = 'iOS';
ret.osVersion = (/CPU OS (\w+){1,3}/g.exec(UAstr)||unknownArr)[1].replace(/_/g,'.');
ret.isTablet = true;
}else if (UAstr.indexOf('Windows Phone')!==-1) {//Windows phone
ret.device = 'WindowsPhone';
ret.os = 'WindowsPhone';
ret.isSmartphone = true;
//version
}else if (UAstr.indexOf('BlackBerry')!==-1){
ret.device = 'BlackBerry';
ret.os = 'BlackBerry';
//ret.osVersion =
}else if (UAstr.indexOf('Windows')!==-1) {//Windows PC
ret.device = 'PC';
ret.os = 'Windows';
ret.osVersion = detectWindowsOS(UAstr);
ret.isPC = true;
}else if (UAstr.indexOf('Mac OS X')!==-1) {//Mac OS X
ret.device = 'PC';
ret.os = 'MacOSX';
ret.osVersion = (/OS X (\w+){1,3}/g.exec(UAstr)||unknownArr)[1].replace(/_/g,'.');
ret.isPC = true;
ret.isUnixLike = true;
}else if (UAstr.indexOf('Mac')!==-1) {//old Macintosh
ret.device = 'PC';
ret.os = 'Machintosh';
ret.osVersion = 'unknown';
ret.isPC = true;
}else if (UAstr.indexOf('Linux')!==-1) {//Linux
ret.device = 'PC';
ret.os = 'Linux';
ret.osVersion = '';
ret.isPC = true;
ret.isUnixLike = true;
}else if (UAstr.indexOf('BSD')!==-1) {//*BSD
ret.device = 'PC';
ret.os = (/ (\w+BSD)/g.exec(UAstr)||unknownArr)[1];
ret.osVersion = '';
ret.isPC = true;
ret.isUnixLike = true;
}else if (UAstr.indexOf('DoCoMo')!==-1) {//Docomo ktai
ret.device = 'Docomo';
ret.browser = 'imode';
ret.isFeaturePhone = true;
ret.isJapaneseFeaturePhone = true;
}else if (UAstr.indexOf('UP.Browser')!==-1) {//au ktai
ret.device = 'au';
ret.browser = 'EZweb';
ret.isFeaturePhone = true;
ret.isJapaneseFeaturePhone = true;
}else if (UAstr.indexOf('SoftBank')!==-1||UAstr.indexOf('Vodafone')!==-1||UAstr.indexOf('J-PHONE')!==-1) {//Softbank ktai
ret.device = 'Softbank';
ret.browser = 'Y!ktai';
ret.isFeaturePhone = true;
ret.isJapaneseFeaturePhone = true;
}else if (UAstr.indexOf('WILLCOM')!==-1) {//willcom ktai
ret.device = 'Willcom';
ret.browser = 'willcom';
ret.isFeaturePhone = true;
ret.isJapaneseFeaturePhone = true;
}else if (UAstr.indexOf('emobile')!==-1) {//emobile ktai
ret.device = 'Emobile';
ret.browser = 'EMnet';
ret.isFeaturePhone = true;
ret.isJapaneseFeaturePhone = true;
}else if (UAstr.indexOf('Nintendo Wii')!==-1) {//Wii
ret.device = 'Wii';
ret.isGame = true;
}else if (UAstr.indexOf('Nintendo 3DS')!==-1) {//3DS
ret.device = '3DS';
ret.isGame = true;
}else if (UAstr.indexOf('PlayStation Portable')!==-1){//PSP
ret.device = 'PSP';
ret.isGame = true;
}else if (UAstr.indexOf('MIDP')!==-1 || UAstr.indexOf('Nokia')!==-1){// global feature phone
ret.device = 'Phone';
ret.isGlobalFeaturePhone = true;
}else if (UAstr.indexOf('w3m')!==-1){
ret.browserName = 'w3m';
ret.browserVersion = (/w3m\/(\d+\.\d+)/g.exec(UAstr)||unknownArr)[1];
ret.isTextBrowser = true;
}else if (UAstr.indexOf('Lynx')!==-1){
ret.browserName = 'Lynx';
ret.browserVersion = (/Lynx\/(\d+\.\d+\.\d+)/g.exec(UAstr)||unknownArr)[1];
ret.isTextBrowser = true;
}
//CPU type
if (UAstr.indexOf('Win64')!==-1 || UAstr.indexOf('WOW64')!==-1 || UAstr.indexOf('x86_64')!==-1 || UAstr.indexOf('x64')!==-1){
ret.is64bitversion = true;
ret.cpuType = 'x86_64';
}else if (UAstr.indexOf('i686')!==-1 || UAstr.indexOf('x86')!==-1){
ret.cpuType = 'x86';
}else if (UAstr.indexOf('PPC')!==-1 || UAstr.indexOf('PowerPC')!==-1){
ret.cpuType = 'ppc';
}else if (UAstr.toUpperCase().indexOf('ARM')!==-1){
ret.cpuType = 'arm';
}else if(ret.os === 'Windows'){
ret.cpuType = 'x86';
}
return ret;
}
module.exports = UAparse;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment