I am playing with getting sold items from ebay using eBay::API::Simple::Finding and I want to use ItemFilters but I can't see where they go. In particular I am looking to use the item filters
(itemFilter.name = SoldItemsOnly, itemFilter.value = true)
and
(itemFilter.name = Condition, itemFilter.value = Used)
I tried just including directly with the following here:
keywords => '"princess cut", "diamond ring", -"14k*"',
Condition => 'Sold',
SoldItemsOnly => 'true',
sortOrder => 'PricePlusShippingHighest'
I have been on it quite a while and whilst I am sure it is somehow quite straight forward, I just can't seem to get it
use eBay::API::Simple::Finding;
my $api = eBay::API::Simple::Finding->new( {
appid => 'APIKEY',
siteid => 'EBAY-AU',
} );
$api->execute(
'findCompletedItems', {
keywords => '"princess cut", "diamond ring", -"14k*"',
sortOrder => 'PricePlusShippingHighest',
}
);
if ( $api->has_error() ) {
die "Call Failed:" . $api->errors_as_string();
}
my $dom = $api->response_dom();
my $hash = $api->response_hash();
Any help is very appreciated,
As for what I am seeing? The sort is working, the search by keywords is working, but the itemfilters are not working, so it is returning new & used items that have completed, whether sold or unsold
Reading the eBay API docs about findCompletedItems
shows that you need to use child elements for ItemFilter
s. There is a sample that shows this nicely (link).
<?xml version="1.0" encoding="UTF-8"?>
<findCompletedItemsRequest xmlns="http://www.ebay.com/marketplace/search/v1/services">
<keywords>Garmin nuvi 1300 Automotive GPS Receiver</keywords>
<categoryId>156955</categoryId>
<itemFilter>
<name>Condition</name>
<value>3000</value>
</itemFilter>
<itemFilter>
<name>FreeShippingOnly</name>
<value>true</value>
</itemFilter>
<itemFilter>
<name>SoldItemsOnly</name>
<value>true</value>
</itemFilter>
<sortOrder>PricePlusShippingLowest</sortOrder>
<paginationInput>
<entriesPerPage>2</entriesPerPage>
<pageNumber>1</pageNumber>
</paginationInput>
</findCompletedItemsRequest>
Looking at the source code of the eBay::API::Simple::Finding module we can see that it uses XML::Simple to construct requests. While in general XML::Simple
is discouraged, we will have to work with it.
Taking a deeper look at the docs for the ItemFilter
shows that we can provide one <itemFilter>
block per filter. That implies that multiple ones are treated as AND automatically.
To make a single item with the way XML::Simple get set up in the API module, we just need a hashref.
{
itemFilter => {
name => 'Condition',
value => 3000,
},
}
will become
<itemFilter>
<name>Condition</name>
<value>3000</value>
</itemFilter>
To get several, we need an array reference behind the itemFilter
key.
{
itemFilter => [
{
name => 'Condition',
value => 3000,
},
{
name => 'FreeShippingOnly',
value => 'true',
},
],
}
This produces this XML.
<itemFilter>
<name>Condition</name>
<value>3000</value>
</itemFilter>
<itemFilter>
<name>FreeShippingOnly</name>
<value>true</value>
</itemFilter>
So far so good. We can easily hack that into the API module call. Instead of executing the call directly, I have prepared it, and then called the private method _get_request_body
, which uses XML::Simple to form and return the request body string. That's neat to check if the request will look ok. I figured that out by reading the code, starting at the one I lined above, and working my way towards the base class, which provides execute
.
use eBay::API::Simple::Finding;
my $api = eBay::API::Simple::Finding->new( {
appid => 'APIKEY',
siteid => 'EBAY-AU',
} );
$api->prepare(
'findCompletedItems',
{
keywords => '"princess cut", "diamond ring", -"14k*"',
sortOrder => 'PricePlusShippingHighest',
itemFilter => [
{
name => 'SoldItemsOnly',
value => 'true',
},
{
name => 'Condition',
value => 'Used',
},
],
}
);
print $api->_get_request_body;
Here's the XML that comes out.
<?xml version='1.0' encoding='utf-8'?>
<findCompletedItemsRequest xmlns="http://www.ebay.com/marketplace/search/v1/services">
<itemFilter>
<name>SoldItemsOnly</name>
<value>true</value>
</itemFilter>
<itemFilter>
<name>Condition</name>
<value>Used</value>
</itemFilter>
<keywords>"princess cut", "diamond ring", -"14k*"</keywords>
<sortOrder>PricePlusShippingHighest</sortOrder>
</findCompletedItemsRequest>
It doesn't matter that it' not indented nicely. It is clear that the filters are there.
Since I don't have an API key I cannot run this myself, but I am pretty sure it's going to work.