eBayのAPIを使ったツールを開発したいけど何から始めたらいいのか分からないという方へ、僕はこんな手順で進めましたよというお話です。
APIの操作イメージはこんな感じ
1.APIのリクエストをXML形式でeBayサーバに向けて送信する
2.eBay上で、リクエストに従った動作(商品の出品やSold listの取得などいろいろ)が行われる
3.APIの動作結果(Success、Errorなど)および取得データなどがXML形式でリターンされる
僕もそこまで専門的に理解しているわけではないので、用語の使用法など間違いがあるかもしれませんが、ざっとこんなイメージだと理解しておけば開発に支障はないです。
そして我々が開発する部分は、1のXMLを送信するところと、3のXMLを受信するところです。
どんなXMLを送ればいいのか
まずはeBayジャパンサイトのこちらを参考にしてください。
ざっくり説明すると、SoapUIというツール(eBayとは何の関係もないツールです)を使えばプログラムを組むことなくXMLの送受信が行えるので、これでAPIのテストを行おうというものです。
とりあえず、上のサイトに書いてある1から3までを行います。これで、SoapUIを使ってXMLの送受信が行えるようになります。
Application KeyとUser tokenを取得する
APIリクエストを送信する前に必要なのが、App ID、Dev ID、Cert ID、そしてUser tokenの取得です。これらは、eBay Deveroppers programのサイトから取得します。以下を参考にしてください。
各IDとトークンを取得するにあたり、Sandboxと言われるテスト環境と、Productionと言われる本番環境のどちらを使うかによって別のIDとトークンを取得します。
Sandboxの場合、仮に間違ったAPIを送信した場合でも誰にも迷惑がかかりませんし、テストのための商品を出品したとしても誰も間違って購入することもありません。しかしどうもSandbox環境の動きが怪しかったというか、ページを移動するたびに毎回ログインを要求されたり、あとメッセージ系はSandboxではテストできなかったり何だりと面倒だったので、今ではProduction環境でテストから何から行っています。プログラムをぶっつけ本番で動かすというのはちょっと怖いですがw。一度メッセージ送信のテストで壊れたメッセージをお客様に送ってしまったという事がありました。また出品のテストも、できるだけ高い値段を付けて出して誰も買わないようにして、かつテストで出品されたものはすぐに取り消すという事をやっています。
どちらでもいいのですが、僕はProduction環境をおすすめします。
試しにGeteBayOfficialTimeを送信してみる
このAPIは、eBayサイトの時刻を取得するものです。上で取得したApplication Keyとトークンだけあれば送信できるので、環境の確認に最適です。僕も最初はこれから始めてみました。
SoapUIの画面左からGeteBayOfficialTimeを探し、そこのBasic_Request_XMLをダブルクリックすると次のような画面になります。
ここの赤矢印の部分に、取得したトークンと各IDを入力します。Sandboxを使う場合は、左下のEndpointを「https://api.sandbox.ebay.com/ws/api.dll」に変更します。Productionの場合はデフォルトの「https://api.ebay.com/ws/api.dll」のまま変更の必要はありません。
そして入力が終わったら、右の小ウィンドウの左上にある緑色の▷ボタンをクリックします。そして結果が右半分に表示されます。上の図では、すでに実行した結果が表示されています。
ここでXMLが正常に送受信できていることが確認できたら、あとは同じXMLを自分の開発する環境から送受信すればいいだけです。あまり綺麗ではないかもしれませんがPythonでのサンプルを以下に出しておきます。
#! C:\Program Files (x86)\Python36-32\python # coding: utf-8 print ("Content-type:text/html\n\n") print () import http.client from xml.dom.minidom import parse, parseString devID = "xxxxxxxxxx" appID = "xxxxxxxxxx" certID = "xxxxxxxxxx" serverUrl = "api.ebay.com" serverDir = "/ws/api.dll" userToken = "xxxxxxxxxx" siteID = "0" verb = "GeteBayOfficialTime" compatabilityLevel = "433" # FUNCTION: buildHttpHeaders def buildHttpHeaders(): httpHeaders = {"X-EBAY-API-COMPATIBILITY-LEVEL": compatabilityLevel, "X-EBAY-API-DEV-NAME": devID, "X-EBAY-API-APP-NAME": appID, "X-EBAY-API-CERT-NAME": certID, "X-EBAY-API-CALL-NAME": verb, "X-EBAY-API-SITEID": siteID, "Content-Type": "text/xml"} return httpHeaders # FUNCTION: buildRequestXml def buildRequestXml(): requestXml = "<?xml version='1.0' encoding='utf-8'?>"+\ "<GeteBayOfficialTimeRequest xmlns=\"urn:ebay:apis:eBLBaseComponents\">"+\ "<RequesterCredentials><eBayAuthToken>" + userToken + "</eBayAuthToken></RequesterCredentials>" + \ "</GeteBayOfficialTimeRequest>" return requestXml connection = http.client.HTTPSConnection(serverUrl) #Setup the HTML Page with name of call as title print ("<HTML>") print ("<HEAD><TITLE>", verb, "</TITLE></HEAD>") print ("<BODY>") connection.request("POST", serverDir, buildRequestXml(), buildHttpHeaders()) response = connection.getresponse() # if response was unsuccessful, output message if response.status != 200: print ("Error sending request:" + response.reason) else: #response successful data = response.read() connection.close() # parse the response data into a DOM response = parseString(data) # check for any Errors errorNodes = response.getElementsByTagName("Errors") if (errorNodes != []): #there are errors print ("<P><B>eBay returned the following errors</B>") #Go through each error: for error in errorNodes: #output the error code and short message print ("<P>" + ((error.getElementsByTagName("ErrorCode")[0]).childNodes[0]).nodeValue) print (" : " + ((error.getElementsByTagName("ShortMessage")[0]).childNodes[0]).nodeValue.replace("<", "<")) #output Long Message if it exists (depends on ErrorLevel setting) if (error.getElementsByTagName("LongMessage")!= []): print ("<BR>" + ((error.getElementsByTagName("LongMessage")[0]).childNodes[0]).nodeValue.replace("<", "<")) else: #eBay returned no errors - output results # check for the <EBayTime> tag and print if (response.getElementsByTagName("Timestamp")!=[]): print ("<P><B>Timestamp : ", ((response.getElementsByTagName("Timestamp")[0]).childNodes[0]).nodeValue, "</B></P>") print ("<P><B>Ack : ", ((response.getElementsByTagName("Ack")[0]).childNodes[0]).nodeValue, "</B></P>") print ("<P><B>Version : ", ((response.getElementsByTagName("Version")[0]).childNodes[0]).nodeValue, "</B></P>") print ("<P><B>Build : ", ((response.getElementsByTagName("Build")[0]).childNodes[0]).nodeValue, "</B></P>") # force garbage collection of the DOM object response.unlink() print ("</BODY>") print ("</HTML>")
自分の環境は、とりあえずWindows上にApacheとPythonをインストールして、その上で開発を行っています。一通り完成したら、サーバー上にデプロイする予定で考えています。
実際の開発で
今ちょうどAddItemを送信するところを作っています。これは送信のオプションが沢山あって、いきなりコードに埋め込んでもどこでエラーになっているのかなかなか分かりにくいです。なのでまずはSoapUIで正常に送信できるXMLを組み立ててから、これと同じXMLをプログラムで組み立ててから送信するという手順を取っています。
参考にしてみてください。