Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting 403 forbidden when using Twitter Fabric to get user_timeline

I've been trying to implement Fabric to get a list of the 5 latest tweet from a user. It worked great for a few hours and then it stopped working. I would like to do this without having the user log in, and as far as I can tell the API allows guest-logins to read tweets, but maybe this has a greater effect on the Rate Limit?

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    TwitterAuthConfig authConfig = new TwitterAuthConfig(TWITTER_KEY, TWITTER_SECRET);
    Fabric.with(this, new Twitter(authConfig), new Crashlytics());
    TwitterCore.getInstance().logInGuest(new Callback() {
        @Override
        public void success(Result result) {
            AppSession session = (AppSession) result.data;
            getTweets();
        }

        @Override
        public void failure(TwitterException exception) {
            // unable to get an AppSession with guest auth
        }
    });
}

    public void getTweets() {

    TwitterApiClient twitterApiClient = TwitterCore.getInstance().getApiClient();
    StatusesService statusesService = twitterApiClient.getStatusesService();


    statusesService.userTimeline([USERID], null, 5, null, null, null, true, null, false, new Callback<List<Tweet>>() {
        @Override
        public void success(Result <List<Tweet>> result) {

            for(Tweet Tweet : result.data) {
                tweetList.add(Tweet.text);
            }
            createListView();
        }
        public void failure(TwitterException exception) {
            Log.e("Failure", exception.toString());
            exception.printStackTrace();
        }
    });
}

When I don't get the 403 everything works perfectly and my list gets populated.

Now, it's entirely possible that there is just something wrong my code that gets me rate limit blacklisted? Otherwise; do I need have the user log in just to show them 5 tweets? Or should I implement some sort of serverside-cache?

Thankful for any tips/help.

like image 467
Jens Hendar Avatar asked Feb 11 '23 21:02

Jens Hendar


2 Answers

I think I might have it figured out. Looks like you have to save the session from the success method in the logInGuest callback and then pass that to getApiClient. Here's some code that's working for me so far:

private TweetViewFetchAdapter adapter;
...
adapter = new TweetViewFetchAdapter<CompactTweetView>(getActivity());
...
TwitterCore.getInstance().logInGuest( new Callback<AppSession>() {
    @Override
    public void success(Result<AppSession> appSessionResult) {
        AppSession session = appSessionResult.data;
        TwitterApiClient twitterApiClient =  TwitterCore.getInstance().getApiClient(session);
        twitterApiClient.getStatusesService().userTimeline(null, "RadioOkinawa864", 10, null, null, false, false, false, true, new Callback<List<Tweet>>() {
            @Override
            public void success(Result<List<Tweet>> listResult) {
                adapter.setTweets(listResult.data);
            }

            @Override
            public void failure(TwitterException e) {
                Toast.makeText(getActivity().getApplicationContext(), "Could not retrieve tweets", Toast.LENGTH_SHORT).show();
                e.printStackTrace();
            }
        });
    }

    @Override
    public void failure(TwitterException e) {
        Toast.makeText(getActivity().getApplicationContext(), "Could not get guest Twitter session", Toast.LENGTH_SHORT).show();
        e.printStackTrace();
    }
});
like image 86
Mark Duncan Avatar answered Feb 13 '23 10:02

Mark Duncan


When using logInGuest, be aware that guest AppSessions will expire after some time. Your application must handle expiration TwitterExceptions and request another guest AppSession. For example,

TwitterApiClient twitterApiClient =  TwitterCore.getInstance().getApiClient(guestAppSession);
twitterApiClient.getSearchService().tweets("#fabric", null, null, null, null, 50, null, null, null, true, new Callback<Search>() {
    @Override
    public void success(Result<Search> result) {
        // use result tweets
    }

    @Override
    public void failure(TwitterException exception) {
        final TwitterApiException apiException = (TwitterApiException) exception;
        final int errorCode = apiException.getErrorCode();
        if (errorCode == TwitterApiConstants.Errors.APP_AUTH_ERROR_CODE || errorCode == TwitterApiConstants.Errors.GUEST_AUTH_ERROR_CODE) {
            // request new guest AppSession (i.e. logInGuest)
            // optionally retry
        }
    }
});

Note that AppSessions may only be used to make API requests that do not require a user context. For example, you cannot Tweet with an AppSession. You can get a user's timeline of public Tweets. See TwitterKit Android REST API docs.

Finally, if you are using the TweetUtils.loadTweet or TweetUtils.loadTweets helpers from the TweetUi kit of the Twitter kit group, setting up guest auth and handling expiration is performed automatically, you need not call logInGuest yourself.

like image 37
dgh Avatar answered Feb 13 '23 10:02

dgh