Facebook Graph API: The remote server returned an error: (400) Bad Request instead of error inside - facebook-graph-api

I have a code that make a Get request to Facebook Graph API to get business account.
This is code:
var facebookBusinessAccountId = ConfigurationManager.AppSettings["facebook_business_account_id"];
facebookRestUrl += "&access_token=" + acct.AccessToken;
facebookRestUrl = facebookRestUrl.Replace("{0}", facebookBusinessAccountId);
var request = WebRequest.Create(facebookRestUrl);
request.Method = "GET";
request.ContentType = "application/json";
var response = request.GetResponse(); (Error here)
The URI look like:
https://graph.facebook.com/v3.1/1x8xx4005xxxxxx?fields=business_discovery.username(yess_cub){biography,id,ig_id,profile_picture_url,username,website}&access_token=EAAJ..
It should be return error like this:
{
"error": {
"message": "Invalid user id",
"type": "OAuthException",
"code": 110,
"error_subcode": 2207013,
"is_transient": false,
"error_user_title": "Cannot find User",
"error_user_msg": "The user with username: yess_cub cannot be found.",
"fbtrace_id": "BMEAcyYOZf9"
}
}
But error : The remote server returned an error: (400) Bad Request is what I get
Could anyone please help me?
Thanks alot!

I found an idea and catch the inner exception from try/catch statement
It should be like this:
catch (WebException ex)
{
using (StreamReader reader = new StreamReader(ex.Response.GetResponseStream()))
{
string jsonMessageString = reader.ReadToEnd();
}
}

Related

Which .NET Object corresponds to Lambda Proxt Integration in AWS

I've a lambda function that does some verification before inserting data into dynamoDB. I wish to return a 400 HttpStatus code if the passed payload is invalid and that's the reason I've googled and found
public async Task<APIGatewayProxyResponse> FunctionHandler(RequestItem request, ILambdaContext context)
{
But when I return the code as
private static APIGatewayProxyResponse GetBadRequestResponse()
{
var responseBadRequest = new APIGatewayProxyResponse
{
StatusCode = (int)HttpStatusCode.BadRequest,
Body = "Invalid payload sent",
// Headers = new Dictionary<string, string> { { "Content-Type", "text/plain" } }
};
return responseBadRequest;
}
It returns a 200 with the content of
{
"statusCode": 400,
"body": "Invalid payload sent",
"isBase64Encoded": false
}
In the AWS Console I did
But doing so If I put the APIGatewayProxyRequest as request, I've got null for Body field
Anyone has got a simila situation?

How can I return JSON with HTTP code in Vibe.d?

I would like to return not only JSON, but also the HTTP response code.
I registering REST interface through URLRouter:
router.registerRestInterface(new ClientServerAPI);
Example of my REST implementation:
module clienserverapi.clientserver;
import api.clientserver;
import models.replies.client_versions;
/**
Implementation of Client-Server API.
*/
class ClientServerAPI : IClientServerAPI {
#safe:
ClientVersions getSupportedClientVersions() {
bool[string] unstableFeatures;
return ClientVersions(supportedVersions.dup, unstableFeatures);
}
}
In the REST interface generator the response codes are handled automatically and as you can't pass in a HTTPServerResponse/HTTPServerRequest argument into your REST methods, you can't control what status gets returned.
However there are some built-in statuses which get handled:
200/204 are returned based on content
400 Bad request for mismatched arguments
404 Not found for unmatched routes
500 internal server error is returned on most exceptions
(outside of debug mode) unauthorized / bad request / forbidden are sent
See also: REST interface documentation
and you can control any status code using HTTPStatusException, however it is treated as error and will result in a predefined error json which has statusMessage as exception message set and returns the HTTP status code you pass to it. (this is probably what you want for error handling)
You can also change what the errors look like by setting the errorHandler to a RestErrorHandler delegate in your RestInterfaceSettings.
Alternatively, depending on what you want to do, you can use a WebInterface which is a lot like a rest interface, but doesn't have some convenience functions REST interfaces do, but instead can fully access the request/response arguments and can basically do anything like a normal http route and has some other convenience functions you can use.
In theory you could abuse the errorHandler + HTTPStatusException with valid HTTP status codes if you want to return custom success codes with your data, but I would discourage that and instead go with web interfaces if that's what you are after.
However if all you want to do is having custom error codes with a custom, but consistent, error page then I would definitely go with REST interface with an errorHandler.
Your could could now look like this:
import vibe.vibe;
import std.uni;
#safe:
void main() {
auto server = new HTTPServerSettings;
server.port = 3000;
server.bindAddresses = ["::1", "127.0.0.1"];
auto router = new URLRouter;
RestInterfaceSettings settings = new RestInterfaceSettings();
// this is how the error page will look on any thrown exception (like HTTPStatusException)
settings.errorHandler = (HTTPServerRequest req, HTTPServerResponse res,
RestErrorInformation error) #safe {
res.writeJsonBody([
// design this however you like
"ok": Json(false),
"error": serializeToJson([
"status": Json(cast(int)error.statusCode),
"message": Json(error.exception.msg),
"parent": Json("/api/something")
])
]);
};
router.registerRestInterface(new Impl, settings);
listenHTTP(server, router);
runApplication();
}
interface RestAPI {
string getGreeting(string name);
}
class Impl : RestAPI {
string getGreeting(string name)
{
// throw an HTTP Bad Request error when name is empty
if (name.length == 0)
throw new HTTPStatusException(HTTPStatus.badRequest, "Name parameter cannot be empty!");
// throw an HTTP Conflict error code when name is Bob
if (sicmp(name, "bob") == 0)
throw new HTTPStatusException(HTTPStatus.conflict, "Server cannot greet Bob!");
return "Hello, " ~ name ~ "!";
}
}
and your server will then respond something like:
{
"ok": false,
"error": {
"message": "Server cannot greet Bob!",
"status": 409,
"parent": "/api/something"
}
}
You can try hunt framework, sample code for Rest api:
module app.controller.myapi;
import hunt.framework;
import app.message.UserMessage;
class MyapiController : Controller
{
mixin MakeController;
#Action
JsonResponse test()
{
UserMessage user;
user.id = 1;
user.name = "MyName";
user.email = "test#domain.com";
return new JsonResponse(user);
}
}
Your response struct:
module app.message.ResultMessage;
struct UserMessage
{
int id;
string name;
string email;
}
Response result is:
[ "id": 1, "name": "MyName", "email": "test#domain.com" ]

