A guide to working with the Twitter API v2 in Java using twitter-api-java-sdk

Suhem Parack - Jun 17 '22 - - Dev Community

twitter-api-java-sdk is Twitter's official SDK for Java that supports the Twitter API v2 and the academic research product track. In this guide, we will learn how to use the various functionality available in the Twitter API v2, using this twitter-api-java-sdk.

Prerequisite

In order to work with the Twitter API, you need to have a developer account and your API keys and tokens to connect to the API. Learn more on how to obtain these keys and tokens here.

In order to work with twitter-api-java-sdk, make sure you have Java installed on your machine. If you use Maven, add the following dependency:

<dependency>
  <groupId>com.twitter</groupId>
  <artifactId>twitter-api-java-sdk</artifactId>
  <version>2.0.0</version>
</dependency>
Enter fullscreen mode Exit fullscreen mode

For all the examples in this section, you will first need to create an instance of the TwitterApi class and pass it your bearer token. Once you have the instance set up, you will be ready to start using the various functions in this library.

TwitterApi apiInstance = new TwitterApi();
TwitterCredentialsBearer credentials = new TwitterCredentialsBearer("BEARER_TOKEN");
apiInstance.setTwitterCredentials(credentials);
Enter fullscreen mode Exit fullscreen mode

1. Searching for Tweets from the last 7 days

In order to search Tweets from the last 7 days, you can use the tweetsRecentSearch method. You will have to pass it a search query to specify the data that you are looking for. In the example below, we are searching for Tweets from the last 7 days that contain the term covid and we are excluding retweets using -is:retweet.

By default, in your response, you will only get the Tweet ID and Tweet text for each Tweet. If you need additional Tweet fields such as context_annotations, created_at (the time the tweet was created) etc., you can specifiy those fields using the tweetFields parameter, as shown in the example 2. Learn more about available fields here. By default, a request returns 10 Tweets. If you want more than 10 Tweets per request, you can specify that using the maxResults parameter. The maximum Tweets per request for this recent search endpoint is 100.

import java.util.*;

import com.twitter.clientlib.TwitterCredentialsBearer;
import com.twitter.clientlib.ApiException;
import com.twitter.clientlib.api.TwitterApi;
import com.twitter.clientlib.model.*;

public class TwitterApiExample {

    public static void main(String[] args) throws ApiException {

        TwitterApi apiInstance = new TwitterApi();
        TwitterCredentialsBearer credentials = new TwitterCredentialsBearer("BEARER_TOKEN");
        apiInstance.setTwitterCredentials(credentials);

        String query = "covid -is:retweet";

        int maxResults = 100;

        TweetSearchResponse result = apiInstance.tweets().tweetsRecentSearch(query, null, null, null, null, maxResults,
                null, null, null, null, null, null, null, null, null);

        if (result.getData() != null) {
            for (Tweet tweet : result.getData()) {
                System.out.println(tweet.getId());
                System.out.println(tweet.getText());
            }

        }

    }

}
Enter fullscreen mode Exit fullscreen mode

2. Searching for Tweets from the full-archive of public Tweets

If you have access to the academic research product track, you can get Tweets older than 7 days i.e. from the full archive of publicly available Tweets. In order to get these Tweets, make sure to use the bearer token from an app connected to your academic project in the Twitter developer portal. You can use the tweetsFullarchiveSearch method and pass it the search query. As shown in the example below, you can also specify additional Tweet fields such as created_at, lang etc. that you'd like returned for your request to the Twitter API.

Note: Not all Tweets have context_annotations associated with them, which is why, in the sample below, we only print the context_annotations if those are available for a Tweet.

import java.util.*;

import com.twitter.clientlib.TwitterCredentialsBearer;
import com.twitter.clientlib.ApiException;
import com.twitter.clientlib.api.TwitterApi;
import com.twitter.clientlib.model.*;

public class TwitterApiExample {

