Old dogs, new tricks

Archive for the ‘ebay’ Category

ebay_shopping is now a gem (and now at github)

with 16 comments

OK. I’ve jumped on the Git bandwagon, and to celebrate have made the ebay_shopping plugin (a ruby on rails library for eBay’s shopping API) into a gem, hosted at Github. It’ll take a few days before the rubyforge project is approved and loaded up, but you can still download it from github, or with a github clone.

Why turn it into a gem? Well, it was originally a plugin as that was the easiest and quickest way to do it at the time — it was generated from a Rails application, after all. It also made things like getting the initial config (from a YAML file in the Rails config directory) a no-brainer, and meant I could use some of the ActiveSupport methods without thinking.

But over the past few weeks, I’ve been playing around with Merb, and decided these benefits are more than outweighed by the greater portability a gem brings. There’s also the benefit of versioning and dependencies. Finally, with Rails edging away from plugins with 2.1, and the ease of gem generation using Dr Nic’s newgem gem, there’s really no reason to stay with the plugin approach. Enter, stage left, the ebay_shopping gem.

If you’re already using the plugin, there’s no hurry to change. If not, give the gem a try and let me know how it goes. Use is almost identical to the plugin. The only difference is with the initial configuration. You can still use the same YAML config file in your Rails config folder (if you’re using Rails or Merb), you just need to set it up explictly in your environment.rb

EbayShopping::Request.config_params("#{RAILS_ROOT}/config/ebay.yml", RAILS_ENV)

Passing the RAILS_ENV as the second param just ensures it will use the correct environment settings from the config file, if you’ve got different ones for development, production, test, etc. If not, or if you don’t tell it, it will just default to the production settings.

You can also (from the console, for example), set the inital configuration with a Hash

EbayShopping::Request.config_params({:app_id => "my_app_id", :default_site_id =>"3"})

The hash must provide the app_id you’re given by ebay, and can optionally provide the ebay affiliate info and your preferred default country (e.g. the UK in the above one). This can be overridden in individual requests, or if you just leave it out it will default to ebay.com.

Enough waffle. Explore the code over at github. The documentation still needs tweaking, but the test suite and code comments should explain it all fairly well. Plus there are some use examples on the post about the original plugin, which still stand. Patches and forks welcome — this is git after all we’re talking about.


Finally gotten around to adding the gemspec file which allows github to build the gem automatically. So now all you need to do  is the usual:

gem sources -a http://gems.github.com

sudo gem install ctagg-ebay_shopping

Written by ctagg

May 13, 2008 at 4:54 pm

Posted in ebay, rails, ruby

Tagged with , , , ,

the ebay shopping api and the new ebay affiliate scheme

leave a comment »

As you may have heard, started from April 1, eBay is phasing out its old affiliate schemes in favour of it’s own home-grown one.

I won’t go here into discussing the pros and cons of the change (for Autopendium, the classic car website I run, on balance it’s probably good, if only from an admin point of view), but I did think it’s worth mentioning how how to update your config file for ebay-shopping, the rails library I wrote for the eBay Shopping API.

Step 1: Update your ebay.yml file with the new settings

  :app_id: "your_api_app_id_code" # this doesn't change
  :affiliate_partner: "9"  # this is to signify you are using
eBay's own affiliate scheme and afer the end of April will
be the only working choice
  :affiliate_id:  "your_new_ebay_affiliate_code" # This is the
new affiliate code from eBay, and is also called a CampaignId
  :affiliate_shopper_id: "my_campaign" # Doesn't need to change

The CampaignID is the only tricky bit, as eBay sometime also refers to is as CampID and Tracking Partner ID. Once you’ve signed up for the affiliate scheme, click on the Campaigns tab to find it (you can actually have more than one campaign and hence more than one CampaignID).

Step 2: Restart your server. Er, that’s it.

Written by ctagg

April 4, 2008 at 6:48 pm

Posted in ebay, rails, ruby

Tagged with , , , ,

A RubyonRails library for the ebay shopping API

with 21 comments

After the lightweight Facebook library I wrote to scratch my own itch, a couple of days ago I started to look at adding ebay items to Autopendium :: Stuff About Old Cars, the classic car website I run. Users were already shown books from Amazon, appropraite to the content being shown on the page, and it seemed to make sense to show models, cars and parts from ebay, for the vehicle or model being displayed.

Amazon books on Autopendium

I’d had a look at adding ebay functionality quite a while back, when I’d first just started to use Ruby and Rails, and couldn’t quite get to grips with ebay4r, which was at that time the ebay API ruby library. Since I’d last looked, another library had been written, Cody Fauser’s ebayapi, which he introduces with a brief tutorial here, and having a quick look at the code and the tests, it seemed just the job. I then fired up IRB and and gave it a test drive in the console.

It all seemed fine, just rather slow. The problem is, the library uses ebay’s SOAP interface, which is markedly slower than the REST one. And in fact, even the Trading REST interface is slower than the Shopping interface, as a quick and dirty benchmark shows:

  user       system       total      real
0.050000    0.030000    0.080000  (  6.487812) # 10 calls to the shopping REST API
0.130000    0.060000    0.190000  ( 12.517658) # 10 calls to the trading REST API

Now, if you want all the functionality that the Trading API provides — the ability to bid on items, or to list new items — that speed trade-off is no problem, as the user will expect such things to take a couple of seconds.

But if you’re wanting to include items for sale on a page each time it’s displayed (even allowing for caching), each 1/10th of a second counts, and the extra functionality that the Trading API provides is irrelevant.

Unfortunately, there’s no Ruby or Rails library for the Shopping API. So, time to scratch my own itch again. Enter ebay-shopping, a RubyonRails plugin for the ebay Shopping API. It’s a pretty straightforward plugin that was fairly easy to write (the first version, implemented as a basic lib file, was done in an afternoon), and is even easier to use.

