From a2475dc8f6b0c05dd23780319a302f49b4c20e9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D0=BB=D0=B8=D0=B2=D0=B0=D0=BD=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=92=D0=B0=D1=81=D0=B8=D0=BB=D0=B8=D0=B9?= Date: Wed, 20 Jan 2016 16:43:23 +0300 Subject: [PATCH 01/16] exclude node_modules/, test/ --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index f356293..e937057 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,6 @@ logs results npm-debug.log + +node_modules/ +test/ \ No newline at end of file From 6e8d53797f90a4a3376272ae35666fd77b02469d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D0=BB=D0=B8=D0=B2=D0=B0=D0=BD=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=92=D0=B0=D1=81=D0=B8=D0=BB=D0=B8=D0=B9?= Date: Wed, 20 Jan 2016 17:10:12 +0300 Subject: [PATCH 02/16] use signature-based authentication --- lib/expedia.js | 33 ++++++++++++++++----------------- package.json | 5 +++-- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/lib/expedia.js b/lib/expedia.js index d4c3e65..69c8e4f 100644 --- a/lib/expedia.js +++ b/lib/expedia.js @@ -7,39 +7,38 @@ var querystring = require('querystring'); var parser = require('jstoxml'); var request = require('request'); var color = require('cli-color'); +var crypto = require('crypto'); +var _ = require('lodash'); module.exports = function (options, sendAsREST) { - + // development and production ean endpoints var generalBaseUrl = "http://api.ean.com/ean-services/rs/hotel/v3/"; var bookingBaseUrl = "https://book.api.ean.com/ean-services/rs/hotel/v3/"; var sendAsREST = sendAsREST || false; + var secret = options.secret || null; var defaults = { - cid : null, - apiKey : null, - locale : "en_US", - currencyCode :"USD" + cid: null, + apiKey: null, + locale: "en_US", + currencyCode: "USD" }; - options = _extend(defaults, options); + options = _.assign(defaults, _.omit(options, 'secret')); if(options.apiKey === null) throw new Error("Api Key is required"); if(options.cid === null) throw new Error("CID is required"); if(options.cid == 55505) console.log(color.red.bold.underline("|WARNING|") + color.red.bold(" CID 55505 is for development only, for production you must use another value")); + if (options.secret === null) { throw new Error('Secret is required'); } + // add a callable endpoint to help us build the URL var endpoint = function (endpoint, type){ - var baseUrl = (type == "booking") ? bookingBaseUrl : generalBaseUrl; - return baseUrl + endpoint + "?" + querystring.stringify(options) + "&"; - }; + var baseUrl = (type == "booking") ? bookingBaseUrl : generalBaseUrl, + timestamp = Math.floor(Date.now() / 1000), + sig = '&sig=' + crypto.createHash('md5').update(options.apiKey + secret + timestamp).digest('hex'); - // Simple extend for our defaults - function _extend(settings1,settings2){ - var newSettings = {}; - for (var name in settings1) { newSettings[name] = settings1[name]; } - for (var name in settings2) { newSettings[name] = settings2[name]; } - - return newSettings; - } + return baseUrl + endpoint + "?" + querystring.stringify(options) + sig + '&'; + }; // Normalize nested json to xml and then querystring it function _normalizeParameters(parameters, request){ diff --git a/package.json b/package.json index e9c3e94..52fd9a7 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,9 @@ "license": "WTFPL", "dependencies": { "cli-color": "~0.2.2", - "request": "~2.27.0", - "jstoxml": "~0.2.2" + "jstoxml": "~0.2.2", + "lodash": "^4.0.0", + "request": "~2.27.0" }, "engines": { "node": "*" From 18c6469283728fbad37b298e326e5fcd7edf27a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D0=BB=D0=B8=D0=B2=D0=B0=D0=BD=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=92=D0=B0=D1=81=D0=B8=D0=BB=D0=B8=D0=B9?= Date: Wed, 20 Jan 2016 17:26:02 +0300 Subject: [PATCH 03/16] use REST only --- lib/expedia.js | 30 ++++-------------------------- package.json | 1 - 2 files changed, 4 insertions(+), 27 deletions(-) diff --git a/lib/expedia.js b/lib/expedia.js index 69c8e4f..7a00487 100644 --- a/lib/expedia.js +++ b/lib/expedia.js @@ -4,18 +4,16 @@ **/ var querystring = require('querystring'); -var parser = require('jstoxml'); var request = require('request'); var color = require('cli-color'); var crypto = require('crypto'); var _ = require('lodash'); -module.exports = function (options, sendAsREST) { +module.exports = function (options) { // development and production ean endpoints var generalBaseUrl = "http://api.ean.com/ean-services/rs/hotel/v3/"; var bookingBaseUrl = "https://book.api.ean.com/ean-services/rs/hotel/v3/"; - var sendAsREST = sendAsREST || false; var secret = options.secret || null; var defaults = { cid: null, @@ -40,32 +38,12 @@ module.exports = function (options, sendAsREST) { return baseUrl + endpoint + "?" + querystring.stringify(options) + sig + '&'; }; - // Normalize nested json to xml and then querystring it - function _normalizeParameters(parameters, request){ - if(typeof parameters !== 'object'){ + function _normalizeParameters(parameters) { + if (typeof parameters !== 'object') { throw new Error("Parameters must be passed in as an object"); } - // Extract customer from request object - var customer = { - customerSessionId : parameters.customerSessionId, - customerIpAddress : parameters.customerIpAddress, - customerUserAgent : parameters.customerUserAgent - }; - delete(parameters.customerSessionId); - delete(parameters.customerIpAddress); - delete(parameters.customerUserAgent); - - customer = querystring.stringify(customer); - - var paramsAsString = customer +"&json&"; - if (sendAsREST){ - paramsAsString += querystring.stringify(parameters); - } - else { - paramsAsString += querystring.stringify({"xml" : parser.toXML(parameters)}); - } - return paramsAsString; + return querystring.stringify(parameters); } // Check to make sure default parameters are set diff --git a/package.json b/package.json index 52fd9a7..d728ef3 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,6 @@ "license": "WTFPL", "dependencies": { "cli-color": "~0.2.2", - "jstoxml": "~0.2.2", "lodash": "^4.0.0", "request": "~2.27.0" }, From 2564a88f5be2abb7202c07813178bf5363b91ce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D0=BB=D0=B8=D0=B2=D0=B0=D0=BD=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=92=D0=B0=D1=81=D0=B8=D0=BB=D0=B8=D0=B9?= Date: Wed, 20 Jan 2016 18:27:25 +0300 Subject: [PATCH 04/16] fix --- README.md | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 24c7bf0..5caf164 100644 --- a/README.md +++ b/README.md @@ -26,17 +26,16 @@ Install with npm: Usage requires an Expedia Api key and CID. For development use you can use the CID 55505. You can obtain your api key from the [Expedia EAN api documentation](http://developer.ean.com/). ```javascript - var options = { - cid : "YOUR CID", - apiKey : "YOUR EAN API KEY", - locale : "en_US", // optional defaults to en_US - currencyCode :"USD" // optional defaults to USD +var options = { + cid: 'YOUR CID', + apiKey: 'YOUR EAN API KEY', + secret: 'YOUR SECRET', + locale: 'en_US', // optional defaults to en_US + currencyCode: 'USD' // optional defaults to USD }; -var expedia = require("expedia")(options, sendAsREST); +var expedia = require("expedia")(options); ``` -sendAsREST parameter allows you to choose if you want to send your data in XML or REST format (forgetting the param sets format to XML). -Note that usage of XML is going to be deprecated by Expedia. ## Usage @@ -44,17 +43,17 @@ Expedia requires that you pass in a customer ip, unique session identifier, and ```javascript var options = { - "customerSessionId" : "thisisauniqueID", - "customerIpAddress" : "127.0.0.1", - "customerUserAgent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", - "LocationInfoRequest": { - "locale": "en_US", - "destinationString": "Seattle, WA" - } + customerSessionId: 'thisisauniqueID', + customerIpAddress: '127.0.0.1', + customerUserAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)', + city: 'Bellevue', + stateProvinceCode: 'WA', + countryCode: 'US', + postalCode: '98004' }; -expedia.geoSearch(options, function(err, res){ - if(err)throw new Error(err); +expedia.geoSearch(options, function(err, res) { + if (err) { throw new Error(err); } console.log(res); }); ``` From 9faef77f58a4523c297fe1ee047f72607a42558d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D0=BB=D0=B8=D0=B2=D0=B0=D0=BD=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=92=D0=B0=D1=81=D0=B8=D0=BB=D0=B8=D0=B9?= Date: Fri, 22 Jan 2016 11:57:37 +0300 Subject: [PATCH 05/16] partial promisification --- lib/expedia.js | 38 +++++++++++++++++--------------------- package.json | 3 ++- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/lib/expedia.js b/lib/expedia.js index 7a00487..5ab2f47 100644 --- a/lib/expedia.js +++ b/lib/expedia.js @@ -4,7 +4,7 @@ **/ var querystring = require('querystring'); -var request = require('request'); +var request = require('request-promise'); var color = require('cli-color'); var crypto = require('crypto'); var _ = require('lodash'); @@ -53,39 +53,35 @@ module.exports = function (options) { if(!params.customerUserAgent) throw new Error("Customer user agent string address must be sent in as customerUserAgent"); } - function _handleResponse(response, cb){ + function _handleResponse(response, cb) { var result; - try{ + + try { result = JSON.parse(response); + } catch (error) { + cb({error: 'Error trying to parse response', details: {error: error, response: response}}); } - catch (error){ - cb({error:"Error trying to parse response", details:{error:error, response:response}}); - } - if(result && result.EanWsError){ - cb({error:result.EanWsError.verboseMessage, details:result.EanWsError}); - } - else{ + + if (result && result.EanWsError) { + cb({error: result.EanWsError.verboseMessage, details: result.EanWsError}); + } else { cb(null, result); } } - function _get(method, parameters, cb, type){ + function _get(method, parameters, cb, type) { var url = endpoint(method, type) + _normalizeParameters(parameters); - request.get(url, function (error, response, body) { - if (!error && response.statusCode == 200) { - _handleResponse(body, cb); - } - else if(error){ - cb({error:"http request error", details : error}); - } - else{ - cb({error:"http request error", details :{response : response,body : body}}); - } + + request({ uri: url, json: true }).then(function (response) { + cb(null, response); + }).catch(function (error) { + cb({ error: "http request error", details: error }); }); } function _post(method, parameters, cb, type){ var url = endpoint(method, type) + _normalizeParameters(parameters); + request.post(url, function (error, response, body) { if (!error && response.statusCode == 200) { _handleResponse(body, cb); diff --git a/package.json b/package.json index d728ef3..a557070 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,8 @@ "dependencies": { "cli-color": "~0.2.2", "lodash": "^4.0.0", - "request": "~2.27.0" + "request": "~2.27.0", + "request-promise": "^2.0.0" }, "engines": { "node": "*" From 5d9c79064e3fe054c4db4b9358e0d81cbc57b37f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D0=BB=D0=B8=D0=B2=D0=B0=D0=BD=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=92=D0=B0=D1=81=D0=B8=D0=BB=D0=B8=D0=B9?= Date: Tue, 29 Mar 2016 10:16:18 +0300 Subject: [PATCH 06/16] optional promisify all GET-methods --- lib/expedia.js | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/lib/expedia.js b/lib/expedia.js index 5ab2f47..835a3a5 100644 --- a/lib/expedia.js +++ b/lib/expedia.js @@ -70,13 +70,18 @@ module.exports = function (options) { } function _get(method, parameters, cb, type) { - var url = endpoint(method, type) + _normalizeParameters(parameters); - - request({ uri: url, json: true }).then(function (response) { - cb(null, response); - }).catch(function (error) { - cb({ error: "http request error", details: error }); - }); + var url = endpoint(method, type) + _normalizeParameters(parameters), + fn = request({ uri: url, json: true }); + + if (typeof cb === 'function') { + fn.then(function (response) { + cb(null, response); + }).catch(function (error) { + cb({ error: "http request error", details: error }); + }); + } else { + return fn; + } } function _post(method, parameters, cb, type){ @@ -99,33 +104,33 @@ module.exports = function (options) { // Utility functions ping : function(params, cb){ _checkParameters(params); - _get("ping", params, cb, "general"); + return _get("ping", params, cb, "general"); }, geoSearch : function(params, cb){ _checkParameters(params); - _get("geoSearch", params, cb, "general"); + return _get("geoSearch", params, cb, "general"); }, // Hotel specific methods hotels:{ list : function(params, cb){ _checkParameters(params); - _get("list", params, cb, "general"); + return _get("list", params, cb, "general"); }, info : function(params, cb){ _checkParameters(params); - _get("info", params, cb, "general"); + return _get("info", params, cb, "general"); }, availability : function(params, cb){ _checkParameters(params); - _get("avail", params, cb, "general"); + return _get("avail", params, cb, "general"); }, roomImages : function(params, cb){ _checkParameters(params); - _get("roomImages", params, cb, "general"); + return _get("roomImages", params, cb, "general"); }, acceptedPayments : function(params, cb){ _checkParameters(params); - _get("paymentInfo", params, cb, "general"); + return _get("paymentInfo", params, cb, "general"); } }, // Reservation/Itinerary specific methods @@ -136,11 +141,11 @@ module.exports = function (options) { }, get : function(params, cb){ _checkParameters(params); - _get("itin", params, cb, "general"); + return _get("itin", params, cb, "general"); }, cancel : function(params, cb){ _checkParameters(params); - _get("cancel", params, cb, "general"); + return _get("cancel", params, cb, "general"); } } }; From 31c44d5bc040c24dc6a6eb831603eeae48e37a77 Mon Sep 17 00:00:00 2001 From: Emanuele Tonello Date: Thu, 5 May 2016 10:45:29 +1000 Subject: [PATCH 07/16] beautified --- README.md | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 5caf164..f98777f 100644 --- a/README.md +++ b/README.md @@ -2,28 +2,33 @@ This module is a fork of [expedia](https://www.npmjs.com/package/expedia) module that is not maintained anymore. -## Expedia API +# Expedia API -Small client interface for the [Expedia EAN api](http://developer.ean.com/). Provides an interface for the following methods: -- **Hotel List** Retrieve a list of hotels by location or a list of specific hotel ids -- **Hotel Information** Retrieve detailed information about a hotel from a hotel id -- **Room Availability** Retrieve all available rooms for a specific hotel that accommodate the provided guest count and any other criteria. -- **Room Images** Retrieve a list of room images for a specific hotelId organized by room type -- **Payment Types** Retrieve credit card types compatible with current request settings -- **Book Reservation** Request a reservation for the specified room(s). -- **Itinerary Request** Retrieve an existing itinerary's status and details, confirm the status of a previously requested booking, or retrieve a list of itineraries from a specified date span. -- **Cancel Reservation** Cancel an existing reservation for a single room. -- **Ping Request** Send a ping request to expedia API servers to determine if service is available in the event of a suspected outage or ISP issue, or to obtain EAN's Unix server time when troubleshooting issues with signature authentication. -- **Geo Functions** Obtain location data such as a specific destinationId, latitude/longitude coordinates, and the number of active properties available within the location. +Small client interface for the [Expedia EAN api](http://developer.ean.com/).
+Provides an interface for the following methods: -## Installation +- **Hotel List** Retrieve a list of hotels by location or a list of specific hotel ids +- **Hotel Information** Retrieve detailed information about a hotel from a hotel id +- **Room Availability** Retrieve all available rooms for a specific hotel that accommodate the provided guest count and any other criteria. +- **Room Images** Retrieve a list of room images for a specific hotelId organized by room type +- **Payment Types** Retrieve credit card types compatible with current request settings +- **Book Reservation** Request a reservation for the specified room(s). +- **Itinerary Request** Retrieve an existing itinerary's status and details, confirm the status of a previously requested booking, or retrieve a list of itineraries from a specified date span. +- **Cancel Reservation** Cancel an existing reservation for a single room. +- **Ping Request** Send a ping request to expedia API servers to determine if service is available in the event of a suspected outage or ISP issue, or to obtain EAN's Unix server time when troubleshooting issues with signature authentication. +- **Geo Functions** Obtain location data such as a specific destinationId, latitude/longitude coordinates, and the number of active properties available within the location. -Install with npm: -```npm install yfb-expedia``` +# Installation -## Initialization +Install with npm: -Usage requires an Expedia Api key and CID. For development use you can use the CID 55505. You can obtain your api key from the [Expedia EAN api documentation](http://developer.ean.com/). +``` +npm install node-expedia-api +``` + +# Initialization + +Usage requires an Expedia Api key and CID. For development use you can use the CID 55505\. You can obtain your api key from the [Expedia EAN api documentation](http://developer.ean.com/). ```javascript var options = { @@ -37,9 +42,9 @@ var options = { var expedia = require("expedia")(options); ``` -## Usage +# Usage -Expedia requires that you pass in a customer ip, unique session identifier, and browser agent. The remaining parameters are defined in the [Expedia EAN api documentation](http://developer.ean.com/). Please see the example directory for more options. +Expedia requires that you pass in a customer ip, unique session identifier, and browser agent. The remaining parameters are defined in the [Expedia EAN api documentation](http://developer.ean.com/). Please see the example directory for more options. ```javascript var options = { From 983ec193fb233b39f6de1bda5fe150f54c141bbd Mon Sep 17 00:00:00 2001 From: Emanuele Tonello Date: Thu, 5 May 2016 10:47:06 +1000 Subject: [PATCH 08/16] beautified js files --- examples/geo-search.js | 24 ++++--- examples/hotel-accepted-payments.js | 28 ++++---- examples/hotel-availability.js | 34 ++++++---- examples/hotel-info.js | 24 ++++--- examples/hotel-list.js | 40 ++++++----- examples/hotel-room-images.js | 22 +++--- examples/ping.js | 20 +++--- examples/reservation-book.js | 90 ++++++++++++------------ examples/reservation-cancel.js | 28 ++++---- examples/reservation-get.js | 24 ++++--- lib/expedia.js | 102 +++++++++++++++++----------- 11 files changed, 243 insertions(+), 193 deletions(-) diff --git a/examples/geo-search.js b/examples/geo-search.js index 36adfbf..47c350b 100644 --- a/examples/geo-search.js +++ b/examples/geo-search.js @@ -1,19 +1,21 @@ -var expedia = require("../lib/expedia")({apiKey:"cbrzfta369qwyrm9t5b8y8kf",cid:"55505"}); +var expedia = require("../lib/expedia")({ + apiKey: "cbrzfta369qwyrm9t5b8y8kf", + cid: "55505" +}); // Takes a search string as an argument, and returns location information available for performing a hotel search // a complete list of options is available at http://developer.ean.com/docs/geo-functions/ var options = { - "customerSessionId" : "thisisauniqueID", - "customerIpAddress" : "127.0.0.1", - "customerUserAgent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", - "LocationInfoRequest": { - "locale": "en_US", - "destinationString": "Seattle, WA" - } + "customerSessionId": "thisisauniqueID", + "customerIpAddress": "127.0.0.1", + "customerUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", + "LocationInfoRequest": { + "locale": "en_US", + "destinationString": "Seattle, WA" + } }; -expedia.geoSearch(options, function(err, res){ - if(err)throw new Error(err); +expedia.geoSearch(options, function(err, res) { + if (err) throw new Error(err); console.log(res); }); - diff --git a/examples/hotel-accepted-payments.js b/examples/hotel-accepted-payments.js index da4d3cd..fef8c2f 100644 --- a/examples/hotel-accepted-payments.js +++ b/examples/hotel-accepted-payments.js @@ -1,19 +1,21 @@ -var expedia = require("../lib/expedia")({apiKey:"cbrzfta369qwyrm9t5b8y8kf",cid:"55505"}); +var expedia = require("../lib/expedia")({ + apiKey: "cbrzfta369qwyrm9t5b8y8kf", + cid: "55505" +}); -// a complete list of options is available at http://developer.ean.com/docs/payment-types/ +// a complete list of options is available at http://developer.ean.com/docs/payment-types/ var options = { - "customerSessionId" : "thisisauniqueID", - "customerIpAddress" : "127.0.0.1", - "customerUserAgent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", - "HotelPaymentRequest": { - "hotelId": "122212", - "supplierType": "E", - "rateType": "MerchantStandard" - } + "customerSessionId": "thisisauniqueID", + "customerIpAddress": "127.0.0.1", + "customerUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", + "HotelPaymentRequest": { + "hotelId": "122212", + "supplierType": "E", + "rateType": "MerchantStandard" + } }; -expedia.hotels.acceptedPayments(options, function(err, res){ - if(err)throw new Error(err); +expedia.hotels.acceptedPayments(options, function(err, res) { + if (err) throw new Error(err); console.log(res); }); - diff --git a/examples/hotel-availability.js b/examples/hotel-availability.js index 6279ca8..8c108b2 100644 --- a/examples/hotel-availability.js +++ b/examples/hotel-availability.js @@ -1,23 +1,27 @@ -var expedia = require("../lib/expedia")({apiKey:"cbrzfta369qwyrm9t5b8y8kf",cid:"55505"}); +var expedia = require("../lib/expedia")({ + apiKey: "cbrzfta369qwyrm9t5b8y8kf", + cid: "55505" +}); // a complete list of options is available at http://developer.ean.com/docs/room-avail/ var options = { - "customerSessionId" : "thisisauniqueID", - "customerIpAddress" : "127.0.0.1", - "customerUserAgent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", - "HotelRoomAvailabilityRequest": { - "hotelId": "106347", - "arrivalDate": "9/30/2013", - "departureDate": "10/2/2013", - "includeDetails": "true", - "RoomGroup": { - "Room": { "numberOfAdults": "2" } + "customerSessionId": "thisisauniqueID", + "customerIpAddress": "127.0.0.1", + "customerUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", + "HotelRoomAvailabilityRequest": { + "hotelId": "106347", + "arrivalDate": "9/30/2013", + "departureDate": "10/2/2013", + "includeDetails": "true", + "RoomGroup": { + "Room": { + "numberOfAdults": "2" + } + } } - } }; -expedia.hotels.availability(options, function(err, res){ - if(err)throw new Error(err); +expedia.hotels.availability(options, function(err, res) { + if (err) throw new Error(err); console.log(res); }); - diff --git a/examples/hotel-info.js b/examples/hotel-info.js index ac89454..41ff620 100644 --- a/examples/hotel-info.js +++ b/examples/hotel-info.js @@ -1,18 +1,20 @@ -var expedia = require("../lib/expedia")({apiKey:"cbrzfta369qwyrm9t5b8y8kf",cid:"55505"}); +var expedia = require("../lib/expedia")({ + apiKey: "cbrzfta369qwyrm9t5b8y8kf", + cid: "55505" +}); // a complete list of options is available at http://developer.ean.com/docs/hotel-info/ var options = { - "customerSessionId" : "thisisauniqueID", - "customerIpAddress" : "127.0.0.1", - "customerUserAgent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", - "HotelInformationRequest": { - "hotelId": "122212", - "options": "0" - } + "customerSessionId": "thisisauniqueID", + "customerIpAddress": "127.0.0.1", + "customerUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", + "HotelInformationRequest": { + "hotelId": "122212", + "options": "0" + } }; -expedia.hotels.info(options, function(err, res){ - if(err)throw new Error(err); +expedia.hotels.info(options, function(err, res) { + if (err) throw new Error(err); console.log(res); }); - diff --git a/examples/hotel-list.js b/examples/hotel-list.js index fd286db..805c0fd 100644 --- a/examples/hotel-list.js +++ b/examples/hotel-list.js @@ -1,25 +1,29 @@ -var expedia = require("../lib/expedia")({apiKey:"cbrzfta369qwyrm9t5b8y8kf",cid:"55505"}); +var expedia = require("../lib/expedia")({ + apiKey: "cbrzfta369qwyrm9t5b8y8kf", + cid: "55505" +}); // a complete list of options is available at http://developer.ean.com/docs/hotel-list/ var options = { - "customerSessionId" : "thisisauniqueID", - "customerIpAddress" : "127.0.0.1", - "customerUserAgent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", - "HotelListRequest": { - "city": "Seattle", - "stateProvinceCode": "WA", - "countryCode": "US", - "arrivalDate": "9/30/2013", - "departureDate": "10/2/2013", - "RoomGroup": { - "Room": { "numberOfAdults": "2" } - }, - "numberOfResults": "25" - } + "customerSessionId": "thisisauniqueID", + "customerIpAddress": "127.0.0.1", + "customerUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", + "HotelListRequest": { + "city": "Seattle", + "stateProvinceCode": "WA", + "countryCode": "US", + "arrivalDate": "9/30/2013", + "departureDate": "10/2/2013", + "RoomGroup": { + "Room": { + "numberOfAdults": "2" + } + }, + "numberOfResults": "25" + } } -expedia.hotels.list(options, function(err, res){ - if(err)throw new Error(err); +expedia.hotels.list(options, function(err, res) { + if (err) throw new Error(err); console.log(res); }); - diff --git a/examples/hotel-room-images.js b/examples/hotel-room-images.js index 99fd924..3ff8450 100644 --- a/examples/hotel-room-images.js +++ b/examples/hotel-room-images.js @@ -1,17 +1,19 @@ -var expedia = require("../lib/expedia")({apiKey:"cbrzfta369qwyrm9t5b8y8kf",cid:"55505"}); +var expedia = require("../lib/expedia")({ + apiKey: "cbrzfta369qwyrm9t5b8y8kf", + cid: "55505" +}); // a complete list of options is available at http://developer.ean.com/docs/room-images/ var options = { - "customerSessionId" : "thisisauniqueID", - "customerIpAddress" : "127.0.0.1", - "customerUserAgent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", - "HotelRoomImagesRequest": { - "hotelId": "106347", - } + "customerSessionId": "thisisauniqueID", + "customerIpAddress": "127.0.0.1", + "customerUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", + "HotelRoomImagesRequest": { + "hotelId": "106347", + } }; -expedia.hotels.roomImages(options, function(err, res){ - if(err)throw new Error(err); +expedia.hotels.roomImages(options, function(err, res) { + if (err) throw new Error(err); console.log(res); }); - diff --git a/examples/ping.js b/examples/ping.js index 6b1251c..e91f287 100644 --- a/examples/ping.js +++ b/examples/ping.js @@ -1,15 +1,19 @@ -var expedia = require("../lib/expedia")({apiKey:"cbrzfta369qwyrm9t5b8y8kf",cid:"55505"}); +var expedia = require("../lib/expedia")({ + apiKey: "cbrzfta369qwyrm9t5b8y8kf", + cid: "55505" +}); // Simple echo server, response should match input var options = { - "customerSessionId" : "thisisauniqueID", - "customerIpAddress" : "127.0.0.1", - "customerUserAgent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", - "PingRequest": { "echo": "This message should be echoed back to you." } + "customerSessionId": "thisisauniqueID", + "customerIpAddress": "127.0.0.1", + "customerUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", + "PingRequest": { + "echo": "This message should be echoed back to you." + } }; -expedia.ping(options, function(err, res){ - if(err)throw new Error(err); +expedia.ping(options, function(err, res) { + if (err) throw new Error(err); console.log(res); }); - diff --git a/examples/reservation-book.js b/examples/reservation-book.js index 279bf7e..8764af7 100644 --- a/examples/reservation-book.js +++ b/examples/reservation-book.js @@ -1,52 +1,54 @@ -var expedia = require("../lib/expedia")({apiKey:"cbrzfta369qwyrm9t5b8y8kf",cid:"55505"}); +var expedia = require("../lib/expedia")({ + apiKey: "cbrzfta369qwyrm9t5b8y8kf", + cid: "55505" +}); // a complete list of options is available at http://developer.ean.com/docs/book-reservation/ var options = { - "customerSessionId" : "thisisauniqueID", - "customerIpAddress" : "127.0.0.1", - "customerUserAgent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", - "HotelRoomReservationRequest": { - "hotelId": "106347", - "arrivalDate": "9/30/2013", - "departureDate": "10/2/2013", - "supplierType": "E", - "rateKey": "af00b688-acf4-409e-8bdc-fcfc3d1cb80c", - "roomTypeCode": "198058", - "rateCode": "484072", - "chargeableRate": "231.18", - "RoomGroup": { - "Room": { - "numberOfAdults": "2", - "firstName": "test", - "lastName": "tester", - "bedTypeId": "23", - "smokingPreference": "NS" - } - }, - "ReservationInfo": { - "email": "test@travelnow.com", - "firstName": "test", - "lastName": "tester", - "homePhone": "2145370159", - "workPhone": "2145370159", - "creditCardType": "CA", - "creditCardNumber": "5401999999999999", - "creditCardIdentifier": "123", - "creditCardExpirationMonth": "11", - "creditCardExpirationYear": "2015" - }, - "AddressInfo": { - "address1": "travelnow", - "city": "Seattle", - "stateProvinceCode": "WA", - "countryCode": "US", - "postalCode": "98004" + "customerSessionId": "thisisauniqueID", + "customerIpAddress": "127.0.0.1", + "customerUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", + "HotelRoomReservationRequest": { + "hotelId": "106347", + "arrivalDate": "9/30/2013", + "departureDate": "10/2/2013", + "supplierType": "E", + "rateKey": "af00b688-acf4-409e-8bdc-fcfc3d1cb80c", + "roomTypeCode": "198058", + "rateCode": "484072", + "chargeableRate": "231.18", + "RoomGroup": { + "Room": { + "numberOfAdults": "2", + "firstName": "test", + "lastName": "tester", + "bedTypeId": "23", + "smokingPreference": "NS" + } + }, + "ReservationInfo": { + "email": "test@travelnow.com", + "firstName": "test", + "lastName": "tester", + "homePhone": "2145370159", + "workPhone": "2145370159", + "creditCardType": "CA", + "creditCardNumber": "5401999999999999", + "creditCardIdentifier": "123", + "creditCardExpirationMonth": "11", + "creditCardExpirationYear": "2015" + }, + "AddressInfo": { + "address1": "travelnow", + "city": "Seattle", + "stateProvinceCode": "WA", + "countryCode": "US", + "postalCode": "98004" + } } - } }; -expedia.reservation.book(options, function(err, res){ - if(err)throw new Error(err); +expedia.reservation.book(options, function(err, res) { + if (err) throw new Error(err); console.log(res); }); - diff --git a/examples/reservation-cancel.js b/examples/reservation-cancel.js index c099331..79cffd9 100644 --- a/examples/reservation-cancel.js +++ b/examples/reservation-cancel.js @@ -1,20 +1,22 @@ -var expedia = require("../lib/expedia")({apiKey:"cbrzfta369qwyrm9t5b8y8kf",cid:"55505"}); +var expedia = require("../lib/expedia")({ + apiKey: "cbrzfta369qwyrm9t5b8y8kf", + cid: "55505" +}); // a complete list of options is available at http://developer.ean.com/docs/cancel-reservation/ var options = { - "customerSessionId" : "thisisauniqueID", - "customerIpAddress" : "127.0.0.1", - "customerUserAgent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", - "HotelRoomCancellationRequest": { - "itineraryId": "1234", - "email": "test@travelnow.com", - "reason": "COP", - "confirmationNumber": "1234" - } + "customerSessionId": "thisisauniqueID", + "customerIpAddress": "127.0.0.1", + "customerUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", + "HotelRoomCancellationRequest": { + "itineraryId": "1234", + "email": "test@travelnow.com", + "reason": "COP", + "confirmationNumber": "1234" + } }; -expedia.reservation.cancel(options, function(err, res){ - if(err)throw new Error(err); +expedia.reservation.cancel(options, function(err, res) { + if (err) throw new Error(err); console.log(res); }); - diff --git a/examples/reservation-get.js b/examples/reservation-get.js index b375901..249bdcb 100644 --- a/examples/reservation-get.js +++ b/examples/reservation-get.js @@ -1,18 +1,20 @@ -var expedia = require("../lib/expedia")({apiKey:"cbrzfta369qwyrm9t5b8y8kf",cid:"55505"}); +var expedia = require("../lib/expedia")({ + apiKey: "cbrzfta369qwyrm9t5b8y8kf", + cid: "55505" +}); // a complete list of options is available at http://developer.ean.com/docs/request-itinerary/ var options = { - "customerSessionId" : "thisisauniqueID", - "customerIpAddress" : "127.0.0.1", - "customerUserAgent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", - "HotelItineraryRequest": { - "itineraryId": "1234", - "email": "test@travelnow.com" - } + "customerSessionId": "thisisauniqueID", + "customerIpAddress": "127.0.0.1", + "customerUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", + "HotelItineraryRequest": { + "itineraryId": "1234", + "email": "test@travelnow.com" + } }; -expedia.reservation.get(options, function(err, res){ - if(err)throw new Error(err); +expedia.reservation.get(options, function(err, res) { + if (err) throw new Error(err); console.log(res); }); - diff --git a/lib/expedia.js b/lib/expedia.js index 835a3a5..7f32578 100644 --- a/lib/expedia.js +++ b/lib/expedia.js @@ -1,7 +1,7 @@ /** -* Author : Shiem Edelbrock -* License: Released under the WTFPL license - http://sam.zoy.org/wtfpl/ -**/ + * Author : Shiem Edelbrock + * License: Released under the WTFPL license - http://sam.zoy.org/wtfpl/ + **/ var querystring = require('querystring'); var request = require('request-promise'); @@ -9,7 +9,7 @@ var color = require('cli-color'); var crypto = require('crypto'); var _ = require('lodash'); -module.exports = function (options) { +module.exports = function(options) { // development and production ean endpoints var generalBaseUrl = "http://api.ean.com/ean-services/rs/hotel/v3/"; @@ -24,13 +24,15 @@ module.exports = function (options) { options = _.assign(defaults, _.omit(options, 'secret')); - if(options.apiKey === null) throw new Error("Api Key is required"); - if(options.cid === null) throw new Error("CID is required"); - if(options.cid == 55505) console.log(color.red.bold.underline("|WARNING|") + color.red.bold(" CID 55505 is for development only, for production you must use another value")); - if (options.secret === null) { throw new Error('Secret is required'); } + if (options.apiKey === null) throw new Error("Api Key is required"); + if (options.cid === null) throw new Error("CID is required"); + if (options.cid == 55505) console.log(color.red.bold.underline("|WARNING|") + color.red.bold(" CID 55505 is for development only, for production you must use another value")); + if (options.secret === null) { + throw new Error('Secret is required'); + } // add a callable endpoint to help us build the URL - var endpoint = function (endpoint, type){ + var endpoint = function(endpoint, type) { var baseUrl = (type == "booking") ? bookingBaseUrl : generalBaseUrl, timestamp = Math.floor(Date.now() / 1000), sig = '&sig=' + crypto.createHash('md5').update(options.apiKey + secret + timestamp).digest('hex'); @@ -47,10 +49,10 @@ module.exports = function (options) { } // Check to make sure default parameters are set - function _checkParameters(params){ - if(typeof params !== 'object') throw new Error("Parameters must be passed in as an object"); - if(!params.customerIpAddress) throw new Error("Customer ip address must be sent in as customerIpAddress"); - if(!params.customerUserAgent) throw new Error("Customer user agent string address must be sent in as customerUserAgent"); + function _checkParameters(params) { + if (typeof params !== 'object') throw new Error("Parameters must be passed in as an object"); + if (!params.customerIpAddress) throw new Error("Customer ip address must be sent in as customerIpAddress"); + if (!params.customerUserAgent) throw new Error("Customer user agent string address must be sent in as customerUserAgent"); } function _handleResponse(response, cb) { @@ -59,11 +61,20 @@ module.exports = function (options) { try { result = JSON.parse(response); } catch (error) { - cb({error: 'Error trying to parse response', details: {error: error, response: response}}); + cb({ + error: 'Error trying to parse response', + details: { + error: error, + response: response + } + }); } if (result && result.EanWsError) { - cb({error: result.EanWsError.verboseMessage, details: result.EanWsError}); + cb({ + error: result.EanWsError.verboseMessage, + details: result.EanWsError + }); } else { cb(null, result); } @@ -71,79 +82,92 @@ module.exports = function (options) { function _get(method, parameters, cb, type) { var url = endpoint(method, type) + _normalizeParameters(parameters), - fn = request({ uri: url, json: true }); + fn = request({ + uri: url, + json: true + }); if (typeof cb === 'function') { - fn.then(function (response) { + fn.then(function(response) { cb(null, response); - }).catch(function (error) { - cb({ error: "http request error", details: error }); + }).catch(function(error) { + cb({ + error: "http request error", + details: error + }); }); } else { return fn; } } - function _post(method, parameters, cb, type){ + function _post(method, parameters, cb, type) { var url = endpoint(method, type) + _normalizeParameters(parameters); - request.post(url, function (error, response, body) { + request.post(url, function(error, response, body) { if (!error && response.statusCode == 200) { _handleResponse(body, cb); - } - else if(error){ - cb({error:"http request error", details : error}); - } - else{ - cb({error:"http request error", details :{response : response,body : body}}); + } else if (error) { + cb({ + error: "http request error", + details: error + }); + } else { + cb({ + error: "http request error", + details: { + response: response, + body: body + } + }); } }); } return { // Utility functions - ping : function(params, cb){ + ping: function(params, cb) { _checkParameters(params); return _get("ping", params, cb, "general"); }, - geoSearch : function(params, cb){ + geoSearch: function(params, cb) { _checkParameters(params); return _get("geoSearch", params, cb, "general"); }, // Hotel specific methods - hotels:{ - list : function(params, cb){ + hotels: { + list: function(params, cb) { _checkParameters(params); return _get("list", params, cb, "general"); }, - info : function(params, cb){ + info: function(params, cb) { _checkParameters(params); return _get("info", params, cb, "general"); }, - availability : function(params, cb){ + availability: function(params, cb) { _checkParameters(params); return _get("avail", params, cb, "general"); }, - roomImages : function(params, cb){ + roomImages: function(params, cb) { _checkParameters(params); return _get("roomImages", params, cb, "general"); }, - acceptedPayments : function(params, cb){ + acceptedPayments: function(params, cb) { _checkParameters(params); return _get("paymentInfo", params, cb, "general"); } }, // Reservation/Itinerary specific methods - reservation:{ - book : function(params, cb){ + reservation: { + book: function(params, cb) { _checkParameters(params); _post("res", params, cb, "booking"); }, - get : function(params, cb){ + get: function(params, cb) { _checkParameters(params); return _get("itin", params, cb, "general"); }, - cancel : function(params, cb){ + cancel: function(params, cb) { _checkParameters(params); return _get("cancel", params, cb, "general"); } From dd57e0a865130ae85763a7c956c1b59294f81f88 Mon Sep 17 00:00:00 2001 From: Emanuele Tonello Date: Thu, 5 May 2016 10:47:35 +1000 Subject: [PATCH 09/16] changed package name to node-expedia-api and bump up dependencies --- package.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index a557070..730afa4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "yfb-expedia", - "version": "1.0.1", + "name": "node-expedia-api", + "version": "1.0.5", "description": "simple wrapper around the expedia EAN api", "main": "lib/expedia.js", "repository": { @@ -12,10 +12,10 @@ "contributors": "Shiem Edelbrock", "license": "WTFPL", "dependencies": { - "cli-color": "~0.2.2", - "lodash": "^4.0.0", - "request": "~2.27.0", - "request-promise": "^2.0.0" + "cli-color": "^1.1.0", + "lodash": "^4.11.2", + "request": "~2.72.0", + "request-promise": "^3.0.0" }, "engines": { "node": "*" From e8c2f50fdca6c2080323fceebcf67142b3d4abbd Mon Sep 17 00:00:00 2001 From: Emanuele Tonello Date: Thu, 5 May 2016 10:54:58 +1000 Subject: [PATCH 10/16] updated repo url pointings --- README.md | 2 +- package.json | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f98777f..9b16178 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Provides an interface for the following methods: Install with npm: ``` -npm install node-expedia-api +npm install --save node-expedia-api ``` # Initialization diff --git a/package.json b/package.json index 730afa4..c7a8ae0 100644 --- a/package.json +++ b/package.json @@ -5,11 +5,11 @@ "main": "lib/expedia.js", "repository": { "type": "git", - "url": "https://github.com/chris-verclytte/node-expedia-api.git" + "url": "https://github.com/startsat60/node-expedia-api.git.git" }, - "url": "https://github.com/chris-verclytte/node-expedia-api", + "url": "https://github.com/startsat60/node-expedia-api", "author": "Christophe Verclytte ", - "contributors": "Shiem Edelbrock", + "contributors": "Shiem Edelbrock, Emanuele Tonello", "license": "WTFPL", "dependencies": { "cli-color": "^1.1.0", From 88de6cc981293fb052355a9f1632bfbb9c43c050 Mon Sep 17 00:00:00 2001 From: Emanuele Tonello Date: Thu, 5 May 2016 11:01:29 +1000 Subject: [PATCH 11/16] package published on npm --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9b16178..33f2daa 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![NPM](https://nodei.co/npm/yfb-expedia.png)](https://nodei.co/npm/yfb-expedia/) +[![NPM](https://nodei.co/npm/node-expedia-api.png)](https://nodei.co/npm/node-expedia-api/) This module is a fork of [expedia](https://www.npmjs.com/package/expedia) module that is not maintained anymore. From 865ff92c0ac858cadaf0a5d72e2800bec8b117cc Mon Sep 17 00:00:00 2001 From: Emanuele Tonello Date: Thu, 5 May 2016 13:28:28 +1000 Subject: [PATCH 12/16] removed unused request package --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index c7a8ae0..5d9f567 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,6 @@ "dependencies": { "cli-color": "^1.1.0", "lodash": "^4.11.2", - "request": "~2.72.0", "request-promise": "^3.0.0" }, "engines": { From 1db03c28f1a61ef5d303053ec8f45a7b8f642298 Mon Sep 17 00:00:00 2001 From: Kirill Kozak Date: Mon, 26 Dec 2016 22:41:01 +0200 Subject: [PATCH 13/16] fixed the examples --- examples/geo-search.js | 6 +-- examples/hotel-accepted-payments.js | 8 ++-- examples/hotel-availability.js | 16 +++---- examples/hotel-info.js | 6 +-- examples/hotel-list.js | 24 +++++------ examples/reservation-book.js | 66 ++++++++++++++--------------- examples/reservation-cancel.js | 10 ++--- examples/reservation-get.js | 6 +-- 8 files changed, 63 insertions(+), 79 deletions(-) diff --git a/examples/geo-search.js b/examples/geo-search.js index 47c350b..d55c8cd 100644 --- a/examples/geo-search.js +++ b/examples/geo-search.js @@ -9,10 +9,8 @@ var options = { "customerSessionId": "thisisauniqueID", "customerIpAddress": "127.0.0.1", "customerUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", - "LocationInfoRequest": { - "locale": "en_US", - "destinationString": "Seattle, WA" - } + "locale": "en_US", + "destinationString": "Seattle, WA" }; expedia.geoSearch(options, function(err, res) { diff --git a/examples/hotel-accepted-payments.js b/examples/hotel-accepted-payments.js index fef8c2f..02fd2ea 100644 --- a/examples/hotel-accepted-payments.js +++ b/examples/hotel-accepted-payments.js @@ -8,11 +8,9 @@ var options = { "customerSessionId": "thisisauniqueID", "customerIpAddress": "127.0.0.1", "customerUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", - "HotelPaymentRequest": { - "hotelId": "122212", - "supplierType": "E", - "rateType": "MerchantStandard" - } + "hotelId": "122212", + "supplierType": "E", + "rateType": "MerchantStandard" }; expedia.hotels.acceptedPayments(options, function(err, res) { diff --git a/examples/hotel-availability.js b/examples/hotel-availability.js index 8c108b2..94d9665 100644 --- a/examples/hotel-availability.js +++ b/examples/hotel-availability.js @@ -8,15 +8,13 @@ var options = { "customerSessionId": "thisisauniqueID", "customerIpAddress": "127.0.0.1", "customerUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", - "HotelRoomAvailabilityRequest": { - "hotelId": "106347", - "arrivalDate": "9/30/2013", - "departureDate": "10/2/2013", - "includeDetails": "true", - "RoomGroup": { - "Room": { - "numberOfAdults": "2" - } + "hotelId": "106347", + "arrivalDate": "9/30/2013", + "departureDate": "10/2/2013", + "includeDetails": "true", + "RoomGroup": { + "Room": { + "numberOfAdults": "2" } } }; diff --git a/examples/hotel-info.js b/examples/hotel-info.js index 41ff620..d107f71 100644 --- a/examples/hotel-info.js +++ b/examples/hotel-info.js @@ -8,10 +8,8 @@ var options = { "customerSessionId": "thisisauniqueID", "customerIpAddress": "127.0.0.1", "customerUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", - "HotelInformationRequest": { - "hotelId": "122212", - "options": "0" - } + "hotelId": "122212", + "options": "0" }; expedia.hotels.info(options, function(err, res) { diff --git a/examples/hotel-list.js b/examples/hotel-list.js index 805c0fd..4fa0fe0 100644 --- a/examples/hotel-list.js +++ b/examples/hotel-list.js @@ -8,19 +8,17 @@ var options = { "customerSessionId": "thisisauniqueID", "customerIpAddress": "127.0.0.1", "customerUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", - "HotelListRequest": { - "city": "Seattle", - "stateProvinceCode": "WA", - "countryCode": "US", - "arrivalDate": "9/30/2013", - "departureDate": "10/2/2013", - "RoomGroup": { - "Room": { - "numberOfAdults": "2" - } - }, - "numberOfResults": "25" - } + "city": "Seattle", + "stateProvinceCode": "WA", + "countryCode": "US", + "arrivalDate": "9/30/2013", + "departureDate": "10/2/2013", + "RoomGroup": { + "Room": { + "numberOfAdults": "2" + } + }, + "numberOfResults": "25" } expedia.hotels.list(options, function(err, res) { diff --git a/examples/reservation-book.js b/examples/reservation-book.js index 8764af7..3ffe43d 100644 --- a/examples/reservation-book.js +++ b/examples/reservation-book.js @@ -8,43 +8,41 @@ var options = { "customerSessionId": "thisisauniqueID", "customerIpAddress": "127.0.0.1", "customerUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", - "HotelRoomReservationRequest": { - "hotelId": "106347", - "arrivalDate": "9/30/2013", - "departureDate": "10/2/2013", - "supplierType": "E", - "rateKey": "af00b688-acf4-409e-8bdc-fcfc3d1cb80c", - "roomTypeCode": "198058", - "rateCode": "484072", - "chargeableRate": "231.18", - "RoomGroup": { - "Room": { - "numberOfAdults": "2", - "firstName": "test", - "lastName": "tester", - "bedTypeId": "23", - "smokingPreference": "NS" - } - }, - "ReservationInfo": { - "email": "test@travelnow.com", + "hotelId": "106347", + "arrivalDate": "9/30/2013", + "departureDate": "10/2/2013", + "supplierType": "E", + "rateKey": "af00b688-acf4-409e-8bdc-fcfc3d1cb80c", + "roomTypeCode": "198058", + "rateCode": "484072", + "chargeableRate": "231.18", + "RoomGroup": { + "Room": { + "numberOfAdults": "2", "firstName": "test", "lastName": "tester", - "homePhone": "2145370159", - "workPhone": "2145370159", - "creditCardType": "CA", - "creditCardNumber": "5401999999999999", - "creditCardIdentifier": "123", - "creditCardExpirationMonth": "11", - "creditCardExpirationYear": "2015" - }, - "AddressInfo": { - "address1": "travelnow", - "city": "Seattle", - "stateProvinceCode": "WA", - "countryCode": "US", - "postalCode": "98004" + "bedTypeId": "23", + "smokingPreference": "NS" } + }, + "ReservationInfo": { + "email": "test@travelnow.com", + "firstName": "test", + "lastName": "tester", + "homePhone": "2145370159", + "workPhone": "2145370159", + "creditCardType": "CA", + "creditCardNumber": "5401999999999999", + "creditCardIdentifier": "123", + "creditCardExpirationMonth": "11", + "creditCardExpirationYear": "2015" + }, + "AddressInfo": { + "address1": "travelnow", + "city": "Seattle", + "stateProvinceCode": "WA", + "countryCode": "US", + "postalCode": "98004" } }; diff --git a/examples/reservation-cancel.js b/examples/reservation-cancel.js index 79cffd9..dcc96af 100644 --- a/examples/reservation-cancel.js +++ b/examples/reservation-cancel.js @@ -8,12 +8,10 @@ var options = { "customerSessionId": "thisisauniqueID", "customerIpAddress": "127.0.0.1", "customerUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", - "HotelRoomCancellationRequest": { - "itineraryId": "1234", - "email": "test@travelnow.com", - "reason": "COP", - "confirmationNumber": "1234" - } + "itineraryId": "1234", + "email": "test@travelnow.com", + "reason": "COP", + "confirmationNumber": "1234" }; expedia.reservation.cancel(options, function(err, res) { diff --git a/examples/reservation-get.js b/examples/reservation-get.js index 249bdcb..2703370 100644 --- a/examples/reservation-get.js +++ b/examples/reservation-get.js @@ -8,10 +8,8 @@ var options = { "customerSessionId": "thisisauniqueID", "customerIpAddress": "127.0.0.1", "customerUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", - "HotelItineraryRequest": { - "itineraryId": "1234", - "email": "test@travelnow.com" - } + "itineraryId": "1234", + "email": "test@travelnow.com" }; expedia.reservation.get(options, function(err, res) { From 973ed86115f3b2e80acd4448fa68ac609e3a9986 Mon Sep 17 00:00:00 2001 From: Kirill Kozak Date: Wed, 4 Jan 2017 17:45:37 +0200 Subject: [PATCH 14/16] fix post requests --- lib/expedia.js | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/lib/expedia.js b/lib/expedia.js index 7f32578..d986d2a 100644 --- a/lib/expedia.js +++ b/lib/expedia.js @@ -59,7 +59,7 @@ module.exports = function(options) { var result; try { - result = JSON.parse(response); + result = response.HotelRoomReservationResponse; } catch (error) { cb({ error: 'Error trying to parse response', @@ -69,8 +69,8 @@ module.exports = function(options) { } }); } - - if (result && result.EanWsError) { + + if (result && result.EanWsError) { cb({ error: result.EanWsError.verboseMessage, details: result.EanWsError @@ -101,27 +101,23 @@ module.exports = function(options) { } } - function _post(method, parameters, cb, type) { - var url = endpoint(method, type) + _normalizeParameters(parameters); + function _post(method, parameters, cb, type) { + var url = endpoint(method, type); - request.post(url, function(error, response, body) { - if (!error && response.statusCode == 200) { - _handleResponse(body, cb); - } else if (error) { - cb({ - error: "http request error", - details: error - }); - } else { - cb({ - error: "http request error", - details: { - response: response, - body: body - } - }); - } - }); + var body = _.assign(options, parameters); + + var fn = request({ + method: 'POST', + uri: url, + json: true, + body: _normalizeParameters(body), + headers: { + 'content-type': 'application/x-www-form-urlencoded' // Set automatically + } + }); + + fn.then(body => _handleResponse(body, cb)) + .catch(err => err); } return { From ad021dc606b013591cd860b08e3b80c506779d44 Mon Sep 17 00:00:00 2001 From: Kirill Kozak Date: Wed, 4 Jan 2017 17:46:34 +0200 Subject: [PATCH 15/16] fix reservation-book request --- examples/reservation-book.js | 38 ++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/examples/reservation-book.js b/examples/reservation-book.js index 3ffe43d..2c3b268 100644 --- a/examples/reservation-book.js +++ b/examples/reservation-book.js @@ -5,27 +5,27 @@ var expedia = require("../lib/expedia")({ // a complete list of options is available at http://developer.ean.com/docs/book-reservation/ var options = { - "customerSessionId": "thisisauniqueID", - "customerIpAddress": "127.0.0.1", + "customerSessionId": "0ABAAC0E-B501-FF91-5952-099A2F397163", + "customerIpAddress": "188.163.105.77", "customerUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)", - "hotelId": "106347", - "arrivalDate": "9/30/2013", - "departureDate": "10/2/2013", + "hotelId": 106347, + "arrivalDate": "02/03/2017", + "departureDate": "02/05/2017", "supplierType": "E", "rateKey": "af00b688-acf4-409e-8bdc-fcfc3d1cb80c", "roomTypeCode": "198058", "rateCode": "484072", "chargeableRate": "231.18", - "RoomGroup": { - "Room": { - "numberOfAdults": "2", - "firstName": "test", - "lastName": "tester", - "bedTypeId": "23", - "smokingPreference": "NS" - } - }, - "ReservationInfo": { + // "RoomGroup": { + // "Room": { + "room1": 2, + "room1firstName": "test", + "room1lastName": "tester", + "room1bedTypeId": "23", + "room1smokingPreference": "NS", + // } + // }, + // "ReservationInfo": { "email": "test@travelnow.com", "firstName": "test", "lastName": "tester", @@ -35,15 +35,15 @@ var options = { "creditCardNumber": "5401999999999999", "creditCardIdentifier": "123", "creditCardExpirationMonth": "11", - "creditCardExpirationYear": "2015" - }, - "AddressInfo": { + "creditCardExpirationYear": "2019", + // }, + // "AddressInfo": { "address1": "travelnow", "city": "Seattle", "stateProvinceCode": "WA", "countryCode": "US", "postalCode": "98004" - } + // } }; expedia.reservation.book(options, function(err, res) { From 84f8bf50d452939b833371b3007b6b022bbea77d Mon Sep 17 00:00:00 2001 From: Kirill Kozak Date: Wed, 4 Jan 2017 18:10:33 +0200 Subject: [PATCH 16/16] fix one more bug & update dependencies --- lib/expedia.js | 62 ++++++++++++++++++++++++++++++++++---------------- package.json | 2 +- 2 files changed, 43 insertions(+), 21 deletions(-) diff --git a/lib/expedia.js b/lib/expedia.js index d986d2a..7ae4107 100644 --- a/lib/expedia.js +++ b/lib/expedia.js @@ -17,6 +17,7 @@ module.exports = function(options) { var secret = options.secret || null; var defaults = { cid: null, + minorRev: "99", apiKey: null, locale: "en_US", currencyCode: "USD" @@ -37,7 +38,7 @@ module.exports = function(options) { timestamp = Math.floor(Date.now() / 1000), sig = '&sig=' + crypto.createHash('md5').update(options.apiKey + secret + timestamp).digest('hex'); - return baseUrl + endpoint + "?" + querystring.stringify(options) + sig + '&'; + return baseUrl + endpoint + "?" + querystring.stringify(options) + sig; }; function _normalizeParameters(parameters) { @@ -55,29 +56,36 @@ module.exports = function(options) { if (!params.customerUserAgent) throw new Error("Customer user agent string address must be sent in as customerUserAgent"); } - function _handleResponse(response, cb) { + function _handleResponse(response) { var result; try { result = response.HotelRoomReservationResponse; - } catch (error) { - cb({ + + if (result && result.EanWsError) { + let error = { + error: result.EanWsError.verboseMessage, + details: result.EanWsError + }; + + return error; + } else { + return result; + } + + } catch (e) { + let error = { error: 'Error trying to parse response', details: { - error: error, + error: e, response: response } - }); - } - - if (result && result.EanWsError) { - cb({ - error: result.EanWsError.verboseMessage, - details: result.EanWsError - }); - } else { - cb(null, result); + }; + + return error; } + + } function _get(method, parameters, cb, type) { @@ -101,7 +109,7 @@ module.exports = function(options) { } } - function _post(method, parameters, cb, type) { + function _post(method, parameters, cb, type) { var url = endpoint(method, type); var body = _.assign(options, parameters); @@ -116,8 +124,18 @@ module.exports = function(options) { } }); - fn.then(body => _handleResponse(body, cb)) - .catch(err => err); + fn + .then(body => { + let response = _handleResponse(body); + + if (response.error) { + cb(response); + } else { + cb(null, response); + } + + }) + .catch(err => err); } return { @@ -130,6 +148,10 @@ module.exports = function(options) { _checkParameters(params); return _get("geoSearch", params, cb, "general"); }, + optionsChange: function(nOpt) { + options = _.assign(options, nOpt); + return options; + }, // Hotel specific methods hotels: { list: function(params, cb) { @@ -156,7 +178,7 @@ module.exports = function(options) { // Reservation/Itinerary specific methods reservation: { book: function(params, cb) { - _checkParameters(params); + //_checkParameters(params); _post("res", params, cb, "booking"); }, get: function(params, cb) { @@ -169,4 +191,4 @@ module.exports = function(options) { } } }; -}; +}; \ No newline at end of file diff --git a/package.json b/package.json index 5d9f567..83549ed 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "dependencies": { "cli-color": "^1.1.0", "lodash": "^4.11.2", - "request-promise": "^3.0.0" + "request-promise": "^4.1.1", }, "engines": { "node": "*"