    public static void main(String[] args) throws ApiException {

        TwitterApi apiInstance = new TwitterApi();
        TwitterCredentialsBearer credentials = new TwitterCredentialsBearer("BEARER_TOKEN");
        apiInstance.setTwitterCredentials(credentials);

        Set<String> tweetFields = new HashSet<>(Arrays.asList("created_at", "lang", "context_annotations"));

        String query = "covid -is:retweet";

        int maxResults = 500;

        TweetSearchResponse result = apiInstance.tweets().tweetsFullarchiveSearch(query, null, null, null, null,
                maxResults, null, null, null, null, tweetFields, null, null, null, null);

        if (result.getData() != null) {
            for (Tweet tweet : result.getData()) {
                System.out.println(tweet.getId());
                if (tweet.getContextAnnotations() != null) {
                    for (ContextAnnotation contextAnnotation : tweet.getContextAnnotations()) {
                        System.out.println(contextAnnotation.getDomain().getName());
                        System.out.println(contextAnnotation.getEntity().getName());
                    }
                }
            }

        }

    }

}
Enter fullscreen mode Exit fullscreen mode

3. Getting Tweets from the full-archive of public Tweets for a specific time-frame

If you want to get Tweets from the full-archive for a specific time-period, you can specify the time-period using the startTime and endTime parameters, as shown in the example below:

import java.time.OffsetDateTime;

import com.twitter.clientlib.TwitterCredentialsBearer;
import com.twitter.clientlib.ApiException;
import com.twitter.clientlib.api.TwitterApi;
import com.twitter.clientlib.model.*;

public class TwitterApiExample {

    public static void main(String[] args) throws ApiException {

        TwitterApi apiInstance = new TwitterApi();
        TwitterCredentialsBearer credentials = new TwitterCredentialsBearer("BEARER_TOKEN");
        apiInstance.setTwitterCredentials(credentials);

        String query = "covid -is:retweet";

        int maxResults = 100;

        OffsetDateTime startTime = OffsetDateTime.parse("2020-01-01T00:00:00Z");

        OffsetDateTime endTime = OffsetDateTime.parse("2021-01-01T11:59:59Z");

        TweetSearchResponse result = apiInstance.tweets().tweetsFullarchiveSearch(query, startTime, endTime, null, null,
                maxResults, null, null, null, null, null, null, null, null, null);

        if (result.getData() != null) {
            for (Tweet tweet : result.getData()) {
                System.out.println(tweet.getId());
                System.out.println(tweet.getText());
            }

        }

    }

}
Enter fullscreen mode Exit fullscreen mode

4. Writing Tweets to a text file

This example shows how you can write the Tweet IDs for each Tweet obtained for a search result, to a text file. Make sure to replace the fileName with the a name of your chosing. If you wish to write other fields to the text file, make sure to adjust the script below accordingly.

import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.time.OffsetDateTime;
import java.util.*;

import com.twitter.clientlib.TwitterCredentialsBearer;
import com.twitter.clientlib.ApiException;
import com.twitter.clientlib.api.TwitterApi;
import com.twitter.clientlib.model.*;

public class TwitterApiExample {

    public static void main(String[] args) throws ApiException, FileNotFoundException, UnsupportedEncodingException {

        TwitterApi apiInstance = new TwitterApi();
        TwitterCredentialsBearer credentials = new TwitterCredentialsBearer("BEARER_TOKEN");
        apiInstance.setTwitterCredentials(credentials);

        String query = "covid -is:retweet";

        int maxResults = 100;

        String fileName = "tweet_ids.txt";

        TweetSearchResponse result = apiInstance.tweets().tweetsFullarchiveSearch(query, null, null, null, null,
                maxResults, null, null, null, null, null, null, null, null, null);

        if (result.getData() != null) {
            PrintWriter writer = new PrintWriter(fileName, "UTF-8");
            for (Tweet tweet : result.getData()) {
                writer.println(tweet.getId());
            }
            writer.close();
        }

    }

}
Enter fullscreen mode Exit fullscreen mode