Having and issue with queryRequest in AWS Dynamodb

I am having an issue with dynamodb and the QueryRequest. I want to implement paging with dynamodb.
I am getting an error back from postman. Scroll right for full error.
{
"timestamp": "2019-06-04T00:12:42.526+0000",
"status": 500,
"error": "Internal Server Error",
"exception": "com.amazonaws.services.dynamodbv2.model.ResourceNotFoundException",
"message": "Request processing failed; nested exception is com.amazonaws.services.dynamodbv2.model.ResourceNotFoundException: Requested resource not found (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ResourceNotFoundException; Request ID: TDAUFVG205A11TFDGOD9U53MMBVV4KQNSO5AEMVJF66Q9ASUAAJG)",
My project does connect and work fine with other api's gets. dynamoDBMapper.query works fine and does return data.
The problem is from the new code using QueryRequest.
public String getRequestPage(String query, String lastEvaluatedKey, String limit) {
...
Map<String, AttributeValue> mapLastEvaluatedKey = null;
Map<String,String> expressionAttributesNames = new HashMap<>();
expressionAttributesNames.put("#tagId","tagId");
Map<String,AttributeValue> expressionAttributeValues = new HashMap<>();
expressionAttributeValues.put(":column_search",new AttributeValue().withS(query));
QueryRequest queryRequest = new QueryRequest()
.withTableName(dynamoDbTableName)
.withKeyConditionExpression("#tagId = :column_search")
.withExpressionAttributeNames(expressionAttributesNames)
.withExpressionAttributeValues(expressionAttributeValues)
.withLimit(page_limit)
.withExclusiveStartKey(mapLastEvaluatedKey);
System.out.println(" queryRequest " + queryRequest );
QueryResult queryResult = client.query(queryRequest);
Map<String, AttributeValue> mapLastEvaluatedKeyReturned = null;
mapLastEvaluatedKeyReturned = queryResult.getLastEvaluatedKey();
error -->{ "timestamp": "2019-06-04T19:58:18.156+0000", "status": 500,
"error": "Internal Server Error", "exception":
"com.amazonaws.services.dynamodbv2.model.ResourceNotFoundException",
"message": "Request processing failed; nested exception is
com.amazonaws.services.dynamodbv2.model.ResourceNotFoundException:
Requested resource not found (Service: AmazonDynamoDBv2; Status Code:
400; Error Code: ResourceNotFoundException; Request ID:
BRCI1FLM3375SB8U6JSJEAH09NVV4KQNSO5AEMVJF66Q9ASUAAJG)", "path":
"/api/v1/metadata/tag/tagIdPage/military_status/page/1/limit/2" }
This is the system.out of the queryRequest and sent to the DB
queryRequest {TableName: tagMetadata_Certified-dev,Limit:
2,FilterExpression: tagId = :tagIdValue,KeyConditionExpression: #tagId = :tagIdValue,ExpressionAttributeNames:
{#tagId=tagId},ExpressionAttributeValues: {:tagIdValue={S:
military_status,}}}
Any help would be great.
Thanks
Phil
I found my issued using the aws cli from the terminal window. This is very useful for testing with the --debug switch.
Scroll right for full code...
aws dynamodb query --table-name tableNameHere --region regionNameHere --key-condition-expression "tagId = :tagIdValue" --filter-expression "isReportable = :p" --expression-attribute-values '{":tagIdValue":{"S":"m_status"}, ":p":{"BOOL":true}}' --debug
public String getRequestPage(String tagIdPassed, String lastEvaluatedKey, String limit) {
.... code removed ...
Boolean isReportableBool = true;
TagMetadata tagMetadata = new TagMetadata();
Map<String,String> expressionAttributesNames = new HashMap<>();
expressionAttributesNames.put("#tagId","tagId");
expressionAttributesNames.put("#isReportable","isReportable");
Map<String,AttributeValue> expressionAttributeValues = new HashMap<>();
expressionAttributeValues.put(":tagIdValue",new AttributeValue().withS(tagIdPassed));
expressionAttributeValues.put(":isReportableValue",new AttributeValue().withBOOL(isReportableBool));
QueryRequest queryRequest = new QueryRequest()
.withTableName(dynamoDbTableName)
.withKeyConditionExpression("#tagId = :tagIdValue")
.withFilterExpression("#isReportable = :isReportableValue")
.withExpressionAttributeNames(expressionAttributesNames)
.withExpressionAttributeValues(expressionAttributeValues)
.withLimit(page_limit);

How to get PowerBI accesstoken using ADAL.JS

I'm trying to use ADAL.js to authenticate against PowerBI in order to get an access_token and the embed_token needed to embed PowerBI reports/dashboards/tiles in a html/javascript-only "webpart". My adal-config looks like:
config = {
instance: 'https://login.windows.net/common/oauth2/authorize/',
tenant: 'tenant.onmicrosoft.com',
clientId: '05xxxxx-xxx-xxxx-xxxx-xxxxxxxxxxxx',
loginResource: "https://analysis.windows.net/powerbi/api",
postLogoutRedirectUri: window.location.origin,
cacheLocation: 'localStorage',
};
But I can't seem to find any access-token etc in the user.profile I get. I am obviously missing something but what.. :) Any help would be much appriciated
Looking at:
https://community.powerbi.com/t5/Developer/get-Access-token-using-js/m-p/350294
and also this:
https://community.powerbi.com/t5/Developer/How-to-Generate-Embed-Token-in-pure-JavaScript/td-p/350056
you can use ADAL.js to get the access token itself
window.config = {
instance: 'https://login.microsoftonline.com/',
tenant: 'common', //COMMON OR YOUR TENANT ID
clientId: 'XXXXX', //This is your client ID
redirectUri: 'XXXXXX', //This is your redirect URI
callback: userSignedIn,
popUp: true
};
var ADAL = new AuthenticationContext(config);
function signIn() {
ADAL.login();
}
function userSignedIn(err, token) {
console.log('userSignedIn called');
if (!err) {
showWelcomeMessage();
ADAL.acquireToken("https://analysis.windows.net/powerbi/api", function (error, token) {
// Handle ADAL Error
if (error || !token) {
printErrorMessage('ADAL Error Occurred: ' + error);
return;
}
}

signing SOAP XML using node-js using private key

Am trying to sign the XML using my private key, and using SOAP UI
it gives the proper success response.
to generate the request am using below code
var Authorization = 'Basic ' + new Buffer((sapConfig.sap.username + ':' + sapConfig.sap.password) || '').toString('base64');
soap.createClient(__dirname + '/wsdl/SI_CARWORKZ_Customer_Sen_Sync.wsdl', wsdlOptions, function (err, client) {
client.setSecurity(new soap.WSSecurityCert(privateKey, publicKey, password, 'utf8'));
//client.setSecurity(new soap.ClientSSLSecurity(privateKey, publicKey, ca));
client.SI_CARWORKZ_Customer_Sen_Sync(details, sslOptions, function(err, result, raw, soapHeader) {
console.log('%j', result);
if(_.has(result, "ResponseData") && !_.isEmpty(result.ResponseData.Item)){
var status = _.pluck(result.ResponseData.Item, "Status");
if(status.indexOf('E') != -1){
return callback({status: "error", data: result});
}else{
// insert the user in mongodb
sapLogs.insertCustomers(details.HEADER, function(result){
console.log("customer added");
return callback({status: "success", data: details});
})
}
}else{
return callback({status: "error", data: [], message: "something went wrong." })
}
}, {"Authorization": Authorization});
});
But when am sending the signed xml data using the script it shows me error
Error while valdiating the digital signature. The error was java.lang.NullPointerException while trying to invoke the method com.sap.security.core.ws.wss.tokens.securitytoken.BinarySecurityToken.getSecurityToken()
Is there any issue with my public key or private key?
I have exported them from jks file which is used in SOAP UI.