twitter api v1 から v2 へ移行

管理画面よりstandaloneアプリをプロジェクトにして、apiv2でアクセスできるようにしてから、

twitter oauthをインスコ

```
composer require abraham/twitteroauth
```


とりあえず、無料で使えそうなのは以下の2点
・ツイート
・lookup

bookmarks取得はoauth2.0でのログインが必要らしい。
https://scr.marketing-wizard.biz/dev/tweepy-twitter-apiv2


```
use Abraham\TwitterOAuth\TwitterOAuth;
```

# ツイート

```
$token = "your";
$token_secret = "yoursecret";


$connection = new TwitterOAuth(config('app.twitter_client_id'), config('app.twitter_client_secret'), $token, $token_secret);
$connection->setApiVersion("2");
$result = $connection->post("tweets", ["text" => time()."API v2のテスト"], true); # trueを忘れないように
```

これでツイートできるようになる。
このとき、tokenとtoken_secretなどは、v1の情報と同じものを使用できる。

# me

制限
250 requests / 24 hours
PER USER

app単位の制限は無いので実質使い放題。


```

        $params = [
            "tweet.fields" => "author_id,created_at", // 今回は追加で投稿日時を指定
            'expansions' => 'pinned_tweet_id',
            "user.fields" => "id,name,username,description,profile_image_url",//画像サイズは _normal を消せばオリジナルサイズになる
        ];


        $result = $connection->get("users/me",$params); # trueを忘れないように

```

結果
```
stdClass Object
(
    [data] => stdClass Object
        (
            [profile_image_url] => https://pbs.twimg.com/profile_images/1638515977901215745/4LVwuR4v_normal.jpg
            [pinned_tweet_id] => 1595270465536
            [username] => xxx_555
            [id] => 33340879
            [description] => ここにプロフィールが入るよ。変更すると。
            [name] => あみ
        )

    [errors] => Array
        (
            [0] => stdClass Object
                (
                    [value] => 1555536
                    [detail] => Could not find tweet with pinned_tweet_id: [1528635695270465536].
                    [title] => Not Found Error
                    [resource_type] => tweet
                    [parameter] => pinned_tweet_id
                    [resource_id] => 152836
                    [type] => https://api.twitter.com/2/problems/resource-not-found
                )

        )

)

```

# ツイートを取得

長文も取得するように
//GET /2/users/:id/tweets
//5 requests / 15 mins
//PER USER
//10 requests / 15 mins
//APPS

```
$tweet_id = '3330';

$params = [
    "tweet.fields" => "author_id,created_at,text,entities,note_tweet",
    "expansions" => "attachments.media_keys",
    "media.fields" => "url"
];

$res = $this->client->get("tweets/".$tweet_id, $params);
```


# lookup

```
$params = [
    "ids" => '125023968,234287107',//ユーザーIDを指定 100まで
    "tweet.fields" => "author_id,created_at", // 今回は追加で投稿日時を指定
    'expansions' => 'pinned_tweet_id',
    "user.fields" => "id,name,username,description,profile_image_url",//画像サイズは _normal を消せばオリジナルサイズになる
];

$result = $connection->get("users", $params); # trueを忘れないように

```


# 指定ユーザーがした、いいねを取得

```

//いいねを取得
$params = [
    "tweet.fields" => "author_id,created_at",
    'expansions' => '',
    "user.fields" => "name,username,description,profile_image_url",
];

$res = $this->client->get("users/ユーザーID/liked_tweets", $params);

```

制限を過ぎると

15分で 5リクエスト。
5 requests / 15 mins
PER APP
5 requests / 15 mins
PER USER

```
stdClass Object
(
    [title] => Too Many Requests
    [detail] => Too Many Requests
    [type] => about:blank
    [status] => 429
)
```

# 指定ツイートに誰がいいねをしているか取得

```
$params = [
    "tweet.fields" => "author_id,created_at",
    'expansions' => '',
    "user.fields" => "name,username,description,profile_image_url",
];

$res = $this->client->get("tweets/1804792774749016514/liking_users", $params);

```

```
stdClass Object
(
    [data] => Array
        (
            [0] => stdClass Object
                (
                    [profile_image_url] => https://pbs.twimg.com/profile_images/1638515977901215745/4LVwuR4v_normal.jpg
                    [id] => 3330879
                    [name] => あみ
                    [username] => ami33n_555
                    [description] => ここにプロフィールが入るよ。変更すると。
                )

        )

    [meta] => stdClass Object
        (
            [result_count] => 1
            [next_token] => 7140dibdnow9c7btw4azvbuvul65ufjmtwr6xzembq3hz
        )

)
```



# ベアラートークンの取得

v1からv2にすると、ベアラートークンを見ようと思うとリセットされてしまう。
そこでphpから取得する。

```
        //ベアラートークンを取得
        // APIキーとAPIシークレットキーを設定します
        $api_key = config('app.twitter_client_id');
        $api_secret_key = config('app.twitter_client_secret');


// ベース64でエンコードされた認証情報を作成します
        $auth_credentials = base64_encode($api_key . ':' . $api_secret_key);

// Twitter APIのBearer Tokenを取得するためのリクエストを作成します
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, 'https://api.twitter.com/oauth2/token');
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Authorization: Basic ' . $auth_credentials,
            'Content-Type: application/x-www-form-urlencoded;charset=UTF-8'
        ));
        curl_setopt($ch, CURLOPT_POSTFIELDS, 'grant_type=client_credentials');

// リクエストを実行して、レスポンスを取得します
        $response = curl_exec($ch);
        curl_close($ch);

// レスポンスからBearer Tokenを抽出します
        $bearer_token = json_decode($response)->access_token;

// 取得したBearer Tokenを出力します
        echo $bearer_token;
```

