Help us understand the problem. What is going on with this article?

面倒なAPIアクセスをPryのカスタムコマンドで省略する

More than 5 years have passed since last update.

更新のおしらせ

本記事はWebPay gemのバージョン2系に即して記述しています。
その後、メジャーバージョンアップを行いました。

ほとんどの内容はそのまま利用できますが、メソッド名などが一部変更になっています。
最新の情報はWebPay公式サイトのRuby APIドキュメントを参照してください。

APIアクセスの面倒

ウェブサービスのAPIを試しに叩きたいときに、Rubyの環境を前提とするとIRBやPryがとても便利です。
APIの仕様をコピペしながら、こういう風に動くのかと知り、その場で使い捨てにするには良いのですが、
実装を進めながらとか運用に入った場合にAPIを改めて叩きたいとか、軽く利用状況を把握したいという時には度々コマンドなんだったっけと調べ直す手間がなかなか煩わしいです。
もちろん、ちゃんとスクリプトなどに落としておいて、必要な情報はすぐに取得可能な状態を作っておくのが正しいお話です。

逆にサービスのAPIを提供している側がそこをアシストするようなアプリやスクリプトを提供するというのも手ですが、大々的に専用アプリを準備するのは優先度的に下と判断されて上場するまでリリースされないことが危惧されます。

そこでPryのカスタムコマンドで簡単に対話的なアプリをつくってみます。

Pryのカスタムコマンド

Pryのカスタムコマンドは、PryのCLI上向けに独自のコマンドを定義することが出来ます。
既存のコマンド群もカスタムコマンドと同様に定義されており、引数(オプション)や前処理、後処理、シェルコマンドの実行など諸々のことが出来るようになっています。

WebPayの情報を簡易的に扱う対話的インタフェース

GUI(ブラウザ経由)が現状貧弱なWebPayですが、普段さっと課金や顧客の状態を把握、処理したい場面に遭遇することが多いです。
その度にPryやIRBを立ち上げて

[1] pry(main)> require ‘webpay’
=> true
[2] pry(main)> WebPay.api_key = ‘test_xxxxxxxxxxxx’
=> "test_xxxxxxxxxxxx"
[3] pry(main)> WebPay::Charge.all

と書き進めるのも、なかなか骨の折れる作業です。
しかもこの例だと戻り値のオブジェクトがだだ長くて、スクロールし直すのも憂鬱です。

そこで、そういった場面向けのカスタムコマンド群を書いてみました。
- https://gist.github.com/hmsk/8084235

$ ruby webpay-pry.rb

で実行することで利用することが出来ます。

カスタムコマンドを前面から作成してしまうと、Pry本来のコマンドや評価が全部潰されてしまうので、カスタムコマンド群を

Pry::Commands.import webpay_commands

としてインポートする形を取りました。これで普通のPryの機能も概ね利用出来ます。

使用例

ちょっと使ってみます。

[hmsk@] $ ruby webpay-pry.rb
At first, set secret key with: key 'test_secret_xxxxxxxxxx'

Type 'help' to help. type 'exit' to terminate.

WebPay>

実行すると非公開鍵を教えろという通知とともに、WebPayと対話出来そうなコンソールが表示されます。

WebPay> key 'test_secret_XXXXXXXXXXXXXXXXXXX'
test_secret_XXXXXXXXXXXXXXXXXXX
initializing...
loaded...
WebPay>

指示通りにキーを渡すと何やら初期化処理を行っていると知らされます。この間に課金や顧客の情報を集めてきています。

WebPay> help
charges : show charges
charge num: show charges with page number
customers : show customers
customer num: show customers with page number
WebPay>

helpを請うと使えそうなコマンドが4つ表示されます。(Pryの元々のコマンドも使えますが、丸ごと上書きしています)

