Node-Soap Cannot read property 'Body' of undefined - node.js

Using node-soap:
I'm trying to use this service : http://services.resumeparsing.com/ParsingService.asmx?op=ParseResume
I get a successful response when I query GetAccountInfo so I know my account/servicekey are correct: http://services.resumeparsing.com/ParsingService.asmx?op=GetAccountInfo
The error I'm seeing is: TypeError: Cannot read property 'Body' of undefined when I try to use the ParseResume service.
Here's how I call ParseResume:
var buff_string = new Buffer(upload, 'base64')
var soap_args = {
url:"http://services.resumeparsing.com/ParsingService.asmx?wsdl",
args: {
request: {
AccountId : myAccountId,
ServiceKey : myServiceKey,
FileBytes : buff_string,
OutputXmlDoc : true,
Configuration: myConfString
}
}
}
client.ParsingService.ParsingServiceSoap12.ParseResume(soap_args.args, function(err, result){
if(err) console.log ( err )
if(result) console.log (result)
})
As you can probably tell, I've never used SOAP before, any guidance is greatly appreciated!
edit: FileBytes is asking for a base64Binary string

changed
var buff_string = new Buffer(upload, 'base64')
to
var buff_string = (new Buffer(upload)).toString('base64')

Related

Facebook api giving 400 error with FacebookRequestError msg

const bizSdk = require('facebook-nodejs-business-sdk');
const AdAccount = bizSdk.AdAccount;
const AdsInsights = bizSdk.AdsInsights;
let access_token = '';
let ad_account_id = '';
let app_secret = '';
let app_id = '';
const api = bizSdk.FacebookAdsApi.init(access_token);
const account = new AdAccount(ad_account_id);
const showDebugingInfo = true; // Setting this to true shows more debugging info.
if (showDebugingInfo) {
api.setDebug(true);
}
let ads_insights;
let ads_insights_id;
const logApiCallResult = (apiCallName, data) => {
console.log(apiCallName);
if (showDebugingInfo) {
console.log('Data:' + JSON.stringify(data));
}
};
const fields = [
'website_ctr:link_click',
'purchase_roas:omni_purchase',
'website_purchase_roas:offsite_conversion.fb_pixel_purchase',
'mobile_app_purchase_roas:app_custom_event.fb_mobile_purchase',
];
const params = {
'level' : 'adset',
'filtering' : [{'field':'delivery_info','operator':'IN','value':['active']}],
'breakdowns' : ['days_1'],
'time_range' : {'since':'2020-03-01','until':'2020-03-31'},
};
(new AdAccount(ad_account_id)).getInsights(
fields,
params
)
.then((result) => {
logApiCallResult('ads_insights api call complete.', result);
ads_insights_id = result[0].id;
})
.catch((error) => {
console.log(error);
});
Hi, Here is my node.js code which i copied from facebook.
But, when i am running the code i am getting below error.
status: 400,
response: {
error: {
message: 'Syntax error "Expected "(" instead of ","." at character 109: website_ctr:link_click,purchase_roas:omni_purchase,website_purchase_roas:offsite_conversion.fb_pixel_purchase,mobile_app_purchase_roas:app_custom_event.fb_mobile_purchase',
type: 'OAuthException',
code: 2500,
fbtrace_id: 'ANEo2UqslTEnJqp5yeVRVEW'
}
}
I never used this before so it is confusing for me.
I there any issue with the fields i am sending.
Please have a look
Just solved it myself. The error Syntax error "Expected "(" instead of ","." at character XX comes from the parameter - website_purchase_roas:offsite_conversion.fb_pixel_purchase.
It looks like Node doesn't know how to handle a property:value pair in which the value has a . . Also the Facebook API seems to be expecting enumerated Field types, so it would be interesteing to see what it resolves too.
The line which caused this in my own was this - actions:onsite_conversion.post_save, and pushed the same error.
Full Error - 'Syntax error "Expected "(" instead of ","." at character 324:.

Response undefined - aws-api-gateway-client

I have created an AWS API Gateway to invoke a Lambda function to generate random numbers:
Lambda Function :
exports.handler = (event, context, callback) => {
let min = parseInt(event.min);
let max = parseInt(event.max);
let generatedNumber = Math.floor(Math.random() * max) + min;
context.done(null, {generatedNumber: generatedNumber});
};
Body mapping Template in API gateway for get method:
{
"min" : $input.params('min'),
"max" : $input.params('max')
}
When I access API endpoint like below:
https://abcdefgh.execute-api.ap-south-1.amazonaws.com/DEV/number?min=10&max=20
I get the proper response :
{"generatedNumber":28}
But when I try to access the API in node.js using aws-api-gateway-client I am receiving the below response :
_currentUrl: 'https://abcdefgh.execute-api.ap-south-1.amazonaws.com/DEV/number' },
response: undefined
The current url should be set to 'https://abcdefgh.execute-api.ap-south-1.amazonaws.com/DEV/number?min=20&max=40' but it is set to 'https://abcdefgh.execute-api.ap-south-1.amazonaws.com/DEV/number'.
Here is my node.js code to access this api:
let AWS = require('aws-sdk');
AWS.config.loadFromPath('./config.json');
//AWS.config.region = 'ap-south-1';
let lambda = new AWS.Lambda();
let apigClientFactory = require('aws-api-gateway-client').default;
let config = {
invokeUrl: 'https://abcdefgh.execute-api.ap-south-1.amazonaws.com/DEV',
accessKey: '<access-key>',
secretKey: '<secret-key>',
region: 'ap-south-1'
};
let apigClient = apigClientFactory.newClient(config);
let apiParams = '{"min": 20,"max": 40}';
let body = {
}
let additionalParams = {
}
apigClient.invokeApi(apiParams, '/number', 'GET', additionalParams, body)
.then(function (result) {
console.log(result);
})
.catch(function (error) {
console.log(error);
});
I tried changing apiParams to :
let apiParams = {"min": 20,"max": 40};
The I receive the below error:
'{"message": "Could not parse request body into json: Unexpected character (\\\',\\\' (code 44)): expected a value\\n at [Source: [B#42feb146; line: 2, column: 14]"}' } }
What is wrong in my code?
Thanks in advance
Try modifying the mapping template:
{
"min" : "$input.params('min')",
"max" : "$input.params('max')"
}
Source: input-variable-reference
I found the problem. I need to pass parameters in additionalParmaeters object like :
let additionalParams = {
queryParams: {
min: 20, max: 40
}
}
But the text
var params = {
//This is where any header, path, or querystring request params go. The key is the parameter named as defined in the API
userId: '1234',
};
is misleading because query parameters were not passed when parameters were added to params object ( maybe it was for me ), but were only passed when passed inside additionalPrams.
Hope it helps.

