Twitter REST API関数の追加 (xyttr Advent Calendar 13日目)

この記事はxyttr Advent Calendar 2011の記事です。

xyttrパッケージには30ほどのTwitter REST API関数が用意されていますが、未対応のAPIがまだ沢山あります。(参照 Documentation | Twitter Developers)

使いたいAPIがxyttrでサポートされてない! という時は、マクロ xyttr::define-api を使うと簡単にAPI関数を追加できます。

リファレンスより抜粋

- *macro* define-api (name params &key auth method apiurl path key)

    Twitter REST API関数を定義します。
    同期版 api-{name} と 非同期版 api-{name}-async の2つの関数が生成され、
    xyttrパッケージよりexportされます。
    
    * name -- 関数名
    * params -- リクエストパラメータ
    * auth -- OAuth認証ヘッダの必要の有無 (省略時は t)
    * method -- HTTPメソッド (省略時は get)
    * apiurl -- リクエスト先ホスト名 (省略時は "api.twitter.com")
    * path -- リソースURLのパス部分 (省略不可)
    * key -- 関数を指定すると、リクエスト結果(jsonリスト)をその関数に通してから返します。

使用例として、現行のxyttr ver1.1.1には用意されてないトレンド関連のAPIを定義してみます。

trends/available API

トレンド情報の取得可能な地域を返すAPIです。
クエリパラメータlat(緯度)とlong(経度)を指定すると、指定座標から近い順でソートした結果を返します。

(in-package :xyttr)

(define-api trends-available (lat long)
  :path "/1/trends/available.json")

このコードで関数api-trends-availableとapi-trends-available-asyncが生成されます。
api-trends-available関数の引数は (&key lat long) となり、-asyncと付いてる方(非同期版)の引数はコールバック用の引数が追加されて (&key lat long onsuccess onfailure oncomplete handler) となります。

  • API関数使用例
(car (xyttr:api-trends-available :lat 35 :long 135))
; =>
; (("countryCode" . "JP")
;  ("woeid" . 1118370)
;  ("url" . "http://where.yahooapis.com/v1/place/1118370")
;  ("name" . "東京")
;  ("placeType" ("name" . "Town") ("code" . 7))
;  ("country" . "Japan")
;  ("parentid" . 23424856))

trends/:woeid API

指定したwoeid (Yahoo! Where On Earth ID) に対応する地域でのトレンドを返すAPIです。

(in-package :xyttr)

(define-api trends (woeid exclude)
  :path (format nil "/1/trends/~A.json" woeid))

このAPIはパス中にwoeidを埋め込む必要があるので、:pathパラメータはformat関数を使ったフォームになっています。

  • API関数使用例
(in-package :xyttr)

;; woeid 一覧
(defvar *woeids*
  (mapcar #'(lambda (l)
              (w/json (woeid name countryCode) l
                (cons (concat countryCode ":" name) woeid)))
          (api-trends-available :lat 35 :long 135)))

;; トレンド表示コマンド
(defun show-trends (&optional (p 0))
  (interactive "p")
  (let* ((loc (if (= p 0) "JP:日本"
                (completing-read "Location: " (mapcar #'car *woeids*) :must-match t)))
         (woeid (cdr (assoc loc *woeids* :test #'string=))))
    (w/json (trends) (car (api-trends :woeid woeid))
      (msgbox "~{~A~%~}" (mapcar #'(lambda (tr) (json-value tr name)) trends)))))

(define-key *xyttr-timeline-keymap* #\T 'show-trends)

タイムラインバッファでTキーを押すと
http://gyazo.com/5353927732f28bb1d8acf7bf7ccfeb02.png
こんな感じで日本のトレンドが表示されます。
0以外の前置引数を渡す (M-- やM-1 〜 M-9を押してからTを押す) とminibufferで指定した地域のトレンドを表示できます。(complete+の併用を推奨)
http://gyazo.com/080a1de16cc8f2baca65d601a66347a0.png



以上、define-apiマクロの解説でした。