How to get Facebook Rate Limit Header using Facebook4J? - java

According to Facebook Docs
If your app is making enough calls to be considered for rate limiting by our system, we return an X-App-Usage HTTP header. [...] When any of these metrics exceed 100 the app will be rate limited.
I am using Facebook4J to connect my application to the Facebook API. But I could not find any documentation about how I can get the X-App-Usage HTTP header after a Facebook call, in order to avoid being rate limited. I want to use this header to know dinamically if I need to increase or decrease the time between each API call.
So, my question is: using Facebook4J, is possible to check if Facebook returned the X-App-Usage HTTP header and get it? How?

There is a getResponseHeader method for the response of BatchRequests in facebook4j see Facebook4j code examples
You could try getResponseHeader("X-App-Usage")
// Executing "me" and "me/friends?limit=50" endpoints
BatchRequests<BatchRequest> batch = new BatchRequests<BatchRequest>();
batch.add(new BatchRequest(RequestMethod.GET, "me"));
batch.add(new BatchRequest(RequestMethod.GET, "me/friends?limit=50"));
List<BatchResponse> results = facebook.executeBatch(batch);
BatchResponse result1 = results.get(0);
BatchResponse result2 = results.get(1);
// You can get http status code or headers
int statusCode1 = result1.getStatusCode();
String contentType = result1.getResponseHeader("Content-Type");
// You can get body content via as****() method
String jsonString = result1.asString();
JSONObject jsonObject = result1.asJSONObject();
ResponseList<JSONObject> responseList = result2.asResponseList();
// You can map json to java object using DataObjectFactory#create****()
User user = DataObjectFactory.createUser(jsonString);
Friend friend1 = DataObjectFactory.createFriend(responseList.get(0).toString());
Friend friend2 = DataObjectFactory.createFriend(responseList.get(1).toString());

Related

Coinbase pagination returning {"errors":[{"id":"not_found","message":"Not found"}]}

I am trying to iterate over a paginated list of accounts but when I send a request using the value from "next_uri" I receive an error from the server:
{"errors":[{"id":"not_found","message":"Not found"}]}
I am correctly adding headers etc as all other API calls work fine, its just the request using the "next_uri" that is not working. I think I am following the api spec correctly so I am unsure what is the issue and how to fix it. Does anyone know what is wrong with the code / logic please?
Simplified code:
ArrayList<X> results = new ArrayList<>();
String uri = "/v2/accounts";
javax.ws.rs.client.Client client = getClient();
while(uri != null){
T response = client.target("https://api.coinbase.com")
.path(uri).request(MediaType.APPLICATION_JSON).get(responseType);
results.addAll(response.getData());
uri = response.getPagination()==null ? null :response.getPagination().getNextUri();
}
return results;
The results are this:
Request 1:
https://api.coinbase.com/v2/accounts
Response 1: pagination":
{"ending_before":null,"starting_after":null,"previous_ending_before":null,"next_starting_after":"ef35df6c-a45b-5858-b755-f12a709cf26e","limit":25,"order":"desc","previous_uri":null,"next_uri":"/v2/accounts?starting_after=ef35df6c-a45b-5858-b755-f12a709cf26e"},"data":[{....}]
Request 2:
https://api.coinbase.com/v2/accounts%3Fstarting_after=ef35df6c-a45b-5858-b755-f12a709cf26e
Response 2:
{"errors":[{"id":"not_found","message":"Not found"}]}
This was related to how the jax-rs library needs the query params adding. Just relying on the uri is not enough, the parameters also need adding specifically:
target = target.queryParam(e.getKey(), e.getValue());
so the final code is something like
WebTarget target = client.target(e"https://api.coinbase.com");
if(params !=null){
for(Map.Entry<String, String> e : params.entrySet()){
target = target.queryParam(e.getKey(), e.getValue());
}
}
target = target.path(path);
return target.request(MediaType.APPLICATION_JSON).get(responseType);

Pagination on Google Analytics using Java

I'm implementing a data extraction from Google Analytics using Java and I'm following this example: https://developers.google.com/analytics/devguides/reporting/core/v4/quickstart/service-java
I managed to extract the data I need but I can't figure out how to set the start-index using its client. Below you can see the changed I made to the default implementation. I can set the page size but I can't find out how to set the start-index.
public GetReportsResponse getReport(String dateStart, String dateEnd) throws IOException {
String[] metricsArr = {"ga:users", "ga:newUsers", "ga:sessions", "ga:totalEvents"};
String[] dimensionsArr = {"ga:eventLabel","ga:eventCategory","ga:eventAction", "ga:country", "ga:countryIsoCode", "ga:dateHourMinute"};
// Create the DateRange object.
DateRange dateRange = new DateRange();
dateRange.setStartDate(dateStart);
dateRange.setEndDate(dateEnd);
// Create the Metrics object.
ArrayList<Metric> metrics = new ArrayList<Metric>();
for(String item : metricsArr){
Metric m = new Metric().setExpression(item).setAlias(item.replace("ga:", ""));
metrics.add(m);
}
ArrayList<Dimension> dimensions = new ArrayList<Dimension>();
for(String item : dimensionsArr){
Dimension d = new Dimension().setName(item);
dimensions.add(d);
}
// Create the ReportRequest object.
ReportRequest request = new ReportRequest()
.setViewId(this.VIEW_ID)
.setDateRanges(Arrays.asList(dateRange))
.setMetrics(metrics)
.setDimensions(dimensions)
.setFiltersExpression("ga:eventCategory=#NOTICE,ga:eventCategory==Document,ga:eventCategory==Document reader")
.setPageSize(10000);
ArrayList<ReportRequest> requests = new ArrayList<ReportRequest>();
requests.add(request);
// Create the GetReportsRequest object.
GetReportsRequest getReport = new GetReportsRequest().setReportRequests(requests);
// Call the batchGet method.
GetReportsResponse response = service.reports().batchGet(getReport).execute();
// Return the response.
return response;
}
How can I achieve that so I can navigate through all pages and extract all items?
The Reporting API V4 uses page tokens. The reply from the reporting API will return the next page's token, see nextPageToken. Using that you can make the exact same call but updating the pageToken in the request with the nextpagetoken from the previous reply. Note that the first call you make the reporting API will not have a page token attached to the request and the last page will not have the nextpagetoken set.
I hope that helps.

Extract data from returned string

I'm using Katalon Studio and using it to send an API request. The request is basically returning information I want to use in the HTTP Header. I can use Groovy or Java to extract this but not sure how I can do it.
I've tried create_game_response.getHeadewrFields(GameCode) in order to get the GameCode but it won't work.
Here is the code I use
WS.sendRequest(findTestObject('UserRestService/Create Game'))
WS.verifyResponseStatusCode(create_game_response, 201)
def header_text = create_game_response.getHeaderFields()
println(header_text)
def game_code = create_game_response.getHeaderFields();
String game_code_list = game_code.toString()
println(game_code_list)
And this is the response:
{GameCode=[1jwoz2qy0js], Transfer-Encoding=[chunked], null=[HTTP/1.1 201 Created]}
I'm trying to extract "1jwoz2qy0js" from the game code and use it as a string, how can I do this?
getHeaderFields() returns a Map of the headers where each header is a List. Rather than converting that to a String and attempting to parse it, just get the field you want:
Map headers = create_game_response.getHeaderFields()
List gameCodes = headers["GameCode"]
And then select the first one, if that's all there is:
assert gamesCodes[0] == "1jwoz2qy0js"
Groovy code below:
​
str = '{GameCode=[1jwoz2qy0js], Transfer-Encoding=[chunked], null=[HTTP/1.1 201 Created]}'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
left_idx = str.indexOf('[') + 1
right_idx = str.indexOf(']')
print str.substring(left_idx,right_idx)
Output:
1jwoz2qy0js

Getting bad response using JRAW

