TwitterAPI v2に切り替えることになりました（TwitterOAuthでの移行）

## TwitterAPIの有料化とv1.1の廃止
TwitterAPI v1.1がついに使えなくなりました。2023年2月頃から発表されていたいようですが、私は5月になって知りました。正直なところDeveloper Portalにはそんなこと何も書いていないかったし、ずっと半信半疑だったのです。でも、それは悪い情報から目を背けたかっただけでした。だって、今回の仕様変更で
- FREE
- BASIC
- PRO

という３段階のプランができてFREEでは使えるエンドポイントはたったの３つです。
- POST /2/tweets
- DELETE /2/tweets/:id
- GET /2/users/me

これで何がつらいかというと、
`GET /2/users/:id/tweets`
はエンドポイントから外れているということです。
要するに**APIを通じてできるのは、投稿だけで、閲覧に関してはユーザーのプロフィールだけですよ**ということです。
**自分のツイートのタイムラインも取れない**ということです。
さらに、投稿できるのも**１日５０ツイートまでかつ月１５００ツイートまで**と大幅に数量制限もかかりました。
それで問題があるなら上のランクのプランに格上げしてねということですが、その上のBASICからは有料で、BASICは月１００＄、PROは月５０００＄というんです。日本円にしたらBASICで月１万円以上、PROで月６０万円以上になります。とてもフリーランスのWeb制作者が払える金額ではありません。
したがって、FREEでできる範囲に機能を限定せざるを得ません。それでも無料で利用できる枠を残してくれただけでも良しとせざるを得ませんかね。

そして、問題は残されたエンドポイント
- POST /2/tweets
- DELETE /2/tweets/:id

ですが、ご覧のとおり、これってAPIバージョンが２なんです。ですから、今までv1.1のエンドポイントをv2のエンドポイントに切り替えないといけません。これまで、移行期間でv1.1のエンドポイントで使えていたのですが、ついに使えなくなりました（私が2023/6/16に確認したということでいつから使えていなかったかは不明です。）。
今までできていた自動投稿が無情にもエラーを出してしまったのです。

いずれ手入れしなければいけなかったので、重い腰を上げる機会になりました。

v1.1とv2の比較は以下のサイトにあります。
https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/migrate
しかし、わたしはTwitterOAuthというライブラリを使っているので、これだけ見てもよくわかりません。
それともう一つ非常に気になるのが、画像や動画付きのツイートはできるのかということです。

ということで、以下の３点が課題となりました。
TwitterOAuthを使うことを前提として

1. v1.1およびv2でのツイートの方法の違いの把握
2. 画像や動画付きのツイート
3. v1.1およびv2でのツイートの削除方法の違いの把握

これらの課題を何とか克服することができたので、そのノウハウを情報提供させていただくことにします。同じ課題を抱えておられる方のお役に立てば幸いです。

## v1.1およびv2でのツイートの方法の違いの把握
早速コードからお見せします。

v1.1のコード
```
require_once "vendor/autoload.php";

use Abraham\TwitterOAuth\TwitterOAuth;

$apiKey            = "your_api_key";
$apiSecret         = "your_api_secret";
$accessToken       = "your_access_token";
$accessTokenSecret = "your_access_token_secret";

$connection = new TwitterOAuth($apiKey, $apiSecret, $accessToken, $accessTokenSecret);
$result = $connection->post("statuses/update", ["status" => "API v1.1のテスト"]);
```


v2のコード
```
require_once "vendor/autoload.php";

use Abraham\TwitterOAuth\TwitterOAuth;

$apiKey            = "your_api_key";
$apiSecret         = "your_api_secret";
$accessToken       = "your_access_token";
$accessTokenSecret = "your_access_token_secret";

$connect = new TwitterOAuth($apiKey, $apiSecret, $accessToken, $accessTokenSecret);
$connect->setApiVersion("2");・・・⓵
$result = $connect->post("tweets", ["text" => "API v2のテスト"], true); # trueを忘れないように・・・⓶
```
ポイントは３つあります。
1. TwitterOAuthのオブジェクトを①でv2用にしておくこと。
2. ②のとおりエンドポイントがstatuses/updateからtweetsに変わり、POSTするオブジェクトのキーがstatusからtweetsに変わっていること。
3. POSTするデータの形式はJSONとなるので、POSTメソッドの第3引数をtrueにすること

## 画像や動画付きのツイート
これが今回の大きな課題でした。すこし、この手のツイートの仕組みを説明しておきます。


![画像や動画付き投稿の仕組み.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124662/b0fd6848-8a87-e501-97af-c374f538fc4b.jpeg)

この図解のとおり②でAPIが必要です。このAPIはどうなっているのか。この情報がなかなか見つかりませんでした。
結論をいうと、このAPIはまだv2には存在していません。
こちらのページで確認できます。
https://developer.twitter.com/en/docs/twitter-api/migrate/twitter-api-endpoint-map