To install, from the root of your rails app simply run the usual

script/plugin install http://ebay-shopping.googlecode.com/svn/trunk/ ebay_shopping

Then run

ruby vendor/plugins/ebay_shopping/install.rb

This will copy a basic configuration file into your app’s config directory. This is where you put your ebay settings (Ebay Application id, affiliate info if you have it, etc). Update this with your settings — the only thing you actually need is the app id, which you can get by signing up at http://developer.ebay.com (The code you need is called the AppID — the Auth Token and other stuff is for the Trading API).

Then fire up the Rails console and away we go:

>> request = EbayShopping::Request.new(:find_items, :query_keywords=>"Cadillac")
=> #<EbayShopping::Request:0x246aa54 @affiliate_shopper_id="my_campaign", @affiliate_partner="1",
@site_id=nil,@affiliate_id="foo1234bar", @callname=:find_items, @call_params={:query_keywords=>"Cadillac"},

>> response = request.response
=> #<EbayShopping::FindItemsResponse:0x2444520 @request=#<EbayShopping::Request:0x244a36c,
@affiliate_shopper_id="my_campaign", @affiliate_partner="1", @site_id=nil, @affiliate_id=nil, @callname=:find_items,
@call_params={:query_keywords=>"Cadillac"}, @app_id="my_ebay_app_id_1234567",
@full_response={"Version"=>"547", "Timestamp"=>"2008-01-13T13:20:27.641Z", "Build"=>"e547_core_Bundled_5879814_R1",
"Item"=>[{"ShippingCostSummary"=>{"ShippingType"=>"NotSpecified"}, "ListingStatus"=>"Active", "TimeLeft"=>"P20DT16H59M6S",
"PrimaryCategoryName"=>"eBay Motors:Cars & Trucks:Cadillac:STS", "Title"=>"Cadillac : STS",
"Ack"=>"Success", "TotalItems"=>"15580", "xmlns"=>"urn:ebay:apis:eBLBaseComponents"}>

>> response.total_items
=> 15580

To get the items from the response, just ask for them

>> first_item = response.items.first
#<EbayShopping::Item:0x2413a88 @gallery_url="http://thumbs.ebaystatic.com/pict/230212386614.jpg",
@all_params={"ShippingCostSummary"=>{"ShippingType"=>"NotSpecified"}, "ListingStatus"=>"Active",
"TimeLeft"=>"P20DT16H59M6S", "PrimaryCategoryName"=>"eBay Motors:Cars & Trucks:Cadillac:STS",
"Title"=>"Cadillac : STS", "ConvertedCurrentPrice"=>{"currencyID"=>"USD", "content"=>"9500.0"},
"GalleryURL"=>"http://thumbs.ebaystatic.com/pict/230212386614.jpg", "ItemID"=>"230212386614",
"ListingType"=>"FixedPriceItem", "EndTime"=>"2008-02-03T06:19:33.000Z", "PrimaryCategoryID"=>"124117",
@end_time="2008-02-03T06:19:33.000Z", @primary_category_name="eBay Motors:Cars & Trucks:Cadillac:STS",
@converted_current_price={"currencyID"=>"USD", "content"=>"9500.0"}, @title="Cadillac : STS",
@item_id="230212386614", @time_left="P20DT16H59M6S">

The key attributes for the item are available through ruby-ized version of the ebay Attributes (full documentation for the Shopping API calls and responses)

>> first_item.title # for the Title attribute
=> "Cadillac : STS"
>> first_item.gallery_url # for the GalleryURL attribute
=> "http://thumbs.ebaystatic.com/pict/230212386614.jpg"
>> first_item.view_item_url_for_natural_search # for the ViewItemURLForNaturalSearch attribute
=> "http://cgi.ebay.com/Cadillac-STS_W0QQitemZ230212386614QQcategoryZ124117QQcmdZViewItem"
>> first_item.bid_count
=> nil
>> first_item.primary_category_name
=> "eBay Motors:Cars & Trucks:Cadillac:STS"

As you can see, most of these responses are just strings. For the price, you’ve got a couple of options

>> first_item.converted_current_price
=> #<EbayShopping::Money:0x1410b70 @content=9500.0, @currency_id="USD">
>> first_item.converted_current_price.content
=> 9500.0


>> first_item.converted_current_price.to_s
=> "$9500.00"

It’s also worth noting the end time is returned as a Ruby Time object, so you can do calculations against it

>> first_item.end_time
=> Sun Feb 03 06:19:33 GMT 2008
>> first_item.end_time.class
=> Time

Finally, there’s a catch_all [] method which allows you to access other attributes using a familiar hash key notation:

>> first_item["ShippingCostSummary"]
=> {"ShippingType"=>"NotSpecified"}

Other methods and usage are given in the code comments and the fairly extensive test suite (browse the source here). There are also hooks to allow for caching and (separately) error caching, which is necessary if you want to get your app approved as a Compatible Application, which allows you a greater number of API calls per day (I did). I’ll post on usage of these and examples if anyone wants me to.

Tie that into your Rails app, and you’ve got an instant mash-up:
Ebay items on Autopendium

At the moment, the library’s only available as a RubyonRails plugin, rather than a Ruby gem. The only reason for this is that it was extracted from a Rails app, and is slightly structured accordingly (e.g. the YAML config file, and option for different settings in different environments). However, it’s probably not a huge job to package it as a gem, or to use the code as is in a standalone Ruby app.

p.s. Some of the less frequently used API calls haven’t yet been implemented, but are being done bit by bit, and if anyone’s got a crushing need for one of the missing ones, let me know, and I’ll bump it up the priority list.

Written by ctagg

January 13, 2008 at 5:47 pm