1

I'm trying to obtain a list of a user's tweets and I've run into some trouble when trying to authenticate my call to the API. I currently get a 401 when executing the code below:

    public interface TwitterApi {

    String API_URL = "https://api.twitter.com/1.1";

    String CONSUMER_KEY = "<CONSUMER KEY GOES HERE>";
    String CONSUMER_SECRET = "<CONSUMER SECRET GOES HERE>";
    String ACCESS_TOKEN = "<ACCESS TOKEN GOES HERE>";
    String ACCESS_TOKEN_SECRET = "<ACCESS TOKEN SECRET GOES HERE>";

      @GET("/statuses/user_timeline.json")
      List<Tweet> fetchUserTimeline(
            @Query("count") final int count,
            @Query("screen_name") final String screenName);
      }

The following throws a 401 Authorisation error when calling fetchUserTimeline()

RetrofitHttpOAuthConsumer consumer = new RetrofitHttpOAuthConsumer(TwitterApi.CONSUMER_KEY, TwitterApi.CONSUMER_SECRET);
        consumer.setTokenWithSecret(TwitterApi.ACCESS_TOKEN, TwitterApi.ACCESS_TOKEN_SECRET);
        RestAdapter restAdapter = new RestAdapter.Builder()
                .setEndpoint(TwitterApi.API_URL)
                .setClient(new SigningOkClient(consumer))
                .build();


        TwitterApi twitterApi = restAdapter.create(TwitterApi.class)

        tweets = twitterApi.fetchUserTimeline(2, screenName);

I've also included the relevant code from the signpost-retrofit plugin:

public class SigningOkClient extends OkClient {

    private final RetrofitHttpOAuthConsumer mOAuthConsumer;

    public SigningOkClient(RetrofitHttpOAuthConsumer consumer) {
        mOAuthConsumer = consumer;
    }

    public SigningOkClient(OkHttpClient client, RetrofitHttpOAuthConsumer consumer) {
        super(client);
        mOAuthConsumer = consumer;
    }

    @Override
    public Response execute(Request request) throws IOException {
        Request requestToSend = request;
        try {
            HttpRequestAdapter signedAdapter = (HttpRequestAdapter) mOAuthConsumer.sign(request);
            requestToSend = (Request) signedAdapter.unwrap();
        } catch (OAuthMessageSignerException | OAuthExpectationFailedException | OAuthCommunicationException e) {
            // Fail to sign, ignore
            e.printStackTrace();
        }
        return super.execute(requestToSend);
    }

}

The signpost-retrofit plugin can be found here: https://github.com/pakerfeldt/signpost-retrofit

public class RetrofitHttpOAuthConsumer extends AbstractOAuthConsumer {

  private static final long serialVersionUID = 1L;

  public RetrofitHttpOAuthConsumer(String consumerKey, String consumerSecret) {
    super(consumerKey, consumerSecret);
  }

  @Override
  protected HttpRequest wrap(Object request) {
      if (!(request instanceof retrofit.client.Request)) {
        throw new IllegalArgumentException("This consumer expects requests of type " + retrofit.client.Request.class.getCanonicalName());
      }
      return new HttpRequestAdapter((Request) request);
  }
}

Any help here would be great. The solution doesn't have to include the use of signpost but I do want to use Retrofit. I also do not want to show the user an 'Authenticate with Twitter' screen in a WebView - I simply want to display a handful of relevant tweets as part of a detail view.

HBG
  • 1,731
  • 2
  • 23
  • 35

1 Answers1

0

Are you certain the signpost-retrofit project works for twitter oauth? I've used twitter4j successfully in the past - and if you don't want the full library you can use their code for reference. twitter4j

Bruce Hamilton
  • 500
  • 4
  • 11
  • According to this Gist it does work: https://gist.github.com/billynyh/9e96d228b0e64c7c3251 – HBG May 05 '15 at 13:19