I am trying to read data from reddit using java. I am using JRAW.
Here is my code:
public class Main {
public static void main(String args[]) {
System.out.println('a');
String username = "dummyName";
UserAgent userAgent = new UserAgent("crawl", "com.example.crawl", "v0.1", username);
Credentials credentials = Credentials.script(username, <password>,<clientID>, <client-secret>);
NetworkAdapter adapter = new OkHttpNetworkAdapter(userAgent);
RedditClient reddit = OAuthHelper.automatic(adapter, credentials);
Account me = reddit.me().about();
System.out.println(me.getName());
SubmissionReference submission = reddit.submission("https://www.reddit.com/r/diabetes/comments/9rlkdm/shady_insurance_work_around_to_pay_for_my_dexcom/");
RootCommentNode rcn = submission.comments();
System.out.println(rcn.getDepth());
System.out.println();
// Submission submission1 = submission.inspect();
// System.out.println(submission1.getSelfText());
// System.out.println(submission1.getUrl());
// System.out.println(submission1.getTitle());
// System.out.println(submission1.getAuthor());
// System.out.println(submission1.getCreated());
System.out.println("-----------------------------------------------------------------");
}
}
I am making two requests as of now, first one is reddit.me().about(); and the second is reddit.submission("https://www.reddit.com/r/diabetes/comments/9rlkdm/ shady_insurance_work_around_to_pay_for_my_dexcom/");
The output is:
a
[1 ->] GET https://oauth.reddit.com/api/v1/me?raw_json=1
[<- 1] 200 application/json: '{"is_employee": false, "seen_layout_switch": true, "has_visited_new_profile": false, "pref_no_profanity": true, "has_external_account": false, "pref_geopopular": "GL(...)
dummyName
[2 ->] GET https://oauth.reddit.com/comments/https%3A%2F%2Fwww.reddit.com%2Fr%2Fdiabetes%2Fcomments%2F9rlkdm%2Fshady_insurance_work_around_to_pay_for_my_dexcom%2F?sort=confidence&sr_detail=false&(...)
[<- 2] 400 application/json: '{"message": "Bad Request", "error": 400}'
Exception in thread "main" net.dean.jraw.ApiException: API returned error: 400 (Bad Request), relevant parameters: []
at net.dean.jraw.models.internal.ObjectBasedApiExceptionStub.create(ObjectBasedApiExceptionStub.java:57)
at net.dean.jraw.models.internal.ObjectBasedApiExceptionStub.create(ObjectBasedApiExceptionStub.java:33)
at net.dean.jraw.RedditClient.request(RedditClient.kt:186)
at net.dean.jraw.RedditClient.request(RedditClient.kt:219)
at net.dean.jraw.RedditClient.request(RedditClient.kt:255)
at net.dean.jraw.references.SubmissionReference.comments(SubmissionReference.kt:50)
at net.dean.jraw.references.SubmissionReference.comments(SubmissionReference.kt:28)
at Main.main(Main.java:36)
Caused by: net.dean.jraw.http.NetworkException: HTTP request created unsuccessful response: GET https://oauth.reddit.com/comments/https%3A%2F%2Fwww.reddit.com%2Fr%2Fdiabetes%2Fcomments%2F9rlkdm%2Fshady_insurance_work_around_to_pay_for_my_dexcom%2F?sort=confidence&sr_detail=false&raw_json=1 -> 400
... 6 more
As it can been that my first request gives me a response of my username but in the second response i am getting a bad request 400 error.
To check whether my client ID and client secret were working correctly I did the same request using python PRAW library.
import praw
from praw.models import MoreComments
reddit = praw.Reddit(client_id=<same-as-in-java>, client_secret=<same-as-in-java>,
password=<same-as-in-java>, user_agent='crawl',
username="dummyName")
submission = reddit.submission(
url='https://www.reddit.com/r/redditdev/comments/1x70wl/how_to_get_all_replies_to_a_comment/')
print(submission.selftext)
print(submission.url)
print(submission.title)
print(submission.author)
print(submission.created_utc)
print('-----------------------------------------------------------------')
This gives the desired result without any errors so the client secret details must be working.
The only doubt I have is in the user agent creation in java UserAgent userAgent = new UserAgent("crawl", "com.example.crawl", "v0.1", username);.
I followed the following link.
What exactly does the target platform, the unique ID or the version mean. I tried to keep the same format as in the link. Also using the same username as in other places. On the other hand the user_agent in python was a string crawl.
Please tell me if I am missing anything and what could be the issue.
Thank you
P.S. I want to do this in java. not python.
Since your first query is working the credentials are correct. In JRAW don't give the whole URL but only the id in the submission function.
Change this
SubmissionReference submission = reddit.submission("https://www.reddit.com/r/diabetes/comments/9rlkdm/shady_insurance_work_around_to_pay_for_my_dexcom/");
to this
SubmissionReference submission = reddit.submission("9rlkdm");
where the id is the random string after /comment/ in the URL.
Hope this helps.

How to pull more than 500 user objects from my domain?

I am trying to pull about 20,000 users from my Google domain. However, i know that Google only has a limit of about 500 users for a pull request. I know about the pageToken stuff, but the documentation for it online is terrible. Can someone show me how to use the pageToken? Please keep in mind i am using the google client libraries. This is what my code looks like so far:
#Test
public void paginationTest() throws IOException, NullPointerException, GeneralSecurityException {
try {
Directory directory = GCAuthentication.getDirectoryService("xxx", "vvv", dddd);
Directory.Users.List list = directory.users().list().setOrderBy("email").setMaxResults(500).setDomain("dev.royallepage.ca");
do {
com.google.api.services.admin.directory.model.Users users = list.execute();
java.util.List<User> uL = users.getUsers();
//uL.addAll(users.getUsers());
//list.setPageToken(list.getPageToken());
System.out.println(uL.size());
}while (list.getPageToken() != null && list.getPageToken().length() > 0);
}catch(NullPointerException e) {
}
}
Please advise what i am doing wrong! Thanks,
Mesam
You will have to create a function that will get the pageToken variable then call another request including the nextPageToken.
Use the pageToken query string for responses with large number of groups. In the case of pagination, the response returns the nextPageToken property which gives a token for the next page of response results. Your next request uses this token as the pageToken query string value.
Sample Code Request:
GET https://www.googleapis.com/admin/directory/v1/users
?domain=primary domain name&pageToken=token for next results page
&maxResults=max number of results per page
&orderBy=email, givenName, or familyName
&sortOrder=ascending or descending
&query=email, givenName, or familyName:the query's value*
Hope this helps!

Categories

Resources