WebPay> charges
[0] ch_b8Sf3H2ZC7Wq2jh 0yen,
[1] ch_9KagdU6KEgOu90t 400yen,
[2] ch_9Kacih8st9fd8kc 400yen,
[3] ch_9Ka0Q5gDQg8o4sU 400yen,
[4] ch_7Ga8sE0dU2Jf5MS 300yen,
[5] ch_7tMasQ88Q2XBffF 400yen,
[6] ch_5Ca7JD5r15J6g9a 400yen,
[7] ch_5Ca6Br6ZGak1bUv 400yen,
[8] ch_21cfllfyT9sK55a 400yen,
[9] ch_1X49LdePjcyf1WL 400yen,
[10] ch_0X82X8803f5P7XV 0yen,
[11] ch_0X85182yO8g654X 400yen,
[12] ch_g0hcMY5fm0thgKi 0yen, アイテムの購入
[13] ch_fW95bV0KD23H3C2 0yen, アイテムの購入
[14] ch_fW95kbdpHcnsfdr 0yen, アイテムの購入
[15] ch_fW95oj7AAckOgLH 0yen, アイテムの購入
[16] ch_g0h3Fj4ws08C4Vk 400yen, アイテムの購入
[17] ch_fxn00Zecbdin4FY 400yen, アイテムの購入
[18] ch_f8B9XF2UxbIccvY 1000yen,
[19] ch_exreSg4iM58s6nC 1000yen,
[20] ch_dWhdwK2Hf6fAdpO 1000yen,
[21] ch_dS98u83W23NQ5Rp 111yen,
[22] ch_dS96CvcLIeU4ety 320yen,
[23] ch_dS93KW42U08Jeg9 900yen,
[24] ch_dS9ftAanFcgHdIJ 1500yen,
[25] ch_dO12Z031Y0qr2Pu 1554yen, WEB DB PRESSの購入
[26] ch_dO1dTP25MfD36wV 400yen, アイテムの購入
[27] ch_dgZ03K5e182j4VD 1000yen,
[28] ch_d0tarWdMDdxm2nj 400yen, アイテムの購入
[29] ch_cFP6LP7CH5G4dwd 1000yen,
[30] ch_c4FfxUadj3iI9EM 1000yen,
[31] ch_btvesU0rz5YJ9f5 1000yen,
[32] ch_aSlaTe7LYdmDbgf 1000yen,
[33] ch_ad3diPfuj6kPd30 1000yen,
[34] ch_9BTfqO9vCfNk3Ae 400yen, アイテムの購入
[35] ch_9BT4Pv9jwdjG6bh 1000yen,
[36] ch_98Z8Cidycc2Uaga 1000yen,
[37] ch_98Z8Ci3ZN7yCdV3 1000yen,
[38] ch_7Kh2Ir59KdH6e5E 1000yen,
[39] ch_7Khbvs5fH3q9cZN 1000yen,
[40] ch_7Kh4qkgByaeF0wr 400yen, アイテムの購入
You can retrieve charge from above with: e.g. `charge 1`
WebPay>

chargesとすると最近のものから順に課金の情報が表示されました。
最後の指示に従って、ひとつ課金を抽出してみます。

WebPay> charge 3
=> #<WebPay::Charge:0x007f96cc149c58
 @attributes=
  {"id"=>"ch_9Ka0Q5gDQg8o4sU",
   "object"=>"charge",
   "livemode"=>false,
   "shop"=>nil,
   "currency"=>"jpy",
   "description"=>nil,
   "amount"=>400,
   "amount_refunded"=>0,
   "customer"=>nil,
   "created"=>1385340172,
   "paid"=>true,
   "refunded"=>false,
   "failure_message"=>nil,
   "card"=>
    #<WebPay::Card:0x007f96cc149ca8
     @attributes=
      {"object"=>"card",
       "exp_year"=>2014,
       "exp_month"=>11,
       "fingerprint"=>"215b5b2fe460809b8bb90bae6eeac0e0e0987bd7",
       "name"=>"KEI KUBO",
       "country"=>"JP",
       "type"=>"Visa",
       "cvc_check"=>"pass",
       "last4"=>"4242"}>,
   "captured"=>true,
   "expire_time"=>nil}>
WebPay>

charge 3で先ほどのリストの4つ目のWebPay::Chargeのオブジェクトが返されました。
ではwebpay-rubyのインタフェースを用いてこれを返金してみます。

WebPay> _.refund
=> #<WebPay::Charge:0x007f96cc149c58
 @attributes=
  {"id"=>"ch_9Ka0Q5gDQg8o4sU",
   "object"=>"charge",
   "livemode"=>false,
   "shop"=>nil,
   "currency"=>"jpy",
   "description"=>nil,
   "amount"=>400,
   "amount_refunded"=>400,
   "customer"=>nil,
   "created"=>1385340172,
   "paid"=>true,
   "refunded"=>true,
   "failure_message"=>nil,
   "card"=>
    #<WebPay::Card:0x007f96cc952ee0
     @attributes=
      {"object"=>"card",
       "exp_year"=>2014,
       "exp_month"=>11,
       "fingerprint"=>"215b5b2fe460809b8bb90bae6eeac0e0e0987bd7",
       "name"=>"KEI KUBO",
       "country"=>"JP",
       "type"=>"Visa",
       "cvc_check"=>"pass",
       "last4"=>"4242"}>,
   "captured"=>true,
   "expire_time"=>nil}>

返金できました。IRBやPryでは_で最後に評価した結果のオブジェクトをそのまま利用出来ます。

対話的なインタフェースがアシストしてくれるおかげで、何となくの作業はぼーっと口を空けていても出来そうな感じがします。(特にidを毎度コピペしたりGUIから操作するのが辛いので、そこを軽減出来るのは効果的です)

まともな形にしてGemにするか、webpay-rubyにbin/webpay-cliとでもして追加するかしたいところです。
それ以前のそもそもで、もっと使いやすいGUIやAPI向けのインタフェースも考えていきたいものです。

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away