Twitter Java API: OAuth + REST calls - twitter

I can't make 350 requests (the maximum for the REST API) to the Twitter API, I can only make 150.
So I am getting tweet contents from tweet IDs:
url = new URL("https://api.twitter.com/1/statuses/show.json?id=" + tweetId + "&include_entities=true");
connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("GET");
in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
And before this, I tried to authenticate with this:
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setOAuthConsumerKey(consumerKey);
cb.setOAuthConsumerSecret(consumerSecret);
cb.setOAuthAccessToken(token);
cb.setOAuthAccessTokenSecret(tokenSecret);
Twitter twitter = new TwitterFactory(cb.build()).getInstance();
I suppose I should use the "twitter" variable to call the requests but I don't know how.
Thanks in advance,

Related

Need suggestion on with MS Graph Rest API url

I kinda need to suggestion on picking the accurate MSGraph url between below 2 urls.
https://graph.microsoft.com/v1.0/users/{EmailAddress}.
https://graph.windows.net/{TenantID}/users?$filter=userPrincipalName%20eq%20'{EmailAddress}'&api-version=1.6
More details on my situation:
I need to resolve the UserName and ObjectID from MS Graph Rest api using EmailAddress. I have 100s of EmailAddress that I need to resolve UserName and ObjectID for. I was using below which is working fine for most of the time. But lastnight i realized it is not returning valid response for 2 users.
var httpClient = new HttpClient
{
BaseAddress = new Uri("https://graph.microsoft.com/")
};
string URI = $"/v1.0/users/{EmailAddress}";
Then I realized, below rest API url is retuning accurate response for the missing users as comared to above url
var httpClient = new HttpClient
{
BaseAddress = new Uri("https://graph.windows.net/")
};
string URI = $"/{TenantID}/users?$filter=userPrincipalName%20eq%20'{EmailAddress}'&api-version=1.6";

"Resource not found for the segment 'teams'

I am trying to access Teams-Ressourcec via the Microsoft graph-API. I seem to hit a wall with that. The app has the required permissions (as listed in MS documentation)
Queries I've tried:
A simple GET:
string querystring = "api-version=1.6";
var uri = "https://graph.windows.net/contoso.onmicrosoft.com/teams/" + TeamID+ "/channels?" + querystring;
Console.WriteLine(uri);
HTTPClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", result);
var GetResult = await HTTPClient.GetAsync(uri);
This one works with delegated permissions in Graph Explorer (v1.0) however it uses delegate user permissions, and not app permissions.
POST for migration team reation:
string querystring = "api-version=1.6";
var uri = "https://graph.windows.net/contoso.onmicrosoft.com/teams?" + querystring;
HTTPClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
HttpRequestMessage Content = new HttpRequestMessage();
Content.Content = new StringContent("{ \"#microsoft.graph.teamCreationMode\": \"migration\", \"template#odata.bind\": \"https://graph.microsoft.com/v1.0/teamsTemplates('standard')\", \"displayName\": \"My Sample Migration Team\", \"description\": \"\", \"createdDateTime\": \"2020-03-14T11:22:17.043Z\" }", Encoding.UTF8, "application/json");
var GetResult = await HTTPClient.PostAsync(uri, Content.Content);
For both of those, I receive "Resource not found for the segment 'teams'.
Has anybody seen That? How can I acces\work with Teams resources via Graph API?
When you call https://graph.windows.net, this is Azure AD Graph which is deprecated and will be decommissioned from June 30th 2022.
I recommend you switch over to use Microsoft Graph which you call https://graph.microsoft.com/version. See Graph Explorer to get started.
Check List Channels on how to list teams channels using MS Graph.

Why does adding "offline_access" invalidate MS Graph scope and how do I otherwise get a refresh token?

I'm trying to request an access token and a refresh token from Microsoft Graph, but adding "offline_access" to the scope makes the scope invalid.
This is for a service where a user gives us access to an Outlook Calendar once and after that the service checks their calendar every 20 minutes for events. I have managed to get consent and pull data when requesting access to "User.Read" and "Calendars.Read", but when I add "offline_access" I get the message The provided resource value for the input parameter 'scope' is not valid.
I have an array with the permissions I want
private static final String[] ACCESS_PERMISSIONS = {
"https://graph.microsoft.com/User.Read",
"https://graph.microsoft.com/Calendars.Read",
"https://graph.microsoft.com/offline_access",
};
and then combine and encode them
String encodedScope = URLEncoder.encode(
Arrays.stream(ACCESS_PERMISSIONS)
.reduce(
(a,b) -> a + " " + b)
.get(), "UTF-8").replace("+","%20");
which results in the string https%3A%2F%2Fgraph.microsoft.com%2FUser.Read%20https%3A%2F%2Fgraph.microsoft.com%2FCalendars.Read%20https%3A%2F%2Fgraph.microsoft.com%2Foffline_access
Then I request the tokens
String appId = "client_id=" + clientID;
String scope = "&scope=" + encodedScope;
String authCode = "&code=" + code;
String redirect = "&redirect_uri=" + redirectUri;
String grantType = "&grant_type=authorization_code";
String secret = "&client_secret=" + clientSecret;
String data = appId + scope + authCode + redirect + grantType + secret;
// Create POST request
URL url = new URL(postUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// Configure request
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Accept", "application/json");
connection.setDoOutput(true);
// Send data
OutputStream os = connection.getOutputStream();
byte[] inputBytes = data.getBytes(ENCODING);
os.write(inputBytes, 0, inputBytes.length); // Bytes, Offset, Length
The final link then looks like
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?
client_id=[CLIENT ID]
&response_type=code
&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fsport%2Fauth%2Foutlook
&response_mode=query
&scope=https%3A%2F%2Fgraph.microsoft.com%2FUser.Read%20https%3A%2F%2Fgraph.microsoft.com%2FCalendars.Read%20https%3A%2F%2Fgraph.microsoft.com%2Foffline_access
&state=2737
I would expect this to return an access token and a refresh token, but as previously mentioned I get the message that the resource value for the scope is not valid.
It is essential for the service to be able to refresh the tokens as it should run about a year without intervention.
The scope isn't https://graph.microsoft.com/offline_access, it is simply offline_access. Offline Access is a special AAD scope that tells it to return a Refresh Token, it isn't a Microsoft Graph scope.
You can actually drop https://graph.microsoft.com/ across the board. The only time you need to specify the FQDN is when you're requesting the default set of scopes from the app registration (i.e. https://graph.microsoft.com/.default) but that is generally only used when you're using App-Only/Daemon authentication flow (Client Credentials).

twitter4j oauth_token comes wrong, although what's listed on app-page works perfect

Let me explain my question :
In the image we can see a twitter access_token & secret (present on twitter app details page)
when I use the above two and try to update the status it works.
Twitter twitter = TwitterFactory.getSingleton();
twitter.setOAuthConsumer(Tweet.consumer_key, Tweet.consumer_secret);
twitter.setOAuthAccessToken(new AccessToken(u.getTwittertoken(), u.getTwittersecret()));
twitter.updateStatus("test");
But the oauth_token & oauth_secret that I get through using twitter4j callbackURL
don't work with the above code. I always get Invalid/Expired Token error.
I don't know what can be the error. Because it used to work once, but stopped suddenly (don't know exactly when)
Please help! It'll be great if someone can share their code for both - getting & saving the token into database & then getting it again from the db to update the status.
For those who face the same error, here's what I was doing wrong :
I was trying the token & secret received in twitter-response. Although the correct method is to retrieve them from accessToken which has to be retrieved using oauth_verifier being sent in twitter-response.
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true).setOAuthConsumerKey(Tweet.consumer_key);
cb.setOAuthConsumerSecret(Tweet.consumer_secret);
TwitterFactory tf = new TwitterFactory(cb.build());
Twitter twitter = tf.getInstance();
RequestToken requestToken = (RequestToken) mapSession.get("rtoken");
AccessToken accessToken = twitter.getOAuthAccessToken(requestToken, oauth_verifier);
System.out.println("Request Token : " + ToStringBuilder.reflectionToString(requestToken, ToStringStyle.SHORT_PREFIX_STYLE));
System.out.println("Access Token : " + ToStringBuilder.reflectionToString(accessToken, ToStringStyle.SHORT_PREFIX_STYLE));
System.out.println(accessToken.getToken()); //use this further
System.out.println(accessToken.getTokenSecret()); //use this further

How to Access twitter from Salesforce

I am struggling to get this done, I need to connect to twitter rest Api 1.1 to get user details, time line etc.
What I came across is:
I have a Twitter App with access token ,secrete etc.
Now how to use all that access token etc to send (GET or POST) request to Twitter from Salesforce. How to set header or how to authenticate request.
A tutorial would be very help full all I could find was tutorials for php etc I need it for "salesforce"
Note: I don't want to use a external lib
You should be able to do this directly from Apex using the HTTP REST library. Here is the first Google result for "salesforce apex twitter integration" with this sample code from Navatar_DbSup:
VF CODE:
<apex:inputTextarea id="tweetInput" onkeyup="return maxLength();" onKeyPress="return maxLength();" value="{!newTweet}" rows="2" cols="73"/>
<apex:commandButton id="tweetBtn" style="height:35px;" value="Tweet" action="{!postTweet}" />
Controller code:
*** post tweets into twitter*/
public String newTweet{get;set;}
public Void postTweet()
{
Http h = new Http();
HttpRequest req = new HttpRequest();
Method = 'POST';
req.setMethod(Method);
req.setEndpoint('https://api.twitter.com/1/statuses/update.xml');
newTweet = newTweet.replace('%','%25').replace('&','%26').replace('#','%40').replace(';','%3B').replace('?','%3F').replace('/','%2F').replace(':','%3A').replace('#','%23').replace('=','%3D').replace('+','%2B').replace('$','%24').replace(',','%2C').replace(' ','%20').replace('<','%3C').replace('>','%3E').replace('{','%7B').replace('}','%7D').replace('[','%5B').replace(']','%5D').replace('`','%60').replace('|','%7C').replace('\\','%5C').replace('^','%5E').replace('"','%22').replace('\'','%27').replace('!','%21').replace('*','%2A').replace('(','%28').replace(')','%29').replace('~','%7F');
req.setBody('status='+newTweet);
req.setHeader('Content-Type','application/x-www-form-urlencoded');
OAuth oa = new OAuth();
if(!oa.setService())
{
message=oa.message;
}
oa.sign(req);
HttpResponse res = h.send(req);
system.debug('&&&&&&&&&&&&&&&&7' + res.getBody());
PostTweetbody = res.getBody() + '___' + message;
newTweet = '';
}

Resources