Node + Mongodb + ObjectId not working

I am working with nodejs+ express and mongodb.
I am using postman and access the API.
When I use ObjectId the server not responding anything. If i removed means working good.
I am not able to fix this issue. Please can anyone help for this.
test.js
//Post Data:
{
"list_id": "56963e4dbcd5d4ff27ced0fbd"
}
var app = require('express');
var router = app.Router();
var server = require('./../../server');
var mongoUtil = require('./../../mongoUtil');
var ObjectId = require('mongodb').ObjectID;
router.post('/share', function(req, res, next) {
var data = {
query : {}
};
console.log(req.body['list_id']);
//printed 56963e4dbcd5d4ff27ced0fbd
console.log(data.query);
//printed {}
data.query = ObjectId(req.body['list_id']);
console.log(data.query);
//Here not getting any response
// this line not printed and server no response.
//Also tried the following things. but its not working.
// data.query['_id'] = new ObjectID(req.body['list_id']);
//data.query._id = ObjectId(req.body['list_id']);
var collection = mongoUtil.list;
collection.findOne(data.query, function(err, list) {
console.log(err);
console.log(list);
if (!err && list) {
res.send("Sucess");
return;
} else {
res.send("Error");
return;
}
});
});
56963e4dbcd5d4ff27ced0fbd should be of length 24. But it is 25. Make sure it is 24. It might work.
ObjectID()
Constructor
Create a new ObjectID instance
class ObjectID()
Arguments:
id (string) – Can be a 24 byte hex string, 12 byte binary string or a Number.
Returns:
object instance of ObjectID
Caught with the same error. Seems like ObjectId from mongoDB not working.
FOllowing import fixed the issue:
import { ObjectId } from "bson"

Simple soap call is failing (Nodejs, easysoap)

