前回の続き。
PEAR::Services_Twitterを使ってAPI1.1にリクエストを送る方法はこちらを読んでください。

【PHP】 PEAR::Services_TwitterでTwitter API 1.1対応 | mutter


「タイムラインから「google」という単語で検索してマッチしたツイートを取得したい」というような要求があった場合に、API1であればこんなリクエストを送れば取得出来ました。

GET search | Twitter Developers
http://search.twitter.com/search.json?q=google

API1.1では、要Authentication付きでこんなリクエストになります。

GET search/tweets | Twitter Developers
https://api.twitter.com/1.1/search/tweets.json?q=google

このリクエストをServices_Twitterで組み立てるとこんな感じになるのですが、

$obj = new Services_Twitter();
/* oAuth省略 */
$data = $obj->search->tweets(array('q' => 'google'));

実際に動かすと、

Unsupported endpoint search/tweets

と言われて動きません。問題は2つあります。

  1. Services_Twitterが「search/tweets」をサポートしていない
  2. searchの場合のリクエストURLが「http://search.twitter.com」になっている

この2つを解決してやれば、無事に動くようになります。


1. Services_Twitterが「search/tweets」をサポートしていない

Services_TwitterはすべてのAPIのエンドポイントをXMLデータとして持っていて、そこに記載されているかどうかをチェックしているため、API1.1にリクエストを送るようにしたとしても、新しく追加されたリソースは跳ねられてしまうのでした。ということで、このXMLデータを編集してやる必要があります。

このXMLは僕の環境では次の場所にありました。

/usr/share/pear/data/Services_Twitter/data/api.xml


これの466行目にsearchに関する設定があります。

    <!-- Search API methods -->
    <category name="search">
        <endpoint name="search" method="GET" auth_required="false">
            <formats>json,atom</formats>
            <param name="q" type="string" required="true"/>
            <param name="lang" type="iso-639-1" required="false"/>
            <param name="locale" type="string" required="false"/>
            <param name="rpp" type="integer" required="false"/>
            <param name="page" type="integer" required="false"/>
            <param name="since_id" type="integer" required="false"/>
            <param name="until" type="date" required="false"/>
            <param name="geocode" type="geocode" required="false"/>
            <param name="show_user" type="boolean" required="false"/>
            <param name="result_type" type="string" required="false"/>
        </endpoint>
    </category>

ここに次のコードを追加してやります。

        <endpoint name="tweets" method="GET" auth_required="true">
            <formats>json</formats>
            <param name="q" type="string" required="true"/>
            <param name="geocode" type="geocode" required="false"/>
            <param name="lang" type="iso-639-1" required="false"/>
            <param name="locale" type="string" required="false"/>
            <param name="result_type" type="string" required="false"/>
            <param name="count" type="integer" required="false"/>
            <param name="until" type="date" required="false"/>
            <param name="since_id" type="integer" required="false"/>
            <param name="max_id" type="integer" required="false"/>
            <param name="include_entities" type="string" required="false"/>
            <param name="callback" type="string" required="false"/>
        </endpoint>

保存すればOK。


2. searchの場合のリクエストURLが「http://search.twitter.com」になっている

これは前回と同じようなことをすればOK。

Services_Twitter::$searchUri = 'https://api.twitter.com/1.1/search';

こうすることできちんと送られるようになります。


おまけ:もちろん他のAPI1.1で採用された新リソースも追加出来ます

XMLで該当個所を探して、更新。

問題は、PEARでServices_Twitterを更新したらXMLも上書きされちゃうだろうことですけど、でもまあ今現在開発が止まってますし、万が一更新が行われたとしたらこの部分をメンテナンスしてAPI1.1のリソースに対応→更新と言うことになるでしょうから、気にしなくて良いかな。もちろん、更新前にソースの確認は必要ですが。


外からリソースを追加してやれると楽で良いのになー
(それがPEARモジュールとして正しいかはわかりませんけど)