I used Parse's CLI with the new Heroku integration to create the scaffold NodeJS project (parse new).
The example cloud function it gives you is:
// Hello
Parse.Cloud.define('hello', function(request, response) {
response.success('Hello world! ' + (request.params.a + request.params.b));
});
I can hit this route with the following CURL command and everything works fine:
curl -X POST \
-H "X-Parse-Application-Id: b8qPYS4SLSz0WoSWXlWeQosmF2jJPUPydetg3esR" \
-H "X-Parse-REST-API-Key: TOJLbfbNXSQcBdDVnU0MnKVu7SyamQvZmorHL5iD" \
-H "Content-Type: application/json" \
-d '{"a": "Adventurous ", "b": "Parser"}' \
https://api.parse.com/1/functions/hello
But then I added a new Class to my Parse Data, inserted a row, and tried to query & return the results. I keep getting {"code":143,"error":"Invalid webhook response status: 500 Internal Server Error"} as the response.
I'm fairly certain it is not my code that is the problem and am guessing there is some configuration step or something I'm missing.
Here is my modified Parse function:
// Hello
Parse.Cloud.define('hello', function(request, response) {
var query = Parse.Query("Favorites");
query.find({ useMasterKey: true }).then(
function(results) {
response.success('win');
}, function() {
response.error('fail');
});
});
And a picture of my Parse Class with the inserted row:
I have Googled the error and can't find any good answers only poorly worded questions. I'm completely at a loss here. Thanks in advance for your help.
Looks like Parse is wrong initialised on register-webhooks.js post deploy script:
Parse.initialize(process.env.PARSE_APP_ID, "unused", process.env.PARSE_MASTER_KEY);
And without second parameter (JavaScript Key) you can't execute any Parse.Query from cloud functions.
So my solution is:
Add new PARSE_JS_KEY to Heroku Config Variables (value is JavaScript Key from Parse->Settings->Keys)
In server.js file add line:
Parse.initialize(process.env.PARSE_APP_ID, process.env.PARSE_JS_KEY, process.env.PARSE_MASTER_KEY);
before require('./cloud/main.js');
PS: Place process.env.PARSE_JS_KEY directly in register-webhooks.js initializer does not work.
Related
This my first time hooking up to an API. I'm attempting to query NIH project data and can seem to hook up correctly to it as I get a status code of 200. The issue I have is when I try to print the output. I get a URL rejection despite having access. The documentation suggests that if any issues come up, it may be due to my IP being blocked due to a variety of reasons. I reached out to the API support team there and I don't have any issues with a blocked IP. They had me run some curl requests via command prompt and I was able to execute those correctly. This leads me to believe I have a code issue. What am I doing wrong here?
NIH API Info
import requests
params = {
"criteria":
{
"fiscal_years":[2019,2018]
},
"include_fields": [
"ApplId","SubprojectId","FiscalYear","Organization", "ProjectNum","OrgCountry",
"ProjectNumSplit","ContactPiName","AllText","FullStudySection",
"ProjectStartDate","ProjectEndDate"
],
"offset":0,
"limit":25,
"sort_field":"project_start_date",
"sort_order":"desc"
}
response = requests.post("https://api.reporter.nih.gov/v2/projects/Search", data = params)
#print(response.status_code)
print(response.text)
Sample curl script and output:
curl -X POST "https://api.reporter.nih.gov/v2/projects/search" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"criteria\":{\"covid_response\":[\"Reg-CV\",\"CV\"]},\"include_fields\":[\"ApplId\",\"SubprojectId\",\"FiscalYear\",\"Organization\",\"ProjectNum\",\"OrgCountry\",\"ProjectNumSplit\",\"ContactPiName\",\"AllText\",\"FullStudySection\",\"ProjectStartDate\",\"ProjectEndDate\"],\"offset\":0,\"limit\":10}"
The solution is simple, but easily missed. You need json=params See this question: How to POST JSON data with Python Requests?
response = requests.post("https://api.reporter.nih.gov/v2/projects/search", json=params)
Below is the entire code with the small change:
import requests
params = {
"criteria":
{
"fiscal_years":[2019,2018]
},
"include_fields": [
"ApplId","SubprojectId","FiscalYear","Organization", "ProjectNum","OrgCountry",
"ProjectNumSplit","ContactPiName","AllText","FullStudySection",
"ProjectStartDate","ProjectEndDate"
],
"offset":0,
"limit":25,
"sort_field":"project_start_date",
"sort_order":"desc"
}
response = requests.post("https://api.reporter.nih.gov/v2/projects/search", json=params)
print(response.status_code)
print(response.text)
The start of result looks like:
{"meta":{"search_id":null,"total":160216,"offset":0,"limit":25,"sort_field":"project_start_date","sort_order":"desc","sorted_by_relevance":false,"properties":{}},"results":[{"appl_id":10396858,"subproject_id":null,"fiscal_year":2018,"project_num":"7K01AG046366-06","organization":{"org_name":"UNIVERSITY OF CONNECTICUT SCH OF MED/DNT","city":null,"country":null,"org_city":"FARMINGTON","org_country":"UNITED STATES","org_state":"CT","org_state_name":null,"dept_type":"NEUROSCIENCES","fips_country_code":null,"org_duns":["022254226"],...
I'm working with Webhooks and I am trying to run a Curl request from my node.js code. I'm using the npm request package to do this. I'm having trouble finding the proper way to convert the Curl request to code in my application that will send the request.
This is the Curl request:
curl -X POST https://tartan.plaid.com/connect \
-d client_id=test_id \
-d secret=test_secret \
-d username=plaid_test \
-d password=plaid_good \
-d type=wells \
-d options='{
"webhook":"http://requestb.in/",
"login_only":true }'
This works fine when I run it in my terminal so I know the credentials work and it is talking to the server.
Here is my Node.js code:
var request = require('request');
var opt = {
url: 'https://tartan.plaid.com/connect',
data: {
'client_id': 'test_id',
'secret': 'test_secret',
'username': 'plaid_test',
'password': 'plaid_good',
'type': 'wells',
'webhook': 'http://requestb.in/',
'login_only': true
}
};
request(opt, function (error, response, body) {
console.log(body)
});
It should return an item but all I am getting is:
{
"code": 1100,
"message": "client_id missing",
"resolve": "Include your Client ID so we know who you are."
}
All the credentials are from the Plaid website and they work in my terminal just fine so I think it's just the way I am writing my Node.js code that is causing the problem.
If anyone could help my find the right way to write the node code so that it does what the curl request does in the terminal that would be appreciated! Thanks!
You may want to use form: instead of data: in your options. Hopefully that will do the trick.
The default method for request is GET. You want a POST, so you have to set that as a parameter. You also have to send the data as JSON according to the documentation. So I believe this should work:
var opt = {
url: 'https://tartan.plaid.com/connect',
method: "POST",
json: {
'client_id': 'test_id',
'secret': 'test_secret',
'username': 'plaid_test',
'password': 'plaid_good',
'type': 'wells',
'webhook': 'http://requestb.in/',
'login_only': true
}
};
See explainshell: curl -X -d for an explanation of what your curl command actually does.
You send a POST request
You send data using using the content-type application/x-www-form-urlencoded
To replicate that with request you have to configure it accordingly:
var opt = {
url: 'https://tartan.plaid.com/connect',
form: {
// ...
}
};
request.post(opt, function (error, response, body) {
console.log(body)
});
See application/x-www-form-urlencoded for more examples.
I have built an application that assigns a customer a twilio number that they will be able to send text messages to. I am able to create the number dynamically but i now need to set the webhook inside the code for the incoming texts so that twilio knows how to respond. Right now i am only aware of a way to do it through the console which wont work for what i need. Any help would be greatly appreciated. Thanks!
Twilio developer evangelist here.
Thanks to Alex for the answer, that's spot on. I just wanted to add a bit of code as I noticed the question was tagged Node.js.
Here is how to do the API calls with the Node.js helper library.
Update an existing incoming phone number:
var accountSid = 'YOUR_ACCOUNT_NUMBER';
var authToken = 'YOUR_AUTH_TOKEN';
var client = require('twilio')(accountSid, authToken);
client.incomingPhoneNumbers("PHONE_NUMBER_SID").update({
smsUrl: "http://demo.twilio.com/docs/sms.xml"
}, function(err, number) {
if (err) { console.error(err); return }
console.log(number.voiceUrl);
});
When buying the number:
client.incomingPhoneNumbers.create({
friendlyName: "My Company Line",
smsUrl: "http://demo.twilio.com/docs/voice.xml",
phoneNumber: "PHONE_NUMBER_TO_PURCHASE"
}, function(err, number) {
if (err) { console.error(err); return }
console.log(number.sid);
});
It can be done using Optional Parameters
when you update an incoming phone number:
https://www.twilio.com/docs/api/rest/incoming-phone-numbers?code-sample=code-update-an-incomingphonenumber&code-language=curl&code-sdk-version=json
$ curl -XPOST https://api.twilio.com/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/IncomingPhoneNumbers/PN2a0747eba6abf96b7e3c3ff0b4530f6e.json \
-d "VoiceUrl=http://demo.twilio.com/docs/voice.xml" \
-d "SmsUrl=http://demo.twilio.com/docs/sms.xml" \
-u 'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:your_auth_token'
or when you create a new incoming phone number:
https://www.twilio.com/docs/api/rest/incoming-phone-numbers?code-sample=code-create-a-new-incomingphonenumber&code-language=curl&code-sdk-version=json
$ curl -XPOST https://api.twilio.com/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/IncomingPhoneNumbers.json \
-d "FriendlyName=My%20Company%20Line" \
-d "SmsUrl=http://demo.twilio.com/docs/sms.xml" \
-d "PhoneNumber=%2B15105647903" \
-d "SmsMethod=GET" \
-u 'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:your_auth_token'
My Lambda function in node.js:
console.log('Loading function');
exports.handler = function(event, context) {
console.log('value1 =', event.key1);
context.succeed("Hello " + event.key1);
};
I want a client (my laptop) to send an object that contains the value "world" to this lambda function. The function adds "Hello " and returns "Hello world".
I used cmd with curl with the following statement:
curl -X POST -d '{"key1":"world"}' https://blablablabla.execute-api.us-west-2.amazonaws.com/prod/helloworld2
But I only get back {"message":"internal server error"}
Any ideas? Are there any other ways to send the "world" value. Maybe javascript in a html file or a simple java app in Eclipse? The lambda function itself is fine. I successfully tested it with a test event.
Your function seems fine. But you are missing the Content-Type header on your cURL command. Do it as follows:
curl -H "Content-Type: application/json" -X POST -d "{\"key1\": \"World\"}" https://blablablabla.execute-api.us-west-2.amazonaws.com/prod/helloworld2
You can double check this requirement in this AWS documentation.
Update: Try with this function (I only added the callback parameter)
'use strict';
console.log('Loading function');
exports.handler = function(event, context, callback) {
console.log('value1 =', event.key1);
callback(null, {"Hello": event.key1});
};
I have written a shell script code which is successfully adding a new OS Connection IP in Imperva system/instance.
## Create a new IP OS connection in a given site, server group.
create_ip()
{
JSESSIONID="${1}"
addThisIP="${2}"
siteName="${3}"
serverGroupName="${4}"
echo -e "\n- Trying to create a new OS connection IP now.\n";
##Make sure while initiating a REST API call, any parameter which has ' ' (space) in Imperva should be substituted with '%20'.
##JSESSIONID will be generated first and will be available to this function
create_new_ip_output="$(curl -ik -X POST -H "Cookie: JSESSIONID=$JSESSIONID" -H "Content-Type: application/json" -H "Accept: application/json" "https://${MX}:8083/SecureSphere/api/v1/conf/serverGroups/${siteName// /%20}/${serverGroupName// /%20}/servers/${addThisIP}" -d '{"connection-mode":"SSH","host-name":"thisLinuxServer.fdqn","OS-type":"linux","user-name":"enter_your_userID"}')";
return_code="$?";
if [[ "${return_code}" == "0" && ! `echo "${create_new_ip_output}" | grep "do not have permission"` ]]; then
echo -e "\n\n- OS connection IP (${addThisIP}) created successfully in site: ${siteName}, servergroup: ${serverGroupName} and stdout:\n${create_new_ip_output}\n";
return 0;
else
echo -e "\n\n- Failed to create a new OS connection IP (${addThisIP}) in site: ${siteName} and servergroup: ${serverGroupName}\n- using session ID: ${JSESSIONID}, error log:\n${create_new_ip_output}\n";
return 1;
fi
}
OK, the above code works fine and once run, I see valid output showing whether an IP got added successfully or what was the failure message.
Now, I'm trying to implement the same functionality in NodeJS.
To do that, I have successfully created functions to generate JSESSIONID (so that I can use it to perform multiple REST/API call operations, rather than creating a new session each time for any operation), successfully deleting a JSESSIONID (i.e. to logoff/out from Imperva session so that I don't hit the limit) and to successfully search an IP in Imperva system if it has been previously added.
Using the above shell script logic, I have written the following NodeJS code to add a new OS Connection IP in Imperva using Rest/API, but I'm getting an error.
//Imperva create IP
//qData is a hash array that has valid index/value pair values.
var impervaCreateIP = function(qData){
var deferred = Q.defer();
var data = ''
var options = {
hostname: 'myImpervaServerInstance.mycompanydomain.com',
port: 8083,
method: 'POST',
path: '/SecureSphere/api/v1/conf/serverGroups/'+ qData['siteName'] + '/' + qData['serverGroupName'] + '/servers/' + qData['ip'],
headers: {
'Content-Type': 'application/xml',
'X-Requested-With': 'Nodejs',
'Cookie': 'JSESSIONID='+qData['sid']
}
}
//svtLog() is a logger that I'm using to log messages to a file. Out of scope of this post.
svtLog('info','Imperva','Inside impervaCreateIP function')
svtLog('info','Imperva',qData['ip'])
svtLog('info','Imperva',qData['siteName'])
svtLog('info','Imperva',qData['serverGroupName'])
svtLog('info','Imperva','')
console.log('Inside impervaCreateIP')
console.log(options);
httpHelp(options, data)
.then(function(fullResponse){
var result = JSON.parse(fullResponse[1])
console.log("11 -----")
console.log(result)
console.log("22 -----")
deferred.resolve(qData['sid'])
console.log(result)
})
.fail(function(e){
svtLog('error','Imperva','Failed to add IP in Imperva')
svtLog('info','Imperva',qData['ip'])
svtLog('error','Imperva',e)
svtLog('info','Imperva','')
deferred.reject(e)
})
return deferred.promise;
}
Error message:
Inside impervaCreateIP
{ hostname: 'myImpervaServerInstance.mycompanydomain.com',
port: 8083,
method: 'POST',
path: '/SecureSphere/api/v1/conf/serverGroups/some%20Site%20NameInImperva/someServerGroupNameInImperva_01/servers/10.20.30.40',
headers:
{ 'Content-Type': 'application/xml',
'X-Requested-With': 'Nodejs',
Cookie: 'JSESSIONID=7B3C378D365B673F6C749847DEDC7D8F } }
[SyntaxError: Unexpected token <]
I'm looking for 2 things:
1. How to resolve the error (as shown above).
2. How to pass CURL's -d option {...} body parameters in the NodeJS code above, like I used it in the shell script.
PS: Changing POST to GET (method), assures that the code is fine syntax wise as it successfully shows the IP (with GET operation) with the above NodeJS code.
So, it's failing only when I use POST (i.e. when I'm trying to create an IP) -vs- GET (which I use to find an IP exist or not). I checked as per the Imperva API doc, the response comes in JSON format. Not sure if due to missing bullet# 2 question, I'm getting this Syntax error with POST.
OK.
Solution to both bullet# 1 and #2 was to set the CURL "-d option values" in NodeJS like shown below (I was setting it blank earlier):
var data = '{"connection-mode":"SSH","host-name":"thisLinuxServer.fdqn","OS-type":"linux","user-name":"enter_your_userID"}'
Now, both options and data will be sent to httpHelp(options,data) and it'll work.
The above is just an dummy data value. Usually I'd pass valid host-name in the JSON object.
Never thought that not setting the data variable would result in this syntax error.
Other thing, I was missing BIG time was the value for 'Content-Type' inside headers variable. That was the reason, the error message was having "<" bracket in it (as by default it looks for a <body>...</body> section containing some XML format but in our case, the HTML response contained or was getting returned in JSON { ... } format way for the body section. That's why it was showing an error for unexpected token <.
As per the API doc, it should have been "JSON" type, thus changed that line to
'Content-Type': 'application/json',