5. Getting Tweets with user information, for each Tweet

In the examples so far, we have seen how to get Tweet information for the Tweets that we have searched for. However, if you need additional information associated with the Tweet, such as the information of the user Tweeting it, you can use expansions and pass it to the tweetsRecentSearch method.

In this example, we want user information, which is why the value for expansions that we pass is author_id. Additionally, we will specify the userFields that we want returned such as profile_image_url, description (aka user's bio) etc. Learn more about available fields here.

From the response, we will get the users list from the includes object. Then, we will look up the user information for each Tweet, using the author_id of the Tweet.

import java.util.*;

import com.twitter.clientlib.TwitterCredentialsBearer;
import com.twitter.clientlib.ApiException;
import com.twitter.clientlib.api.TwitterApi;
import com.twitter.clientlib.model.*;

public class TwitterApiExample {

    public static void main(String[] args) throws ApiException {

        TwitterApi apiInstance = new TwitterApi();
        // Replace with your own bearer token below
        TwitterCredentialsBearer credentials = new TwitterCredentialsBearer("BEARER_TOKEN");
        apiInstance.setTwitterCredentials(credentials);

        Set<String> tweetFields = new HashSet<>(Arrays.asList("created_at", "lang", "conversation_id"));

        Set<String> userFields = new HashSet<>(Arrays.asList("description", "profile_image_url"));

        Set<String> expansions = new HashSet<>(Arrays.asList("author_id"));

        // Replace with your own query below
        String query = "covid -is:retweet";

        TweetSearchResponse result = apiInstance.tweets().tweetsRecentSearch(query, null, null, null, null, 100, null,
                null, null, expansions, tweetFields, userFields, null, null, null);

        // Create a map with User ID and User Object
        Map<String, User> userMap = new HashMap<>();
        if (result.getIncludes() != null && result.getIncludes().getUsers() != null) {
            List<User> users = result.getIncludes().getUsers();
            for (User user : users) {
                userMap.put(user.getId(), user);
            }
        }

        if (result.getData() != null) {
            for (Tweet tweet : result.getData()) {
                User user = userMap.get(tweet.getAuthorId());
                System.out.println(tweet.getId());
                System.out.println(user.getUsername());
                System.out.println(user.getDescription());
            }

        }

    }

}
Enter fullscreen mode Exit fullscreen mode

6. Searching for geo-tagged Tweets

Some Tweets have geographic information associated with them. The search endpoints in the Twitter API v2 support operators such as place, place_country, bounding_box, point_radius etc. (these operators are currently only available in the academic research product track) that allow you to get these geo-tagged Tweets.

In the example below, we want all Tweets that are from the country US, which is why we specify it in our search query using the place_country:US operator. Now because by default, only the Tweet ID and Tweet text are returned, we have to specify the fact that we want the geo information in our response as well. We do this by setting the expansions to geo.place_id in the tweetsRecentSearch method and we also specify the geo fields that we are looking for.

In our response, we get the list of places from the includes object, and we match on the place_id to get the relevant geo information associated with the Tweet (the place name in the example below)

import java.util.*;

import com.twitter.clientlib.TwitterCredentialsBearer;
import com.twitter.clientlib.ApiException;
import com.twitter.clientlib.api.TwitterApi;
import com.twitter.clientlib.model.*;

public class TwitterApiExample {

    public static void main(String[] args) throws ApiException {

        TwitterApi apiInstance = new TwitterApi();
        TwitterCredentialsBearer credentials = new TwitterCredentialsBearer("BEARER_TOKEN");
        apiInstance.setTwitterCredentials(credentials);

        Set<String> tweetFields = new HashSet<>(Arrays.asList("created_at", "lang", "geo"));

        Set<String> placeFields = new HashSet<>(Arrays.asList("name", "place_type"));

        Set<String> expansions = new HashSet<>(Arrays.asList("geo.place_id"));

        String query = "covid -is:retweet place_country:US";

        TweetSearchResponse result = apiInstance.tweets().tweetsRecentSearch(query, null, null, null, null, 100, null,
                null, null, expansions, tweetFields, null, null, placeFields, null);

        // Create a map with Place ID and Place Object
        Map<String, Place> placeMap = new HashMap<>();
        if (result.getIncludes() != null && result.getIncludes().getPlaces() != null) {
            List<Place> places = result.getIncludes().getPlaces();
            for (Place place : places) {
                placeMap.put(place.getId(), place);
            }
        }

        if (result.getData() != null) {
            for (Tweet tweet : result.getData()) {
                Place place = placeMap.get(tweet.getGeo().getPlaceId());
                System.out.println(tweet.getId());
                System.out.println(place.getName());
            }

        }

    }

}
Enter fullscreen mode Exit fullscreen mode

7. Getting Tweet counts (volume) for a search query

So far, we have seen examples of how to get Tweets for a search query. However, if you want to get the count of Tweets (volume) for a search term, you can use the tweetCountsRecentSearch function. You can pass it the search query and specify the granularity for the data aggregation e.g. if you want the daily count, hourly count or 15-minute count for a search term.

import com.twitter.clientlib.TwitterCredentialsBearer;
import com.twitter.clientlib.ApiException;
import com.twitter.clientlib.api.TwitterApi;
import com.twitter.clientlib.model.*;

public class TwitterApiExample {

    public static void main(String[] args) throws ApiException {

        TwitterApi apiInstance = new TwitterApi();
        TwitterCredentialsBearer credentials = new TwitterCredentialsBearer("BEARER_TOKEN");
        apiInstance.setTwitterCredentials(credentials);

        String query = "covid -is:retweet";

        TweetCountsResponse result = apiInstance.tweets().tweetCountsRecentSearch(query, null, null, null, null, null,
                null, Granularity.DAY);

        if (result.getData() != null) {
            for (SearchCount searchCount : result.getData()) {
                System.out.println(searchCount.getTweetCount());
            }

        }

    }

}
Enter fullscreen mode Exit fullscreen mode

8. Getting a user's timeline

In order to get the most recent 3200 Tweets from a user's timeline, we can use the usersIdTweets method and pass it the user id. We can also specify additional fields that we want using the tweetFields and expansions (as shown in the examples above).

import com.twitter.clientlib.TwitterCredentialsBearer;
import com.twitter.clientlib.ApiException;
import com.twitter.clientlib.api.TwitterApi;
import com.twitter.clientlib.model.*;

public class TwitterApiExample {

    public static void main(String[] args) throws ApiException {

        TwitterApi apiInstance = new TwitterApi();
        TwitterCredentialsBearer credentials = new TwitterCredentialsBearer("BEARER_TOKEN");
        apiInstance.setTwitterCredentials(credentials);

        String userID = "2244994945";

        int maxResults = 100;

        GenericTweetsTimelineResponse result = apiInstance.tweets().usersIdTweets(userID, null, null, maxResults, null,
                null, null, null, null, null, null, null, null, null);

        if (result.getData() != null) {
            for (Tweet tweet : result.getData()) {
                System.out.println(tweet.getId());
            }
        }

    }

}
Enter fullscreen mode Exit fullscreen mode

9. Getting a user's mentions

In order to get the most recent 3200 mentions for a user, we can use the get_users_musersIdMentionsentions method and pass it the user id. We can also specify additional fields that we want using the tweetFields and expansions (as shown in the examples above).

import com.twitter.clientlib.TwitterCredentialsBearer;
import com.twitter.clientlib.ApiException;
import com.twitter.clientlib.api.TwitterApi;
import com.twitter.clientlib.model.*;

public class TwitterApiExample {

    public static void main(String[] args) throws ApiException {

        TwitterApi apiInstance = new TwitterApi();
        TwitterCredentialsBearer credentials = new TwitterCredentialsBearer("BEARER_TOKEN");
        apiInstance.setTwitterCredentials(credentials);

        String userID = "2244994945";

        int maxResults = 100;

        GenericTweetsTimelineResponse result = apiInstance.tweets().usersIdMentions(userID, null, null, maxResults,
                null, null, null, null, null, null, null, null, null);

        if (result.getData() != null) {
            for (Tweet tweet : result.getData()) {
                System.out.println(tweet.getId());
            }
        }

    }

}
Enter fullscreen mode Exit fullscreen mode

10. Getting a user's followers

In order to get the followers of a user, we can use the usersIdFollowers function and pass it the user ID. If we want additional fields for the User object such as profile_image_url, we can specify those using the userFields parameter.

import com.twitter.clientlib.TwitterCredentialsBearer;
import com.twitter.clientlib.ApiException;
import com.twitter.clientlib.api.TwitterApi;
import com.twitter.clientlib.model.*;

public class TwitterApiExample {

    public static void main(String[] args) throws ApiException {

        TwitterApi apiInstance = new TwitterApi();
        TwitterCredentialsBearer credentials = new TwitterCredentialsBearer("BEARER_TOKEN");
        apiInstance.setTwitterCredentials(credentials);

        String userID = "2244994945";

        GenericMultipleUsersLookupResponse result = apiInstance.users().usersIdFollowers(userID, null, null);

        if (result.getData() != null) {
            for (User user : result.getData()) {
                System.out.println(user.getId());
                System.out.println(user.getUsername());
            }
        }

    }

}
Enter fullscreen mode Exit fullscreen mode

11. Getting users that a user follows

In order to get the list of users that a user follows, we can use the usersIdFollowing function and pass it the user ID. If we want additional fields for the User object such as profile_image_url, we can specify those using the userFields parameter.

import com.twitter.clientlib.TwitterCredentialsBearer;
import com.twitter.clientlib.ApiException;
import com.twitter.clientlib.api.TwitterApi;
import com.twitter.clientlib.model.*;

public class TwitterApiExample {

    public static void main(String[] args) throws ApiException {

        TwitterApi apiInstance = new TwitterApi();
        TwitterCredentialsBearer credentials = new TwitterCredentialsBearer("BEARER_TOKEN");
        apiInstance.setTwitterCredentials(credentials);

        String userID = "2244994945";

        UsersFollowingLookupResponse result = apiInstance.users().usersIdFollowing(userID, null, null);

        if (result.getData() != null) {
            for (User user : result.getData()) {
                System.out.println(user.getId());
                System.out.println(user.getUsername());
            }
        }

    }

}
Enter fullscreen mode Exit fullscreen mode

12. Getting users that like a Tweet

In order to get the list of users that like a Tweet, we can use the tweetsIdLikingUsers function and pass it the Tweet ID. If we want additional fields for the User object such as profile_image_url, we can specify those using the userFields parameter.

import com.twitter.clientlib.TwitterCredentialsBearer;
import com.twitter.clientlib.ApiException;
import com.twitter.clientlib.api.TwitterApi;
import com.twitter.clientlib.model.*;

public class TwitterApiExample {

    public static void main(String[] args) throws ApiException {

        TwitterApi apiInstance = new TwitterApi();
        TwitterCredentialsBearer credentials = new TwitterCredentialsBearer("BEARER_TOKEN");
        apiInstance.setTwitterCredentials(credentials);

        String tweetId = "20";

        GenericMultipleUsersLookupResponse result = apiInstance.users().tweetsIdLikingUsers(tweetId, null, null);

        if (result.getData() != null) {
            for (User user : result.getData()) {
                System.out.println(user.getId());
                System.out.println(user.getUsername());
            }
        }

    }

}
Enter fullscreen mode Exit fullscreen mode

13. Getting users that retweeted a Tweet

In order to get the list of users that retweeted a Tweet, we can use the tweetsIdRetweetingUsers function and pass it the Tweet ID. If we want additional fields for the User object such as profile_image_url, we can specify those using the userFields parameter.

import com.twitter.clientlib.TwitterCredentialsBearer;
import com.twitter.clientlib.ApiException;
import com.twitter.clientlib.api.TwitterApi;
import com.twitter.clientlib.model.*;

public class TwitterApiExample {

    public static void main(String[] args) throws ApiException {

        TwitterApi apiInstance = new TwitterApi();
        TwitterCredentialsBearer credentials = new TwitterCredentialsBearer("BEARER_TOKEN");
        apiInstance.setTwitterCredentials(credentials);

        String tweetId = "20";

        GenericMultipleUsersLookupResponse result = apiInstance.users().tweetsIdRetweetingUsers(tweetId, null, null);

        if (result.getData() != null) {
            for (User user : result.getData()) {
                System.out.println(user.getId());
                System.out.println(user.getUsername());
            }
        }

    }

}
Enter fullscreen mode Exit fullscreen mode

14. Getting Tweets that a user liked

In order to get the list of Tweets that a user liked, we can use the usersIdLikedTweets function and pass it the User ID. If we want additional fields for the Tweet object such as context_annotations, created_at etc. we can specify those using the tweetFields parameter.

import com.twitter.clientlib.TwitterCredentialsBearer;
import com.twitter.clientlib.ApiException;
import com.twitter.clientlib.api.TwitterApi;
import com.twitter.clientlib.model.*;

public class TwitterApiExample {

    public static void main(String[] args) throws ApiException {

        TwitterApi apiInstance = new TwitterApi();
        TwitterCredentialsBearer credentials = new TwitterCredentialsBearer("BEARER_TOKEN");
        apiInstance.setTwitterCredentials(credentials);

        String userId = "2244994945";

        UsersIdLikedTweetsResponse result = apiInstance.tweets().usersIdLikedTweets(userId, null, null, null, null,
                null, null, null, null);

        if (result.getData() != null) {
            for (Tweet tweet : result.getData()) {
                System.out.println(tweet.getId());
            }
        }

    }

}
Enter fullscreen mode Exit fullscreen mode

15. Lookup Tweets using Tweet IDs

In some cases, if we have a list of Tweet IDs and want to build the Tweet dataset for these Tweet IDs, we can use the findTweetsById function and pass it the list of Tweet IDs. By default, only the Tweet ID and Tweet text are returned. If we want additional Tweet fields, we can specify those using tweetFields parameter.

import com.twitter.clientlib.TwitterCredentialsBearer;
import com.twitter.clientlib.ApiException;
import com.twitter.clientlib.api.TwitterApi;
import com.twitter.clientlib.model.*;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class TwitterApiExample {

    public static void main(String[] args) throws ApiException {

        TwitterApi apiInstance = new TwitterApi();
        TwitterCredentialsBearer credentials = new TwitterCredentialsBearer("BEARER_TOKEN");
        apiInstance.setTwitterCredentials(credentials);

        List<String> tweetIds = Arrays.asList("1460323737035677698", "1519781379172495360", "1519781381693353984");

        Set<String> tweetFields = new HashSet<>(Arrays.asList("created_at", "lang", "context_annotations"));

        MultiTweetLookupResponse result = apiInstance.tweets().findTweetsById(tweetIds, null, tweetFields, null, null,
                null, null);

        if (result.getData() != null) {
            for (Tweet tweet : result.getData()) {
                System.out.println(tweet.getId());
                System.out.println(tweet.getLang());
                System.out.println(tweet.getCreatedAt().toString());
            }
        }

    }

}
Enter fullscreen mode Exit fullscreen mode

These are some common examples of working with the Twitter API v2 using twitter-api-java-sdk.

If you have any questions or feedback about this guide, please feel free to reach out to me on Twitter!

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .