twitter-api-java-sdk (Twitter API v2) でツイートする

Java から Twitter API にアクセスするときは、[Twitter4J](https://twitter4j.org/) が定番です。
ただ、せっかく新しい Twitter API v2 とそれに対応した公式の [twitter-api-java-sdk](https://github.com/twitterdev/twitter-api-java-sdk) が出ていたので、今回はこちらを使ってみました。
その際の、ツイートするまでの手順とサンプルコードをまとめました。

必要な手順は以下の３つです。

1. 開発者情報を登録
1. "Client ID" と "Client Secret" を取得
1. "Access token" と "Refresh token" を取得
1. Twitter API Java SDK でツイート

# 開発者情報を登録

1. [Twitter Developers](https://developer.twitter.com/en/portal/petition/essential/basic-info) を開く
1. 開発者情報（利用目的など）を入力 ![Ready to build something cool?](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205989/b4d0a07a-c911-d2f5-60c1-5060e1220ddf.png)
1. 開発者契約（Developer Agreement）を承諾して、"Submit" をクリック ![Developer Agreement](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205989/d0ee76b2-f12c-f0b3-2f28-ce7a9d65e6fd.png)
1. メールが送られてくるので、その中の "Confirm your email" をクリック ![Time to verify your email](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205989/fe091497-7fbd-f52f-f4e1-2979cc44e811.png) 

# "Client ID" と "Client Secret" を取得

1. 適当なアプリ名（あとで変更可）を設定して、"Next" をクリック ![Name your App](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205989/a71cd223-798c-91d2-9c26-ea79f3a3302c.png)
1. 値をメモして、"App settings" をクリック ![Here are your keys & tokens](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205989/d3ed5828-e365-e514-72b4-7b706bcab0e7.png)
1. "User authentication settings" の "Set up" をクリック ![App details](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205989/64820c0b-6d70-0084-cddc-7fa9582bc5d4.png)
1. "Callback URL", "Website URL" （適当なURLで大丈夫）を設定して、"Save" をクリック ![App info](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205989/9f382f10-f437-1c31-a2ab-aa0d6fcb66fa.png)
1. "Client ID" と "Client Secret" をメモして、"Done" をクリック ![Here si your OAuth 2.0 Client ID and Client Secret](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205989/2addd414-572f-ae9c-d00c-f0d47155de00.png)

# "Access token" と "Refresh token" を取得

1\. サンプルプログラムをチェックアウト
```
git@github.com:YujiSoftware/twitter-api-java-sdk-sample.git
```

2\. 先ほど取得した Client ID / Client Secret、設定した Callback URL を `twtitter.properties` に書く
```
TWITTER_OAUTH2_CLIENT_ID=xxxx
TWITTER_OAUTH2_CLIENT_SECRET=xxxx
TWITTER_OAUTH2_CALLBACK=https://xxxx
```

3\. oauth を実行（[OAuth.java](https://github.com/YujiSoftware/twitter-api-java-sdk-sample/blob/main/oauth/src/main/java/twitter/api/sample/OAuth.java)）

```
./gradlew oauth:run
```

:::note info
`OAuth.java` の中で、[スコープ(権限)を4つ設定しています](https://github.com/YujiSoftware/twitter-api-java-sdk-sample/blob/main/oauth/src/main/java/twitter/api/sample/OAuth.java#L30)。
* [ツイートするのに必要](https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets)
  * `tweet.read`
  * `tweet.write`
  * `users.read`
* [トークンの更新に必要](https://developer.twitter.com/en/docs/authentication/oauth-2-0/authorization-code)
  * `offline.access`

ほかのスコープが必要な時は、書き換えて再度実行してください。
:::

4\. メッセージ（with URL）が表示されて止まります。  

```
Go to the Authorization URL and authorize your App:
https://twitter.com/i/oauth2/authorize?code_challenge=...
After that paste the authorization code here
>> 
```

以下の手順で、コードを貼り付けます。
1. 表示されている URL ( `https://twitter.com/i/oauth2/authorize?code_challenge=...` ) にブラウザでアクセス
2. "アプリにアクセスを許可" をクリック
3. リダイレクトされるので、そのページの URL の `code` パラメータをコピー (`code=xxxx` の `xxxx` の部分)
4. 貼り付けて、Enter

5\. 以下のメッセージが表示されるので、値をメモ
```
Access token: xxxx
Refresh token: yyyy (may be null)
```

# Twitter API Java SDK でツイート

1\. 先ほど取得した Access token / Refresh token を `twitter.properties` に設定
（Refresh token は、null なら設定不要）
```
TWITTER_OAUTH2_CLIENT_ID=xxxx
TWITTER_OAUTH2_CLIENT_SECRET=xxxx
TWITTER_OAUTH2_ACCESS_TOKEN=xxxx
TWITTER_OAUTH2_REFRESH_TOKEN=yyyy
```

2\. tweet を実行 ([Tweet.java](https://github.com/YujiSoftware/twitter-api-java-sdk-sample/blob/main/tweet/src/main/java/twitter/api/sample/Tweet.java)）
```
./gradlew tweet:run
```

これで、うまくいったら「Hello world!」とツイートされています！

# Access Token の更新

上記で Access Token を発行していますが、**これの有効期限は2時間です。**
この時間を超えてツイートする場合、以下のいずれかの方法で Access Token を更新する必要があります。

* 明示的に `TwitterApi#refreshToken()` を呼び出す
* `TwitterCredentialsOAuth2` のコンストラクタの第5引数 `isOAUth2AutoRefreshToken` に `true` を設定しておく
  * サンプルコード: [Refresh.java](https://github.com/YujiSoftware/twitter-api-java-sdk-sample/blob/main/refresh/src/main/java/twitter/api/sample/Refresh.java)