Skip to content

Commit

Permalink
Merge c9ff8ce into 7120fcf
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronmwhitehead committed Jul 15, 2019
2 parents 7120fcf + c9ff8ce commit 8e36674
Show file tree
Hide file tree
Showing 4 changed files with 492 additions and 0 deletions.
1 change: 1 addition & 0 deletions .travis.yml
@@ -1,4 +1,5 @@
before_script:
- export TZ=America/Chicago
- npm i -g eslint
- eslint .

Expand Down
128 changes: 128 additions & 0 deletions carriers/dhl.js
@@ -0,0 +1,128 @@
const async = require('async');
const request = require('request');
const geography = require('../util/geography');
const moment = require('moment-timezone');
const checkDigit = require('../util/checkDigit');

function DHL(options) {
this.isTrackingNumberValid = function(trackingNumber) {
// remove whitespace
trackingNumber = trackingNumber.replace(/\s/g, '');
trackingNumber = trackingNumber.toUpperCase();

if ([/^93612\d{17}$/, /^92612\d{17}$/, /^94748\d{17}$/, /^93748\d{17}$/, /^92748\d{17}$/].some(regex => regex.test(trackingNumber))) {
return checkDigit(trackingNumber, [3, 1], 10);
}
if (/^420\d{27}$/.test(trackingNumber)) {
return checkDigit(trackingNumber.match(/^420\d{5}(\d{22})$/)[1], [3, 1], 10);
}
if (/^420\d{31}$/.test(trackingNumber)) {
if (checkDigit(trackingNumber.match(/^420\d{9}(\d{22})$/)[1], [3, 1], 10)) {
return true;
} else if (checkDigit(trackingNumber.match(/^420\d{5}(\d{26})$/)[1], [3, 1], 10)) {
return true;
}
}

return false;
};

this.track = function(trackingNumber, callback) {
const req = {
url: `https://api-eu.dhl.com/track/shipments?trackingNumber=${trackingNumber}`,
method: 'GET',
json: true,
headers: {
'DHL-API-Key': `${options.DHL_API_Key}`
},
timeout: 5000
};

async.retry(function(callback) {
request(req, callback);
}, function(err, res) {
const response = res.body;

if (err) {
return callback(err);
//invalid credentials or invalid tracking number
} else if (response.status === 401 || response.status === 404) {
return callback(new Error (response.detail));
}

const results = {
events: []
};

var scanDetails = res.body.shipments[0].events;

scanDetails.forEach(scanDetail => {
scanDetail.address = {
city: scanDetail.location != undefined ? scanDetail.location.address.addressLocality : '',
zip: scanDetail.location != undefined ? scanDetail.location.address.postalCode : ''
}
scanDetail.location = geography.addressToString(scanDetail.address);
});

// Get unqiue array of locations
const locations = Array.from(new Set(scanDetails.map(scanDetail => scanDetail.location)));

// Lookup each location
async.mapLimit(locations, 10, function(location, callback) {
geography.parseLocation(location, options, function(err, address) {
if (err || !address) {
return callback(err, address);
}

address.location = location;

callback(null, address);
});
}, function(err, addresses) {
if (err) {
return callback(err);
}

scanDetails.forEach(scanDetail => {
const address = addresses.find(a => a && a.location === scanDetail.location);
let timezone = 'America/New_York';

if (address && address.timezone) {
timezone = address.timezone;
}

const event = {
address: scanDetail.address,
date: new Date(moment.tz(`${scanDetail.timestamp}`, timezone).format('YYYY-MM-DDTHH:mm:ss')),
description: scanDetail.status
};

if (scanDetail.statusCode === 'transit') {
results.shippedAt = event.date;
}

if (scanDetail.statusCode === 'delivered') {
results.deliveredAt = event.date;
}

// Use the city and state from the parsed address (for scenarios where the city includes the state like "New York, NY")
if (address) {
if (address.city) {
event.address.city = address.city;
}

if (address.state) {
event.address.state = address.state;
}
}

results.events.push(event);
});

callback(null, results);
});
});
}
}

module.exports = DHL;
6 changes: 6 additions & 0 deletions index.js
Expand Up @@ -2,6 +2,7 @@ const NodeGeocoder = require('node-geocoder');
const PitneyBowes = require('./carriers/pitneyBowes');
const FedEx = require('./carriers/fedEx');
const USPS = require('./carriers/usps');
const DHL = require('./carriers/dhl');

const geography = require('./util/geography');

Expand All @@ -24,12 +25,15 @@ function Bloodhound(options) {
const fedEx = new FedEx(options && options.fedEx);
const pitneyBowes = new PitneyBowes(options && options.pitneyBowes);
const usps = new USPS(options && options.usps);
const dhl = new DHL(options && options.dhl);

this.guessCarrier = function(trackingNumber) {
if (fedEx.isTrackingNumberValid(trackingNumber)) {
return 'FedEx';
} else if (usps.isTrackingNumberValid(trackingNumber)) {
return 'USPS';
} else if (dhl.isTrackingNumberValid(trackingNumber)) {
return 'DHL';
} else {
return undefined;
}
Expand Down Expand Up @@ -64,6 +68,8 @@ function Bloodhound(options) {
pitneyBowes.track(trackingNumber, callback);
} else if (carrier === 'usps') {
usps.track(trackingNumber, callback);
} else if (carrier === 'dhl') {
dhl.track(trackingNumber, callback);
} else {
return callback(new Error(`Carrier ${carrier} is not supported.`));
}
Expand Down

0 comments on commit 8e36674

Please sign in to comment.