Twitter OAuth Rest Api Status Option "@"

I use twitter rest api, which is ( https://api.twitter.com/1.1/ ).

First of all, I used the signpost library to generate oauth_signature. It works well.

The download status endpoint ( https://api.twitter.com/1.1/statuses/upload.json ) works well, but if the status parameter contains '@' , that doesn't work. So here is my code

TwitterStatusesService.java

import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.http.GET; import retrofit2.http.POST; import retrofit2.http.Path; import retrofit2.http.Query; public interface TwitterStatusesService { @POST("/1.1/statuses/update.json") Call<ResponseBody> update(@Query("status") String status, @Query("in_reply_to_status_id") String inReplyToStatusId, @Query("lat") Double lat, @Query("long") Double lon, @Query("media_ids") String mediaIds); } 

TwitterStatusesAPIClient.java

 import android.util.Log; import com.twitter.sdk.android.core.TwitterAuthToken; import com.twitter.sdk.android.core.TwitterCore; import com.twitter.sdk.android.core.TwitterSession; import okhttp3.OkHttpClient; import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.Retrofit; import se.akerfeldt.okhttp.signpost.OkHttpOAuthConsumer; import se.akerfeldt.okhttp.signpost.SigningInterceptor; public class TwitterStatusesClient { private final String TAG = getClass().getSimpleName(); private static final String BASE_URL = "https://api.twitter.com/"; private final TwitterStatusesService apiService; private static TwitterStatusesClient webServiceClient; public static TwitterStatusesClient getInstance() { if (webServiceClient == null) webServiceClient = new TwitterStatusesClient(); return webServiceClient; } private TwitterStatusesClient() { private TwitterStatusesClient() { OkHttpOAuthConsumer consumer = new OkHttpOAuthConsumer(TWITTER_KEY, TWITTER_SECRET); TwitterSession activeSession = TwitterCore.getInstance().getSessionManager().getActiveSession(); if (activeSession != null) { TwitterAuthToken authToken = activeSession.getAuthToken(); String token = authToken.token; String secret = authToken.secret; consumer.setTokenWithSecret(token, secret); } OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(new SigningInterceptor(consumer)) .build(); Retrofit retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .client(client) .build(); apiService = retrofit.create(TwitterStatusesService.class); } public Call<ResponseBody> update(String status, String statusId, Double lat, Double lon, String mediaIds) { return apiService.update(status, statusId, lat, lon, mediaIds); } } 

call api client

 String status = "@example"; TwitterStatusesClient.getInstance().update(status, null, null, null, null).enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { Log.v(TAG, "onResponse"); progressDialog.dismiss(); try { if (response.errorBody() != null) { String error = response.errorBody().string(); Log.e(TAG, "Error : " + error); ToastUtils.showErrorMessage(getContext(), "Error : " + error); return; } String body = response.body().string(); Log.v(TAG, "body : " + body); } catch (Exception e) { e.printStackTrace(); } } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { Log.v(TAG, "onFailure"); t.printStackTrace(); } }); 

mistake:

 {"errors":[{"code":32,"message":"Could not authenticate you."}]} 

but if I use the status variable “just example” instead of “@example” (a specific point removes the @ symbol), which works. only the "@" character does not work.

EDIT

This is my manual creation of OAuth v1.0a signature signing code via interceptor:

 OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(new Interceptor() { @Override public Response intercept(Interceptor.Chain chain) throws IOException { Request request = chain.request(); String method = request.method(); String baseUrl = "https://api.twitter.com" + request.url().url().getPath(); String oauthToken = ""; String oauthTokenSecret = ""; TwitterSession activeSession = TwitterCore.getInstance().getSessionManager().getActiveSession(); if (activeSession != null) { TwitterAuthToken authToken = activeSession.getAuthToken(); oauthToken = authToken.token; oauthTokenSecret = authToken.secret; } String oauthNonce = "TXZScw4M8TG"; String oauthSignatureMethod = "HMAC-SHA1"; String oauthTimestamp = String.valueOf(System.currentTimeMillis() / 1000); String oauthVersion = "1.0"; String parameterString = ""; parameterString = OAuthParams.addParam(request, parameterString, "count"); parameterString = OAuthParams.addParam(request, parameterString, "id"); parameterString = OAuthParams.addParam(request, parameterString, "in_reply_to_status_id"); // if any parameter added to parameterString, append '&' character. if (parameterString.length() > 0) { parameterString += "&"; } parameterString += "oauth_consumer_key=" + TWITTER_KEY + "&" + "oauth_nonce=" + oauthNonce + "&" + "oauth_signature_method=" + oauthSignatureMethod + "&" + "oauth_timestamp=" + oauthTimestamp + "&" + "oauth_token=" + oauthToken + "&" + "oauth_version=" + oauthVersion; // add status parameter to parameterString. parameterString = OAuthParams.addParam(request, parameterString, "status"); Log.d(TAG, "normalizedParameters : " + parameterString); Log.d(TAG, "parameterStringPercent : " + OAuth.percentEncode(parameterString)); String signatureBaseString = ""; signatureBaseString += OAuth.percentEncode(method) + "&"; signatureBaseString += OAuth.percentEncode(baseUrl) + "&"; signatureBaseString += OAuth.percentEncode(parameterString); String oauthSignature = OauthSignature.generateSignature(signatureBaseString, TWITTER_SECRET, oauthTokenSecret); String authorization = "OAuth oauth_consumer_key=\"" + TWITTER_KEY + "\", " + "oauth_signature_method=\"HMAC-SHA1\", " + "oauth_timestamp=\"" + oauthTimestamp + "\", " + "oauth_nonce=\"" + oauthNonce + "\", " + "oauth_version=\"1.0\", " + "oauth_token=\"" + oauthToken + "\", " + "oauth_signature=\"" + OAuth.percentEncode(oauthSignature) + "\""; Log.w(TAG, "Authorization : " + authorization); request = request.newBuilder() .addHeader("Authorization", authorization) .build(); return chain.proceed(request); } }).addInterceptor(interceptor).build(); 

OAuth.java

 public static String percentEncode(String s) { if (s == null) { return ""; } try { return URLEncoder.encode(s, ENCODING) // OAuth encodes some characters differently: .replace("+", "%20").replace("*", "%2A") .replace("%7E", "~"); // This could be done faster with more hand-crafted code. } catch (UnsupportedEncodingException wow) { throw new RuntimeException(wow.getMessage(), wow); } } 

OAuthSignature.java

 import android.util.Base64; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; public class OauthSignature { public static String generateSignature(String signatueBaseStr, String oAuthConsumerSecret, String oAuthTokenSecret) { byte[] byteHMAC = null; try { Mac mac = Mac.getInstance("HmacSHA1"); SecretKeySpec spec; if (null == oAuthTokenSecret) { String signingKey = OAuth.percentEncode(oAuthConsumerSecret) + '&'; spec = new SecretKeySpec(signingKey.getBytes(), "HmacSHA1"); } else { String signingKey = OAuth.percentEncode(oAuthConsumerSecret) + '&' + OAuth.percentEncode(oAuthTokenSecret); spec = new SecretKeySpec(signingKey.getBytes(), "HmacSHA1"); } mac.init(spec); byteHMAC = mac.doFinal(signatueBaseStr.getBytes()); } catch (Exception e) { e.printStackTrace(); } return new String(Base64.encode(byteHMAC, Base64.DEFAULT)); } } 
+7
android oauth twitter retrofit2 twitter-rest-api
source share
2 answers

I suggest going with the fabric - https://fabric.io , which has the tweeters of various libraries such as twitter login, crashlytics and alss, you need to configure the fabric plugin using android studio. Publish that you will be able to send / receive tweets, no matter what you want to publish.

For your question, check that the "@" character is a special character, where a problem arises through modification. Such problems come up with the modernization that I encountered in different scenarios.

Try using Cloth for Twitter Login / oAuth

+4
source share

You must encode your URL, @ =>% 40. It works fine, I was tried (y).

0
source share

All Articles