As I was building the photo genius app for Tailored, I was tasked with uploading images to Etsy via its API. There is little documentation on how to do this. So I’m going to show you how to do it.
Etsy has an api for image uploading. But it requires a multipart form post. What if you stored your images somewhere like S3 where it is easier to access via a url? Can we upload an image via a url? The trick is to make use of Ruby’s OpenURI library to open the file via url on the fly. The instructions below assumes you’re on a Rails app.
First create a new file with the code below.
123456
# config/initializers/open_uri_fix.rb## Don't allow downloaded files to be created as StringIO. Force a tempfile to be created.# For the image publisherOpenURI::Buffer.send:remove_const,'StringMax'ifOpenURI::Buffer.const_defined?('StringMax')OpenURI::Buffer.const_set'StringMax',0
This sets the constant of StringMax in OpenURI to be 0. The StringMax constant is used to determine when to open the url as a File or StringIO object. If the file size is smaller than StringMax, OpenURI will use StringIO. StringIO will cause problems in the app as it is not compatible with multipart form posts.
Assuming you have the etsy ruby gem installed, here is how you could write the upload method.
# lib/etsy_interface.rbmoduleEtsyInterfacemoduleClient# Public: Makes a request to Etsy API## shop - The EtsyShop instance# url - The String which is the URL to query for# params - The Hash of attributes to pass in to the query## Examples## EtsyInterface::Client.get('foo', shop, '/foo', {bar: 'bar'})# # => {...}## Returns the Hash## Signature## <mtd>(args)## mtd - Either of the get, post, put or delete HTTP methods%w(get put post delete).eachdo|mtd|define_methodmtddo|shop,url,params={}|pre_setupEtsy::Request.send(mtd,url,access_params(shop,params)).to_hashendendprotected# Public: Sets the constants of the Etsy class## Examples## EtsyInterface::Client.pre_setup# # => nil## Returns nothingdefpre_setupEtsy.environment=:productionunlessRails.env=='test'Etsy.api_key=Settings.etsy_api_key# your etsy api keyEtsy.api_secret=Settings.etsy_secret# your etsy secretend# Public: Forms the query parameters for the request## shop - The EtsyShop instance# params - The Hash of attributes to pass in to the query## Examples## EtsyInterface::Client.access_params(shop, {bar: 'bar'})# # => {access_token: 'd', access_secret: 'g', bar: 'bar'}## Returns the Hashdefaccess_params(shop,params)user=shop.etsy_useraccess_params={access_token:EtsyBuilder.etsy_oauth_token_for(user),access_secret:EtsyBuilder.etsy_oauth_secret_for(user)}.merge(params)endendend