![Twitter Develope.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124662/4a1430fa-2674-f518-2c2d-5b01abddeedb.png)


つまり、このエンドポイントはv.1.1のものを使います。したがって、先に説明した「１．TwitterOAuthを①でv2用にしておくこと。」は **やってはいけません。** これをするとIDは返ってきません。
ということでコードはこのようになります。

v1.1、v2共通
```
require_once "vendor/autoload.php";

use Abraham\TwitterOAuth\TwitterOAuth;

$apiKey            = "your_api_key";
$apiSecret         = "your_api_secret";
$accessToken       = "your_access_token";
$accessTokenSecret = "your_access_token_secret";

$connect = new TwitterOAuth($apiKey, $apiSecret, $accessToken, $accessTokenSecret);
//画像や動画のアップロード
if($img_list){
    foreach($img_list as $img_url){
        //画像や動画のダウンロード
        $image = file_get_contents($img_url, false, stream_context_create($options));
        //一時保存場所
        $save_path = SNS_PLUGIN_PATH.'/img/temp'.$ext;
        //ファイルのダウンロードに成功した場合
        if(file_put_contents($save_path, $image)){
          $up_result = $connect->upload('media/upload', [
            'media'=>$save_path,
          ]);・・・⓵
          $media[]= $up_result->media_id_string;・・・⓶
        }
      }
    }
  }

```
v1.1
```
//続きです
//ツイートを実行
  
  $result = $connect->post('statuses/update', [
      'status' => $content,
      'media_ids' => implode(',', $media),・・・⓷
    ];);
}

```
v2
```
//続きです
//ツイートを実行
  $connect->setApiVersion('2');・・・⓸
  $result = $connect->post('tweets', [
      'text' => $content,
      'media' => [
        'media_ids' => $media,
      ]・・・⓹
    ];);
}

```
①が画像や動画をアップロードするAPIです。これはFREEでも使えました（ありがたかった）。
②で無事にアップロードした画像や動画のIDが蓄積されました。この時、$connect（TwitterOAuthオブジェクト）はv1.1用になっています。
v1.1ではエンドポイントはstatuses/updateでテキストはstatusのキーをつけたオブジェクトで渡すのは先に説明したとおりですが、画像や動画のIDは③のようにmedia_idsというキーを持ち、カンマ区切りの文字列を値とするオブジェクトを渡していました。

v2では、ここからAPIの使用方法が変わります。
④で$connect（TwitterOAuthオブジェクト）をv2用に切り替えます。
⑤には２つのポイントがあります。
1. 画像や動画のIDの渡し方ですmediaというキーを持つオブジェクト内にmedia_idsというキーを持つオブジェクトを入れて渡すということ。
2. もう一つはmedia_idsというキーを持つオブジェクトには配列を渡すこと。

この２つです。
これを間違うと容赦なくエラーが返ります。
１日５０回した使えないツイートを無駄に消費しないようにしましょう。

## v1.1およびv2でのツイートの削除方法の違いの把握
これはエンドポイントとオブジェクトの渡し方がわかれば簡単です。コードを示します。
v1.1
```
require_once "vendor/autoload.php";

use Abraham\TwitterOAuth\TwitterOAuth;

$apiKey            = "your_api_key";
$apiSecret         = "your_api_secret";
$accessToken       = "your_access_token";
$accessTokenSecret = "your_access_token_secret";

$connect = new TwitterOAuth($apiKey, $apiSecret, $accessToken, $accessTokenSecret);

$id = 'ツイートID';
$statuses = $connect->post("statuses/destroy/".$id, array());・・・⓵
```
v2
```
require_once "vendor/autoload.php";

use Abraham\TwitterOAuth\TwitterOAuth;

$apiKey            = "your_api_key";
$apiSecret         = "your_api_secret";
$accessToken       = "your_access_token";
$accessTokenSecret = "your_access_token_secret";

$connect = new TwitterOAuth($apiKey, $apiSecret, $accessToken, $accessTokenSecret);

$id = 'ツイートID';
$connect->setApiVersion('2');・・・⓶
$response = $connect->delete('tweets/'.$id);・・・⓷

```
①のようにv1.1では、エンドポイントが'statuses/destroy/'.idでした。
これに対して、v2の場合は③のようにエンドポイントが'tweets/'.idで、postメソッドでなく、deleteメソッドを使います。この手法がなかなか見つからず苦労しました。下記のサイトで助かりました。他のエンドポイントの使い方もまとめてあるのできっと参考になると思います。
https://diy-programming.site/twitter/twitter-api-v2/#toc7
$connect（TwitterOAuthオブジェクト）を②でv2用にセットするのを忘れないでください。

ということで何とかv1.1からv2への移行作業が終わりました。私のようにTwitterAPIでアプリを作っている方はきっと大変だろうと思い、役立ててほしいと思って執筆しました。このブログがお役に立てば幸いです。