phpのバージョンが合わない

php7.1 だと twitterabrahamが使えない。
phpをアップデートするリスクを考慮すると他のライブラリを使うほうが良さそうだ。

以下なら使える。
https://github.com/ferrysyahrinal/twifer

```
        $config = Configure::read('Signup.twitter');

        //
        $token = "8fea3";
        $token_secret = "yA8SMHCXefaMABdd5o";

        $conn = new API($config['consumerKey'], $config['consumerSecret'], $token, $token_secret);


        $text = "ヤフーのurl https://yahoo.co.jp";

        $postfields = "{\"text\":\"".$text."\"}";


        $res = $conn->request('POST', '/2/tweets', $postfields);
        print_r($res);//最後twwets/とスラッシュはつけない！

        //Array ( [data] => Array ( [edit_history_tweet_ids] => Array ( [0] => 1643927152893763586 ) [id] => 1643927152893763586 [text] => ヤフーのurl https://t.co/gL129iYnG0 ) )

```

# ツイートを削除

```
$tweet_id = "1644587228742705152";
$res = $conn->request('DELETE', '/2/tweets/'.$tweet_id);//最後に スラッシュはつけない /tweets/ にすると駄目
```

# lookup

指定したユーザーの情報を取得

```
$res = $conn->request('GET', '/2/users/1402103725');//最後に スラッシュはつけない /tweets/ にすると駄目

```

# フォローする

```
        $target_user_id = 1402103725;//フォローしたいユーザーのID
        $from_user_id = 871228321580711941;

        $postfields = "{\"target_user_id\":\"".$target_user_id."\"}";
        $res = $conn->request('POST', '/2/users/'.$from_user_id.'/following', $postfields);//最後に スラッシュはつけない /tweets/ にすると駄目


        pd($res);

//        Array
//        (
//            [data] => Array
//            (
//                [following] => 1
//            [pending_follow] =>
//        )

)

```


twiferだと、 /2/users/me/ で画像を取得できない。
なので直書きで強引に取得する方法

```hoge.php
    public function buildBaseString($baseURI, $method, $params) {


        $r = array();
        ksort($params);
        foreach ($params as $key => $value) {
            $r[] = "$key=" . rawurlencode($value);
        }

        return $method . "&" . rawurlencode($baseURI) . '&' . rawurlencode(implode('&', $r));
    }

    public function buildAuthorizationHeader($oauth) {
        $r = 'Authorization: OAuth ';
        $values = array();
        foreach ($oauth as $key => $value) {
            $values[] = "$key=\"" . rawurlencode($value) . "\"";
        }
        $r .= implode(', ', $values);
        return $r;
    }

    public function test()
    {

        $config = Configure::read('Signup.twitter');

        //helpee
        $token = "your";
        $token_secret = "yoursec";

        $url = "https://api.twitter.com/2/users/me";
        $query = http_build_query([
            'user.fields' => 'id,name,username,description,profile_image_url'
        ]);
        $full_url = $url . '?' . $query;

        $oauth_access_token = $token;
        $oauth_access_token_secret = $token_secret;
        $consumer_key = $config['consumerKey'];
        $consumer_secret = $config['consumerSecret'];


        $oauth = array(
            'oauth_consumer_key' => $consumer_key,
            'oauth_nonce' => time(),
            'oauth_signature_method' => 'HMAC-SHA1',
            'oauth_timestamp' => time(),
            'oauth_token' => $oauth_access_token,
            'oauth_version' => '1.0'
        );

        $base_info = $this->buildBaseString($url, 'GET', array_merge($oauth, ['user.fields' => 'id,name,username,description,profile_image_url']));
        $composite_key = rawurlencode($consumer_secret) . '&' . rawurlencode($oauth_access_token_secret);
        $oauth_signature = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
        $oauth['oauth_signature'] = $oauth_signature;

        $header = array(
            $this->buildAuthorizationHeader($oauth),
            'Content-Type: application/x-www-form-urlencoded',
            'User-Agent: My Twitter App v1.0.23'
        );

        $options = array(
            CURLOPT_HTTPHEADER => $header,
            CURLOPT_HEADER => false,
            CURLOPT_URL => $full_url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_SSL_VERIFYPEER => false
        );

        $ch = curl_init();
        curl_setopt_array($ch, $options);
        $response = curl_exec($ch);
        curl_close($ch);

        $result = json_decode($response);
        echo "User ID: " . $result->data->id . PHP_EOL;
        echo "Name: " . $result->data->name . PHP_EOL;
        echo "Username: " . $result->data->username . PHP_EOL;
        echo "Description: " . $result->data->description . PHP_EOL;
        echo "Profile Image URL: " . $result->data->profile_image_url . PHP_EOL;

    }

```


# cakephp2 で強引にtwifer

うーん。cakephp2だとさすがにライブラリが全滅している。
ということで、嬉し恥ずかし、vendors直入れ

1 まずは twiferのサイトから twiferをDL
2 vendors フォルダに入れてアップロード
3 以下のような感じで強引に読み込み、使う

```
require_once(VENDORS."twifer/src/API.php");
use Twifer\API;


class HogesController extends AppController {




    public function index()
    {
		$config = Configure::read('Caketweet');


		pd($config);

		$conn = new API($config['APIkey'], $config['APIsecret'], $config['Access token'], $config['Access token secret']);
		$text = "ヤフーのurl https://yahoo.co.jp";

		$postfields = "{\"text\":\"".$text."\"}";


		$res = $conn->request('POST', '/2/tweets', $postfields);
		print_r($res);//最後twwets/とスラッシュはつけない

```