Getting bad response using JRAW - java

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.

Related

GraphAPI Creating a new MSTeam right after creating a new group fails with 404

I want to form a new MSTeam from a newly created group.
I created a new GraphServiceClient
I created a new AuthProvider
I created a new Group with the client like this:
graphApplicationClient.groups().buildRequest().post(group);
It works till here. I get a Group object as a response and can work with it. It has an Id and so on
Right after that I want to create a new team out of this group, so I call
ITeamRequest iTeamRequest = graphApplicationClient.groups(pGroupId).team().buildRequest();
iTeamRequest.setMaxRetries(3);
iTeamRequest.setDelay(10);
Team newTeam = iTeamRequest.post(team);
where pGroupId is the Id I got from the call before.
(In this case: "team" is a new Team-Object created right before this call, like in the MS-Docs.)
I know the sentence from MS-Docs:
If the group was created less than 15 minutes ago, it's possible for
the Create team call to fail with a 404 error code due to replication
delays. The recommended pattern is to retry the Create team call three
times, with a 10 second delay between calls.
thats why I added the maxRetries and Delay..
I watched this video:
https://youtu.be/ybGm1qWVi-k?t=650
in which two MS Employees do exactly the same as I do...
What am I missing? Or is there a workaround for it?
This is the response:
404 : Not Found
Strict-Transport-Security : max-age=31536000
Cache-Control : private
x-ms-ags-diagnostic : {"ServerInfo":{"DataCenter":"West Europe","Slice":"SliceC","Ring":"5","ScaleUnit":"002","RoleInstance":"AGSFE_IN_51"}}
client-request-id : b39c16e4-f786-4d42-865e-9f0cf23ed46f
request-id : 07efc77c-02d3-45f7-85ab-6ca2241d1859
Content-Length : 198
Date : Thu, 23 Apr 2020 12:39:30 GMT
Content-Type : application/json
{
"error": {
"code": "UnknownError",
"message": "",
"innerError": {
"request-id": "07efc77c-02d3-45f7-85ab-6ca2241d1859",
"date": "2020-04-23T12:39:30"
}
}
}
It also does not work, if I put more retries (10 = Max) and more Delay (180 = Max) in it...
And there is no PUT in java..
Best regards
EDIT1: I tried to get it done with two other options.. first with ScribeJava and second with a normal httpRequest.. none of them works. I only get it done with graphExplorer.. With the other options it says BadRequest, but when i copy everything I got in code to GraphExplorer it works... help me :(
EDIT2: I have a group that's been around for a day. From this I wanted to create a new team. Still 404 Not Found. I tried it with GraphAPI and ScribeJava.. None of these calls are working. Debugged through, copied all information, put it in Postman, works fine.
For everyone who has the same problem as I. GraphAPI provides a customRequest() function.
I use the same token, the same url, the same properties, but using the customRequest with PUT. Works...
CustomRequest<JsonObject> createTeamCustomRequest = graphApplicationClient.customRequest("/groups/" + pGroupId + "/team").buildRequest();
createTeamCustomRequest.setMaxRetries(3);
createTeamCustomRequest.setDelay(10);
JsonObject newTeam = _createTeamInJson();
JsonObject createdTeam = createTeamCustomRequest.put(newTeam);
This is the _createTeamInJson function. Returns the same body as I create a Team with GraphAPI
private JsonObject _createTeamInJson()
{
JsonObject teamPayload = new JsonObject();
JsonObject memberSettings = new JsonObject();
JsonObject messagingSettings = new JsonObject();
JsonObject funSettings = new JsonObject();
memberSettings.addProperty("allowCreateUpdateChannels", true);
messagingSettings.addProperty("allowUserEditMessages", true);
messagingSettings.addProperty("allowUserDeleteMessages", true);
funSettings.addProperty("allowGiphy", true);
funSettings.addProperty("giphyContentRating", "strict");
teamPayload.add("memberSettings", memberSettings);
teamPayload.add("messagingSettings", messagingSettings);
teamPayload.add("funSettings", funSettings);
return teamPayload;
}
This isn't the right solution for it, because it should work with the normal GraphAPI, that's why I don't mark this as an answer. But it is a workaround for everyone who has the same problem..

Passing phone input via Twilio

I'm working on a basic Twilio web application using Java and the Spark Java framework. I'm trying to have the user enter a number as input after the initial prompt through a Gather verb and then process that input. So far, I am able to call my Twilio number and it responds with the initial prompt, but after I enter a number it goes to /handle-number and crashes because the request did not contain any params and it can't find the "Digits" param (params is empty when I print it).
I have tried to mimic the API call via the Postman Chrome extension to debug it, but I get a 500 internal server error.
EDIT: Here is a screenshot of the postman request : Postman screenshot
I am new to Java web applications, HTTP requests, and Twilio, so I am unfamiliar with much of this. I have gone thought the twiml documentation and tutorials and tried to follow along but my I'm definitely missing something in my implementation.
How do I properly pass the phone input to the processNumber Route? Any help is appreciated!
App.java
import static spark.Spark.*;
public class App {
public static void main (String[] args){
post("/receive-call", ReceiveCall.call);
post("/handle-number", ReceiveCall.processNumber);
}
}
ReceiveCall.java
import com.twilio.twiml.voice.Gather;
import com.twilio.twiml.voice.Say;
import com.twilio.twiml.*;
import spark.Route;
public class ReceiveCall {
public static Route call = (request, response) -> {
Say sayMessage = new Say.Builder("Hello! Please enter a number as input. Enter # when finished.").build();
Gather input = new Gather.Builder().timeout(3).say(sayMessage).action("/handle-number").build();
VoiceResponse twiml = new VoiceResponse.Builder().gather(input).build();
System.out.println(response.body());
return twiml.toXml();
};
public static Route processNumber = ((request, response) -> {
String digit = request.params("Digits");
//CRASHES HERE BECAUSE digit IS NULL
int number = Integer.parseInt(digit);
Say message = process(number);
VoiceResponse twiml = new VoiceResponse.Builder().say(message).build();
return twiml.toXml();
});
The reason of "digit IS NULL" is: you are using request.params(...), which is for path parameter.
What is "path parameter"?
"path parameter" means passing parameter as part of URL path, especially in RESTful style request.
For example, if you want to send an HTTP GET request to retrieve a book by its ISBN, the request URL could be: /books/9787121022982 or /books/9787101054491, where the ISBN parameter is passed as part of URL path (9787121022982 and 9787101054491). In Spark framework, the corresponding Route code would be:
get("/books/:isbn", (request, response) -> {
return "Book ISBN is: " + request.params(":isbn");
});
What is "query parameter"?
"query parameter" means passing parameter as part of URL queries (entities after the ? character in URL).
Take the previous book ISBN case for example, if you want to pass ISBN as query parameter, the HTTP GET URL would be: /books?isbn=9787121022982, and the corresponding Spark Route code is:
get("/books", (request, response) -> {
return "Book ISBN is: " + request.queryParams("isbn");
});
What is the best practice to pass data in POST request?
In your case, the /handle-number route accept POST request. For HTTP POST request, it's not a good practice to pass data as parameter in URL. Instead, you need to pass data as request body, and get data from body in Spark code:
post("/handle-number", (request, response) -> {
String body = request.body();
// extract ISBN from request body string
});

How to get Facebook Rate Limit Header using Facebook4J?

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());

How do I make authenticated HTTP GET request with Spring schedule service

In ruby I can make a GET request with username and password by doing:
uri = URI('http://192.00.00.00')
req = Net::HTTP::Get.new(uri)
req.basic_auth 'username', 'password'
res = Net::HTTP.start(uri.hostname, uri.port) {|http|
http.request(req)
}
Right now I am trying to make a GET request to my server that requires an username and password using Java and Spring. How does the above code translates to Java?
Also, if I want to make the request every 5 seconds, should I simply have the java code inside the block below?
#Scheduled(fixedRate = 5000)
public void httpRequest() {
//java code here
}

Error While Generating Access Token For Shopify App

I have built an app for Shopify Shops and it was working fine until yesterday. Link to the documentation followed to create a Shopify app: https://docs.shopify.com/api/authentication/oauth
But now there seems to be an error while generating an access token. I have been getting the error in response:
{"error":"795: unexpected token at 'code=<my-code>\u0026client_secret=<my-secret>\u0026client_id=<my-client-id>'"}
Here is the gist of code written in Google App Script.
function doPost(e)
{
try
{
var client_id = e.parameter['client_id'];
var client_secret = e.parameter['client_secret'];
var code = e.parameter['code'];
var shopUrl = e.parameter['shopUrl'];
var headers = {
"Accept":"application/json",
"Content-Type":"application/json"
};
var payload = {
"client_id" : client_id,
"client_secret" : client_secret,
"code": code
};
var options =
{
"method" : "POST",
"payload" : payload,
"headers" : headers,
"muteHttpExceptions":true
};
var response = UrlFetchApp.fetch(shopUrl, options);
var data = response.getContentText().split('"')[3];
//response variable gives the following response
// {"error":"795: unexpected token at 'code=<my-code>\u0026client_secret=<my-client-secret>\u0026client_id=<my-client-id>'"}
return ContentService.createTextOutput(data).setMimeType(ContentService.MimeType.TEXT);
}//try
catch(e)
{
//log the exception
}//catch
}//doPost
Did anybody encounter the same error? Please help
Make sure that you requested to right URL, it just likes as
"https://[YOUR_SHOP_DOMAIN]/admin/oauth/access_token".
Make sure that you gave right ID&secret.
Check my PHP-code here for getting Shopify access-token:
ShopifyClient.php (scroll to the function "getAccessToken")

Categories

Resources