I am having some problems with easysoap (https://npmjs.org/package/easysoap) and I have been unable to find much documentation or people talking about it, so I hope some of you can help:
I’m making a simple call like this:
var clientParams = {
host : 'somewhere.com',
port : '9001',
path : '/somews.asmx',
wsdl : '/somews.asmx?WSDL'
};
var clientOptions = {
secure : false
};
//create new soap client
var SoapClient = new soap.Client(clientParams, clientOptions);
SoapClient.once('initialized', function() {
//successful initialized
SoapClient.once('soapMethod', function(data, header) {
});
console.log('call');
SoapClient.call({
'method' : 'Execute',
'params' : {
'ExecuteXML' : 1
}}, function(attrs, err, responseArray, header){
}
);
});
//initialize soap client
SoapClient.init();
The problem Is that I get a response saying that I am not authorized to make my request.However if I manually try the same url in the browser http://somewhere.com:9001/somews.asmx it does work.
Do you know what am I doing wrong?
Many many thanks in advance.
If any of you know of any other node module to achieve this please let me know. I attempted to use node-soap but got lost in all the dependencies required: python, Visual Studio... you really need all that to make a couple of soap calls to a server???
Thanks
For other nodejs soap modules. I currently use node-soap and am happy with it. You can find the project here.
Here is an example of how I'm using it.
var soap = require('soap');
//example url
var url = 'http://ws.strikeiron.com/GlobalAddressVerification5?WSDL';
var soapHeader = ''//xml string for header
soap.createClient(url, function(err, client){
client.addSoapHeader(soapHeader);
var args = {
StreetAddressLines: "5322 Otter Lane",
CountrySpecificLocalityLine: "Middleberge FL 32068",
Country: "USA"
};
client.BasicVerify(args, function(err, result){
if(err){
throw err;
}
console.log(result);
});
});
For me this worked:
"use strict";
var easysoap = require('easysoap');
var clientParams = {
host : 'http://somewhere.com:9001',
path : '/somews.asmx',
wsdl : '/somews.asmx?WSDL'
};
var clientOptions = {
secure : false
};
var soapClient = easysoap.createClient(clientParams, clientOptions);
soapClient.call({'method' : 'Execute',
'params' : {
'ExecuteXML' : 1
}})
.then(function (callResponse) {
console.log(callResponse);
})
.catch(function (err) {
console.log("Got an error making SOAP call: ", err);
});

How to change the default error output in restify

Is there any way that I can change the default error output? Say I'm going to change the rest error output:
{
"code": "InvalidArgumentError",
"message": "blah blah..."
}
to:
{
"code": 10001,
"message": "blah blah",
"extraMsg": "blah blah"
}
Here are some of my ideas:
Listen to the error events.
It seems like not all the RestError have emitted extra events (like NotFound, MethodNotAllowed, VersionNotAllowed... do). So I can't catch all the errors to rewrite them.
Listen to an event before response data sent.
I look through the official documents and have found nothing relative.
Modify the implementation of the RestError class.
Well it's obviously not a good approach.
Any other ideas?
Finally I provide a customized JSON formatter to get what I want:
var server = restify.createServer( {
formatters: {
'application/json': function customizedFormatJSON( req, res, body ) {
// Copied from restify/lib/formatters/json.js
if ( body instanceof Error ) {
// snoop for RestError or HttpError, but don't rely on
// instanceof
res.statusCode = body.statusCode || 500;
if ( body.body ) {
body = {
code: 10001,
scode: body.body.code,
msg: body.body.message
};
} else {
body = {
code: 10001,
msg: body.message
};
}
} else if ( Buffer.isBuffer( body ) ) {
body = body.toString( 'base64' );
}
var data = JSON.stringify( body );
res.setHeader( 'Content-Length', Buffer.byteLength( data ) );
return data;
}
}
} );
While the answers above might work, the easiest way to add a custom field to the error body is to call the restify error constructor with an object (hash) instead of a string. The object has to contain the body key which is what you will see in the browser.
For example:
return next(new restify.InvalidArgumentError({body: {field: 'password', message: 'Password has to be at least 6 characters long'}}));
or
return next(new restify.UnauthorizedError({body: {foo: 'bar', name: 'john doe', message: 'whatever error message'}}));
Restify offer many ways to implement error management : http://mcavage.github.io/node-restify/#Error-handling
Why don't you create a new error type "myError" just like sample code :
var restify = require('restify');
var util = require('util');
function MyError(message) {
restify.RestError.call(this, {
restCode : 'MyError',
statusCode : 418,
message : message,
constructorOpt: MyError
});
this.name = 'MyError';
}
util.inherits(MyError, restify.RestError);
For common errors I think that overloading methods is not such a bad idea... (I don't speak about modifying restify, just overloading functions using prototype)
(edited)
I was able to provide additional data adding a property to the body object.
Notice the this.body.errors = errors line
var restify = require('restify');
var util = require('util');
function ValidationError(message, errors) {
restify.RestError.call(this, {
restCode: 'ValidationError',
statusCode: 400,
message: message,
constructorOpt: ValidationError
});
this.name = 'ValidationError';
this.body.errors = errors; //<---
}
util.inherits(ValidationError, restify.RestError);
`
You can use restify-errors-options
Your example simply becomes:
const restify = require('restify');
const errors = require('restify-errors');
const errorsOptions = require('restify-errors-options');
errorsOptions.add('extraMsg');
const err = new errors.BadRequestError({extraMsg: 'whatever you want'});
err.toJSON();
//=> {code: 'BadRequest', message: '', extraMsg: 'whatever you want'}
Please also note that the solution provided was only tested on restify 5.x
Follow this issue for more information.

Resources