Socket
Socket
Sign inDemoInstall

ebay-api

Package Overview
Dependencies
Maintainers
1
Versions
74
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ebay-api - npm Package Compare versions

Comparing version 0.1.1 to 1.0.0-alpha

.idea/.name

3

examples/GetOrders.js

@@ -7,3 +7,3 @@ // a basic GetOrders request to the Trading API via XML-POST

ebay.ebayApiPostXmlRequest({
ebay.xmlRequest({
serviceName : 'Trading',

@@ -23,3 +23,2 @@ opType : 'GetOrders',

}
}, function(error, results) {

@@ -26,0 +25,0 @@ if (error) {

@@ -6,3 +6,3 @@ // example of GetSingleItem request to Shopping API.

ebay.ebayApiGetRequest({
ebay.xmlRequest({
'serviceName': 'Shopping',

@@ -9,0 +9,0 @@ 'opType': 'GetSingleItem',

@@ -35,3 +35,3 @@ // example paginated request to FindingService:findItemsAdvanced

ebay.paginateGetRequest({
serviceName: 'FindingService',
serviceName: 'Finding',
opType: 'findItemsAdvanced',

@@ -43,3 +43,3 @@ appId: '......................', // FILL IN YOUR OWN APP KEY, GET ONE HERE: https://publisher.ebaypartnernetwork.com/PublisherToolsAPI

perPage: perPage,
parser: ebay.parseItemsFromResponse
parser: ebay.parseResponse
},

@@ -46,0 +46,0 @@ // gets all the items together in a merged array

// eBay API client for Node.js
var restler = require('restler'),
_ = require('underscore'),
util = require('util'),
async = require('async');
exports.xmlRequest = require('./lib/xml-request').xmlRequest;
exports.paginateGetRequest = require('./lib/pagination').paginateGetRequest;
// [internal] convert params hash to url string.
// some items may be arrays, use key(0)..(n)
// param usage:
// - use null values for plain params
// - use arrays for repeating keys
var buildUrlParams = function buildUrlParams(params) {
var urlFilters = []; // string parts to be joined
// (force each to be string w/ ''+var)
_(params).each(function(value, key) {
if (value === null) urlFilters.push('' + key);
else if (_.isArray(value)) {
_(value).each(function(subValue, subInd) {
urlFilters.push('' + key + '(' + subInd + ')' + "=" + subValue);
});
}
else urlFilters.push( '' + key + "=" + value );
});
return urlFilters.join('&');
};
exports.ItemFilter = require('./lib/filters').ItemFilter;
// [helper] constructor for an 'itemFilter' filter (used by the Finding Service)
module.exports.ItemFilter = function ItemFilter(name, value, paramName, paramValue) {
// required
this.name = name;
this.value = value;
// optional
this.paramName = _.isUndefined(paramName) ? '' : paramName;
this.paramValue = _.isUndefined(paramValue) ? '' : paramValue;
};
// [internal] convert a filters array to a url string
// adapted from client-side JS example in ebay docs
var buildFilters = function buildFilters(filterType, filters) {
var urlFilter = '';
_(filters).each(function eachItemFilter(filter, filterInd) {
// each parameter in each item filter
_(filter).each(function eachItemParam(paramVal, paramKey) {
// Check to see if the paramter has a value (some don't)
if (paramVal !== "") {
// multi-value param
if (_.isArray(paramVal)) {
_(paramVal).each(function eachSubFilter(paramSubVal, paramSubIndex) {
urlFilter += '&' + filterType + '(' + filterInd + ').' + paramKey + '(' + paramSubIndex + ')=' + paramSubVal;
});
}
// single-value param
else {
urlFilter += '&' + filterType + '(' + filterInd + ').' + paramKey + '=' + paramVal;
}
}
});
});
return urlFilter;
};
// build URL to API endpoints
// set sandbox=true for sandbox, otherwise production
// - params is a 1D obj
// - filters is an obj of { filterType:[filters] } (where filters is an array of ItemFilter)
// params,filters only apply to GET requests; for POST pass in empty {} or null
var buildRequestUrl = function buildRequestUrl(serviceName, params, filters, sandbox) {
var url;
params = params || {};
filters = filters || {};
sandbox = (typeof sandbox === 'boolean') ? sandbox : false;
switch (serviceName) {
case 'FindingService':
if (sandbox) {
// url = // @todo
throw new Error("Sandbox endpoing for FindingService not yet implemented. Please add.");
}
else url = "https://svcs.ebay.com/services/search/" + serviceName + "/v1?";
break;
case 'Shopping':
if (sandbox) {
// url = // @todo
throw new Error("Sandbox endpoing for Shopping service not yet implemented. Please add.");
}
else url = "http://open.api.ebay.com/shopping?";
break;
case 'Trading': // ...and the other XML APIs
if (sandbox) url = 'https://api.sandbox.ebay.com/ws/api.dll';
else url = 'https://api.ebay.com/ws/api.dll';
// params and filters don't apply to URLs w/ these
return url;
// break;
default:
if (sandbox) {
// url = // @todo
throw new Error("Sandbox endpoing for " + serviceName + " service not yet implemented. Please add.");
}
else url = "https://svcs.ebay.com/" + serviceName + '?';
}
url += buildUrlParams(params); // no trailing &
_(filters).each(function(typeFilters, type) {
url += buildFilters(type, typeFilters); // each has leading &
});
return url;
};
module.exports.buildRequestUrl = buildRequestUrl;
// build XML input for XML-POST requests
// params should include: authToken, ...
//
// handle nested elements w/ array wrapper around each obj.
// (quirk of XmlBuilder lib)
// e.g. 'Pagination': [ { 'EntriesPerPage': '100' } ]
//
// for repeatable fields, use an array value (see below)
//
var buildXmlInput = function buildXmlInput(opType, params) {
var xmlBuilder = require('xml');
var data = {}, top;
switch(opType) {
// @todo others might have different top levels...
case 'GetOrders':
default:
data[opType + 'Request'] = []; // e.g. <GetOrdersRequest>
top = data[opType + 'Request'];
top.push({ '_attr' : { 'xmlns' : "urn:ebay:apis:eBLBaseComponents" } });
}
if (typeof params.authToken !== 'undefined') {
top.push({ 'RequesterCredentials' : [ { 'eBayAuthToken' : params.authToken } ] });
delete params.authToken;
}
// for repeatable fields, use array values.
// to keep this simpler, treat everything as an array value.
_(params).each(function(values, key) {
if (!_.isArray(values)) values = [values];
_(values).each(function(value){
var el = {};
el[key] = value;
top.push(el);
});
});
// console.log(util.inspect(data,true,10));
data = [ data ];
return '<?xml version="1.0" encoding="UTF-8"?>' + "\n" + xmlBuilder(data, true);
};
// default params per service type.
// for GET requests these go into URL. for POST requests these go into headers.
// options differ by service, see below.
var defaultParams = function defaultParams(options) {
var params = {},
defaultGetParams = {
'OPERATION-NAME': options.opType,
'GLOBAL-ID': 'EBAY-US',
'RESPONSE-DATA-FORMAT': 'JSON',
'REST-PAYLOAD': null // (not sure what this does)
};
options = options || {};
switch (options.serviceName) {
// [GET params >
case 'FindingService':
params = _.extend({}, defaultGetParams, {
'SECURITY-APPNAME': options.appId ? options.appId : null,
'SERVICE-VERSION': '1.11.0'
});
break;
case 'MerchandisingService':
params = _.extend({}, defaultGetParams, {
'SERVICE-NAME': options.serviceName,
'CONSUMER-ID': options.appId ? options.appId : null,
'SERVICE-VERSION': '1.5.0' // based on response data
});
break;
case 'Shopping':
params = _.extend({}, defaultGetParams, {
'appid': options.appId ? options.appId : null,
'version': '771',
'siteid': '0',
'responseencoding': 'JSON',
'callname': options.opType
});
break;
// [POST params >
case 'Trading':
params = {
'X-EBAY-API-CALL-NAME' : options.opType,
'X-EBAY-API-COMPATIBILITY-LEVEL' : '775',
'X-EBAY-API-SITEID' : '0', // US
'X-EBAY-API-DEV-NAME': options.devName,
'X-EBAY-API-CERT-NAME': options.cert,
'X-EBAY-API-APP-NAME': options.appName
};
break;
}
return params;
};
// make a single GET request to a JSON service
var ebayApiGetRequest = function ebayApiGetRequest(options, callback) {
if (! options.serviceName) return callback(new Error("Missing serviceName"));
if (! options.opType) return callback(new Error("Missing opType"));
if (! options.appId) return callback(new Error("Missing appId"));
options.params = options.params || {};
options.filters = options.filters || {};
options.reqOptions = options.reqOptions || {};
options.parser = options.parser || parseItemsFromResponse;
options.sandbox = options.sandbox || false;
options.raw = options.raw || false;
if (options.serviceName === 'MerchandisingService') {
options.reqOptions.decoding = 'buffer'; // otherwise fails to decode json. doesn't seem to be necessary w/ FindingService.
}
// fill in default params. explicit options above will override defaults.
_.defaults(options.params, defaultParams(options));
var url = buildRequestUrl(options.serviceName, options.params, options.filters, options.sandbox);
// console.log('url for', options.opType, 'request:\n', url.replace(/\&/g, '\n&'));
var request = restler.get(url, options.reqOptions);
var data;
// emitted when the request has finished whether it was successful or not
request.on('complete', function(result, response) {
// [restler docs] 'If some error has occurred, result is always instance of Error'
if (result instanceof Error) {
var error = result;
error.message = "Completed with error: " + error.message;
return callback(error);
}
else if (response.statusCode !== 200) {
return callback(new Error(util.format("Bad response status code", response.statusCode, result.toString())));
}
else if (options.raw === true) {
return callback(null, result.toString());
}
try {
data = JSON.parse(result);
// drill down to item(s). each service has its own structure.
if (options.serviceName !== 'Shopping') {
var responseKey = options.opType + 'Response';
if (_.isUndefined(data[responseKey])) {
return callback(new Error("Response missing " + responseKey + " element"));
}
data = data[responseKey];
}
if (_.isArray(data)) {
data = _(data).first();
}
// 'ack' and 'errMsg' indicate errors.
// - in FindingService it's nested, in Merchandising it's flat - flatten to normalize
if (!_.isUndefined(data.ack)) data.ack = flatten(data.ack);
else if (!_.isUndefined(data.Ack)) { // uppercase, standardize.
data.ack = flatten(data.Ack);
delete data.Ack;
}
if (_.isUndefined(data.ack) || data.ack !== 'Success') {
var errMsg = _.isUndefined(data.errorMessage) ? null : flatten(data.errorMessage);
return callback(new Error(util.format("Bad 'ack' code", data.ack, 'errorMessage?', util.inspect(errMsg, true, 3))));
}
}
catch(error) {
return callback(error);
}
// console.log('completed successfully:\n', util.inspect(data, true, 10, true));
// parse the response
options.parser(data, function(error, items) {
callback(error, items);
});
});
// emitted when some errors have occurred
// either this OR 'completed' should fire
request.on('error', function(error, response) {
error.message = "Request error: " + error.message;
callback(error);
});
// emitted when the request was successful
// -- overlaps w/ 'completed', don't use
// request.on('success', function(data, response) {
// });
// emitted when the request was successful, but 4xx status code returned
// -- overlaps w/ 'completed', don't use
// request.on('fail', function(data, response) {
// });
};
module.exports.ebayApiGetRequest = ebayApiGetRequest;
// make a single POST request to an XML service
var ebayApiPostXmlRequest = function ebayApiPostXmlRequest(options, callback) {
if (! options.serviceName) return callback(new Error("Missing serviceName"));
if (! options.opType) return callback(new Error("Missing opType"));
// @see note in buildXmlInput() re: nested elements
options.params = options.params || {};
options.reqOptions = options.reqOptions || {};
options.sandbox = options.sandbox || false;
// options.parser = options.parser || ...; // @todo
// converts XML to JSON by default, but can also return raw XML
options.rawXml = options.rawXml || false;
// app/auth params go into headers (see defaultParams())
options.reqOptions.headers = options.reqOptions.headers || {};
_.defaults(options.reqOptions.headers, defaultParams(options));
// console.dir(options);
var url = buildRequestUrl(options.serviceName, {}, {}, options.sandbox);
// console.log('URL:', url);
options.reqOptions.data = buildXmlInput(options.opType, options.params);
// console.log(options.reqOptions.data);
var request = restler.post(url, options.reqOptions);
request.on('complete', function(result, response) {
if (result instanceof Error) {
var error = result;
error.message = "Completed with error: " + error.message;
return callback(error);
}
else if (response.statusCode !== 200) {
return callback(new Error(util.format("Bad response status code", response.statusCode, result.toString())));
}
// raw XML wanted?
if (options.rawXml) {
return callback(null, result);
}
async.waterfall([
// convert xml to json
function toJson(next) {
var xml2js = require('xml2js'),
parser = new xml2js.Parser();
parser.parseString(result, function parseXmlCallback(error, data) {
if (error) {
error.message = "Error parsing XML: " + error.message;
return next(error);
}
next(null, data);
});
},
function parseData(data, next) {
//// @todo parse the response
// options.parser(data, next);
next(null, data);
}
],
function(error, data){
if (error) return callback(error);
callback(null, data);
});
});
// emitted when some errors have occurred
// either this OR 'completed' should fire
request.on('error', function(error, response) {
error.message = "Request error: " + error.message;
callback(error);
});
};
module.exports.ebayApiPostXmlRequest = ebayApiPostXmlRequest;
// PAGINATE multiple GET/JSON requests in parallel (max 100 per page, 100 pages = 10k items)
var paginateGetRequest = function paginateGetRequest(options, callback) {
if (! options.serviceName) return callback(new Error("Missing serviceName"));
if (! options.opType) return callback(new Error("Missing opType"));
if (! options.appId) return callback(new Error("Missing appId"));
options.params = options.params || {};
options.filters = options.filters || {};
options.reqOptions = options.reqOptions || {};
options.pages = options.pages || 2;
options.perPage = options.perPage || 10;
options.parser = options.parser || parseItemsFromResponse;
console.log('Paginated request to', options.serviceName, 'for', options.pages, 'pages of', options.perPage, 'items each');
var mergedItems = [], // to be merged
pageParams = [],
p;
if (!(_.isNumber(options.pages) && options.pages > 0)) return callback(new Error("Invalid number of pages requested", options.pages));
// index is pageInd-1. can't start array from 1, it just fills in 0 with undefined.
for(p = 0; p < options.pages; p++) {
pageParams[p] = {
'paginationInput.entriesPerPage': options.perPage,
'paginationInput.pageNumber': p+1
};
}
// console.log(pageParams.length, 'pages:', pageParams);
// run pagination requests in parallel
async.forEach(pageParams,
function eachPage(thisPageParams, nextPage) {
// merge the pagination params. new var to avoid confusing scope.
var thisPageOptions = _.extend({}, options);
thisPageOptions.params = _.extend({}, thisPageOptions.params, thisPageParams);
console.log("Requesting page", thisPageOptions.params['paginationInput.pageNumber'], 'with', thisPageOptions.params['paginationInput.entriesPerPage'], 'items...');
ebayApiGetRequest(thisPageOptions, function(error, items) {
// console.log("Got response from page", thisPageOptions.params['paginationInput.pageNumber']);
if (error) {
error.message = "Error on page " + thisPageOptions.params['paginationInput.pageNumber'] + ": " + error.message;
return nextPage(error);
}
if (!_.isArray(items)) {
return nextPage(new Error("Parser did not return an array, returned a " + typeof items));
}
console.log('Got', items.length, 'items from page', thisPageOptions.params['paginationInput.pageNumber']);
// console.log('have', mergedItems.length, 'previous items, adding', items.length, 'new items...');
mergedItems = mergedItems.concat(items);
// console.log('now have', mergedItems.length, 'merged items');
nextPage(null);
});
},
function pagesDone(error) {
// console.log('pages are done');
if (error) callback(error);
else callback(null, mergedItems);
}
); //forEach
};
module.exports.paginateGetRequest = paginateGetRequest;
// helper: RECURSIVELY turn 1-element arrays/objects into flat vars
// (different from _.flatten() which returns an array)
var flatten = function flatten(el, iter) {
// sanity check
if (_.isUndefined(iter)) var iter = 1;
if (iter > 100) {
console.error("recursion error, stop at", iter);
return;
}
// flatten 1-item arrays
if (_.isArray(el) && el.length === 1) {
el = _.first(el);
}
// special value-pair structure in the ebay API: turn { @key:KEY, __value__:VALUE } into { KEY: VALUE }
if (isValuePair(el)) {
var values = _.values(el);
// console.log('found special:', el);
el = {};
el[ values[0] ] = values[1];
// console.log('handled special:', el);
}
// previous fix just creates an array of these. we want a clean key:val obj.
// so, is this an array of special value-pairs?
if (isArrayOfValuePairs(el)) {
var fixEl = {};
_(el).each(function(pair) {
_.extend(fixEl, flatten(pair)); // fix each, combine
});
el = fixEl;
}
// flatten sub-elements
if (_.isArray(el) || _.isObject(el)) {
_.each(el, function(subEl, subInd) {
el[subInd] = flatten(el[subInd], iter++);
});
}
return el;
};
module.exports.flatten = flatten;
// helper: identify a structure returned from the API:
// { @key:KEY, __value__:VALUE } => want to turn into { KEY: VALUE }
// (and array of these into single obj)
var isValuePair = function isValuePair(el) {
if (_.isObject(el) && _.size(el) === 2) {
var keys = _.keys(el);
if (new RegExp(/^@/).test(keys[0]) && keys[1] === '__value__') {
return true;
}
}
return false;
};
// helper: find an array containing only special key-value pairs
// e.g. 'galleryURL' (makes it easier to handle in MongoDB)
var isArrayOfValuePairs = function isArrayOfValuePairs(el) {
if (_.isArray(el)) {
if (_.all(el, isValuePair)) return true;
}
return false;
};
// extract an array of items from responses. differs by query type.
// @todo build this out as more queries are added...
var parseItemsFromResponse = function parseItemsFromResponse(data, callback) {
// console.log('parse data', data);
var items = [];
try {
if (typeof data.Item !== 'undefined') { // e.g. for Shopping::GetSingleItem
items = [ data.Item ]; // preserve array for standardization (?)
}
else if (typeof data.searchResult !== 'undefined') { // e.g. for FindingService
// reduce in steps so successful-but-empty responses don't throw error
if (!_.isEmpty(data.searchResult)) {
data = _(data.searchResult).first();
if (typeof data !== 'undefined') {
if (typeof data.item !== 'undefined') {
items = data.item;
}
}
}
}
else if (typeof data.itemRecommendations !== 'undefined') {
if (typeof data.itemRecommendations !== 'undefined') {
if (typeof data.itemRecommendations.item !== 'undefined') {
items = _.isArray(data.itemRecommendations.item) ? data.itemRecommendations.item : [];
}
}
}
// recursively flatten 1-level arrays and "@key:__VALUE__" pairs
items = _(items).map(function(item) {
return flatten(item);
});
}
catch(error) {
callback(error);
}
callback(null, items);
};
module.exports.parseItemsFromResponse = parseItemsFromResponse;
// check if an item URL is an affiliate URL
// non-affil URLs look like 'http://www.ebay.com...', affil URLs look like 'http://rover.ebay.com/rover...'
// and have param &campid=TRACKINGID (campid=1234567890)
module.exports.checkAffiliateUrl = function checkAffiliateUrl(url) {
var regexAffil = /http\:\/\/rover\.ebay\.com\/rover/,
regexNonAffil = /http\:\/\/www\.ebay\.com/,
regexCampaign = /campid=[0-9]{5}/;
return (regexAffil.test(url) && !regexNonAffil.test(url) && regexCampaign.test(url));
};
// check the latest API versions (to update the code accordingly)
// callback gets hash of APIs:versions
module.exports.getLatestApiVersions = function getLatestApiVersions(options, callback) {
var versionParser = function versionParser(data, callback) {
callback(null, data.version);
};
var checkVersion = function checkVersion(serviceName, next) {
console.log('checkVersion for', serviceName);
ebayApiGetRequest({
serviceName: serviceName,
opType: 'getVersion',
appId: options.appId,
parser: versionParser
},
next);
};
async.series({
'finding': async.apply(checkVersion, 'FindingService'),
'merchandising': async.apply(checkVersion, 'MerchandisingService'),
// 'shopping': async.apply(checkVersion, 'Shopping'), // doesn't have this call!
// 'trading': async.apply(checkVersion, 'Trading') // doesn't have this call!
// ... which others have it?
},
callback);
};
exports.parseResponse = require('./lib/parser').parseResponse;
{
"name": "ebay-api",
"description": "eBay API Client",
"version": "0.1.1",
"version": "1.0.0-alpha",
"homepage": "https://github.com/newleafdigital/nodejs-ebay-api",

@@ -13,10 +13,18 @@ "author": "Ben Buckman <ben@newleafdigital.com> (http://newleafdigital.com)",

"dependencies": {
"async": "~0.1.22",
"restler": "~2.0.1",
"underscore": "~1.3.3",
"xml": "0.0.7",
"xml2js": "~0.1.14"
"async": "^1.4.2",
"debug": "^2.2.0",
"lodash": "^3.10.1",
"request": "^2.64.0",
"xml": "^1.0.0",
"xml2js": "^0.4.12"
},
"devDependencies": {},
"optionalDependencies": {},
"devDependencies": {
"chai": "^3.3.0",
"mocha": "^2.3.3",
"sinon": "^1.17.1",
"sinon-chai": "^2.8.0"
},
"scripts": {
"test": "mocha"
},
"engines": {

@@ -23,0 +31,0 @@ "node": ">= 0.6"

eBay API client for Node.js
===============
## Background
## Intro
This was built to power the "eBay Picks" section of [AntiquesNearMe.com](http://antiquesnearme.com). It can currently query the FindingService, MerchandisingService, and Shopping API via JSON-GET requests, and the Trading API via XML-POST. Other services can be added as needed. (Pull requests welcome!)
This module aims to support all of eBay's APIs (Trading, Shopping, Finding, Merchandising, etc),
with an interface that is both a) somewhat consistent across APIs
and b) not too different from the underlying interface.
## To use
eBay's APIs are primarily XML-based, so this module unfortunately has to do a lot of JSON<->XML conversion.
### History
1. I created this module in 2012, for one of the first Node.js apps I ever launched,
and built it out enough to handle my use cases at the time.
2. Since then, [several other people](https://github.com/benbuckman/nodejs-ebay-api/network) have contributed to the module.
3. I decided, after reviewing the alternatives and finding nothing better,
to revive this module again for a project in October 2015. I've pulled in improvements from various forks,
refactored most of the code, and started adding tests.
It is possible that in adding support for new APIs/endpoints, others that used to work no longer work.
I don't have time to build this out to support every endpoint, so
**if you are using this module, or would like to use this module, please submit pull requests!**
## Usage
`npm install ebay-api`

@@ -19,3 +37,5 @@

eBay has an enormous collection of APIs built over the years. Enter the labyrinth here: [http://developer.ebay.com](http://developer.ebay.com) or here: [https://www.x.com/developers/ebay/products](https://www.x.com/developers/ebay/products)
eBay has an enormous collection of APIs built over the years.
Enter the labyrinth here: [http://developer.ebay.com](http://developer.ebay.com)
or here: [https://www.x.com/developers/ebay/products](https://www.x.com/developers/ebay/products)

@@ -28,33 +48,33 @@ Sign up for an API key here: [https://publisher.ebaypartnernetwork.com/PublisherToolsAPI](https://publisher.ebaypartnernetwork.com/PublisherToolsAPI)

## Why use Node.js to do this?
## Methods
Node.js is great at running HTTP requests asynchronously. If each request takes 5 seconds to run and 5 seconds to parse, for example, dozens of requests can run in parallel and only take 10 seconds total, instead of 10 seconds for each. (This module uses [restler](https://github.com/danwrong/restler) for the HTTP handling and the [async](https://github.com/caolan/async) library for flow control.)
### `xmlRequest(options, callback)`
Node.js speaks JSON natively, so the response data from the JSON APIs can be very easily parsed in code, or dumped into MongoDB.
Makes an XML POST to an eBay API endpoints.
Javascript is a little insane and a lot of fun.
## Methods
### `ebayApiGetRequest(options, callback)`
Make an individual request to a GET service.
`options` must contain:
- `serviceName`: e.g. 'Finding'
- `opType`: e.g. 'findItemsAdvanced'
- `appId`: your eBay API application ID
- serviceName: e.g. 'FindingService'
- opType: e.g. 'findItemsAdvanced'
- appId: your eBay API application ID
and can optionally contain:
- params: (see examples and API documentation)
- filters: (see examples and API documentation)
- reqOptions: passed to the request, e.g. with custom headers
- parser: function which takes the response data and extracts items (or other units depending on the query). Defaults to `parseItemsFromResponse`. To return the raw data, pass in a function like `function(data, callback) { callback(null, data); }`.
- sandbox: true/false (default false = production). May need to add additional endpoint URLs to the code as needed.
- `params`: (see examples and API documentation)
- `filters`: (see examples and API documentation.) _might no longer work in 1.x: if you're using this, please submit a PR!_
- `reqOptions`: passed to the [request](https://github.com/request/request) module, e.g. for additional `headers`.
- `parser`: function which takes the response data and extracts items (or other units depending on the query).
_Module includes a default parser._
- `sandbox`: boolean (default false = production). May need to add additional endpoint URLs to the code as needed.
- `raw`: boolean, set `true` to skip parsing and return the raw XML response.
_for authentication, include:_
`callback` gets `(error, items)` or `(error, data)` depending on the parser.
- `devName`
- `cert`
- `authToken`
`callback` gets `(error, data)`.
### `paginateGetRequest(options, callback)`

@@ -64,2 +84,4 @@

_Note: this is currently broken in 1.x. Fixes/refactors are welcome._
`options` contains the same parameters as `ebayApiGetRequest`, plus:

@@ -77,38 +99,2 @@

### `parseItemsFromResponse(data, callback)`
Default parser, takes the response from an API request and parses items or other units per request type.
Each response type is a little different, so this needs to be built out further.
Is used as the default `parser` option for `paginateGetRequest`.
`callback` gets `(error, items)` where `items` are the items parsed from `data`.
### `ebayApiPostXmlRequest(options, callback)`
Make an individual request to a POST-XML service.
`options` must contain:
- serviceName: e.g. 'FindingService'
- opType: e.g. 'findItemsAdvanced'
and can optionally contain:
- (for authentication)
- devName
- cert
- appName
- params (for the XML input)
- (Note: for `GetCategories` and possibly other services, pass the auth token as `params.authToken`, not `RequesterCredentials.eBayAuthToken` as indicated in the API documentation.)
- See `buildXmlInput()` for ways to structure this.
- reqOptions: headers and other options to pass to the request
- IMPT: Some parameters for these endpoints, such as _SITE-ID_ and _authToken_, should go into the headers, not into `params`. See the API documentation.
- sandbox: true/false (default false = production). May need to add additional endpoint URLs to the code as needed.
- rawXml: boolean. If `true`, passes the raw XML response back to callback. `false` means XML is converted to JSON (for consistency with other APIs). Default is `false`/JSON.
`callback` gets `(error, data)`. (There is not currently a default parser for these endpoints.)
## Helpers

@@ -133,12 +119,6 @@

### `checkAffiliateUrl(url)`
### `getLatestApiVersions(callback)`
If you want your affiliate codes included in returned items (see the examples for how to do that), use this to verify that the URLs are of the right format.
e.g. `checkAffiliateUrl(item.viewItemURL)`
_Disabled in 1.x. Please submit a PR with a fix/refactor if you use this._
Returns boolean.
### `getLatestApiVersions(callback)`
Get the version numbers of the APIs that make their version available.

@@ -149,21 +129,9 @@

See the /examples directory. There are two examples, one with a single-page `findItemsByKeywords` request, the other a paginated `findItemsAdvanced` request. It should be reasonably apparent from the examples how these functions are used.
To run the examples, you need to add your own app key (I don't want my keys to be disabled for abuse!) - you can get one [here](https://publisher.ebaypartnernetwork.com/PublisherToolsAPI).
See the /examples directory. There are two examples, one with a single-page `findItemsByKeywords` request,
the other a paginated `findItemsAdvanced` request. It should be reasonably apparent from the examples
how these functions are used.
To run the examples, you need to add your own app key (I don't want my keys to be disabled for abuse!) -
you can get one [here](https://publisher.ebaypartnernetwork.com/PublisherToolsAPI).
## Possible Roadmap
1. Add more services and generally expand the functionality.
2. Add more links related to relevant eBay documentation.
3. Add a generic [Mongoose](http://mongoosejs.com) model. (Mine is currently too filled with custom business logic to be included.)
4. Switch from `async.forEach` to `async.queue` for more fine-grained concurrency control.
5. Suggestions...?
## Credits
Created by Ben Buckman of [New Leaf Digital](http://newleafdigital.com), an independent dev/consulting shop specializing in Node.js, Drupal, mapping, system architecture, and general "full stack" development. Ben writes a [dev blog](http://benbuckman.net) about Node.js and many other subjects.
Ben's other hat is co-founder and CTO of [Antiques Near Me](http://antiquesnearme.com), and this library was created for use there.
Enjoy!
Enjoy!

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc