Post JSON from express to external server - json

I want to be able to post JSON to another server directly from node (using express). Basically, I don't want to expose my api keys when calling different api's but still be able to call the service.
This is what I'm trying to do, but from the server instead of the client:
https://github.com/GetResponse/DevZone/blob/master/API/examples/javascript_synopsis.html
JS from client that I want to implement:
var api_key = 'ENTER_YOUR_API_KEY_HERE';
// API 2.x URL
var api_url = 'http://api2.getresponse.com';
function add_contact() {
var campaigns = {};
// find campaign named 'test'
$.ajax({
url : api_url,
data : JSON.stringify({
'jsonrpc' : '2.0',
'method' : 'get_campaigns',
'params' : [
api_key,
{
// find by name literally
'name' : { 'EQUALS' : 'test' }
}
],
'id' : 1
}),
type : 'POST',
contentType : 'application/json',
dataType : 'JSON',
crossDomain : true,
async : false,
success : function(response) {
// uncomment following line to preview Response
// alert(JSON.stringify(response));
campaigns = response.result;
}
});
// because there can be only (too much HIGHLANDER movie) one campaign of this name
// first key is the CAMPAIGN_ID required by next method
// (this ID is constant and should be cached for future use)
var CAMPAIGN_ID;
for(var key in campaigns) {
CAMPAIGN_ID = key;
break;
}
$.ajax({
url : api_url,
data : JSON.stringify({
'jsonrpc' : '2.0',
'method' : 'add_contact',
'params' : [
api_key,
{
// identifier of 'test' campaign
'campaign' : CAMPAIGN_ID,
// basic info
'name' : 'Test',
'email' : 'test#test.test',
// custom fields
'customs' : [
{
'name' : 'likes_to_drink',
'content' : 'tea'
},
{
'name' : 'likes_to_eat',
'content' : 'steak'
}
]
}
],
'id' : 2
}),
type : 'POST',
contentType : 'application/json',
dataType : 'JSON',
crossDomain : true,
async : false,
success : function(response)
{
// uncomment following line to preview Response
// alert(JSON.stringify(response));
alert('Contact added');
}
});
}

I think your node server can act as a proxy to the third party server for your client requests.
Your server can collect all the input parameters needed for api call, say add_contact. Your node server, who has right credentials to access the 3rd party server, makes the api call, and passes on the response received to the client.
You can make use of built in http library in node, or the request module (more convenient) to make these calls.
Basically, you need to make a wrapper for the external apis you need, and you're all set.
I hope it helps.

Node.js provides an API for HTTP requests similar to jQuery's AJAX-API:
http://nodejs.org/api/http.html#http_http_request_options_callback

Related

POST requests with the Coinbase Pro API using Google Apps Script

I'm working with the Coinbase Pro API and while it's working well for GET requests I'm getting an "Invalid signature" when I try a POST request to place an order. I suspect that this may be something related to the "body" of the message since this is the only difference with the GET where "body" is empty.
I'm wondering if someone can help me on this.
function SellMarket (product,amount) {
var requestPath = '/orders';
var method = 'POST';
var body = JSON.stringify({
"type": "market",
"side": "buy",
"product_id": product,
//"size": amount,
'size': '1.0'
});
Logger.log('Sell - Body = '+body);
var responseJson = SignAndCallAPI(method, requestPath, body);
Logger.log('Sell Executed = '+responseJson);
}
function SignAndCallAPI(method, requestPath, body) {
var timestamp = Math.floor(Date.now() / 1000).toString();
var what = Utilities.base64Decode(Utilities.base64Encode(timestamp + method + requestPath + body));
var decodedsecret = Utilities.base64Decode(globalvars_CB.secret);
var hmac = Utilities.base64Encode(Utilities.computeHmacSha256Signature(what, decodedsecret));
var options = {
'method' : method,
'muteHttpExceptions' : true,
'headers' : {
'Content-Type': 'application/json',
'CB-ACCESS-KEY' : globalvars_CB.apikey,
'CB-ACCESS-SIGN' : hmac,
'CB-ACCESS-TIMESTAMP' : timestamp,
'CB-ACCESS-PASSPHRASE' : globalvars_CB.passphrase,
}
}
var responseJson = UrlFetchApp.fetch(globalvars_CB.uri+requestPath, options);
return(responseJson);
}
Untested suggestion, I recommend changing this bit in your code (in SignAndCallAPI function):
var options = {
'method' : method,
'muteHttpExceptions' : true,
'headers' : {
'Content-Type': 'application/json',
'CB-ACCESS-KEY' : globalvars_CB.apikey,
'CB-ACCESS-SIGN' : hmac,
'CB-ACCESS-TIMESTAMP' : timestamp,
'CB-ACCESS-PASSPHRASE' : globalvars_CB.passphrase,
}
}
to:
const options = {
method: method,
payload: body,
contentType: 'application/json',
muteHttpExceptions: true,
headers: {
'CB-ACCESS-KEY': globalvars_CB.apikey,
'CB-ACCESS-SIGN': hmac,
'CB-ACCESS-TIMESTAMP': timestamp,
'CB-ACCESS-PASSPHRASE': globalvars_CB.passphrase,
},
};
due to the reasons below:
Although you pass body to SignAndCallAPI function and use body in HMAC computation, you don't appear to actually include body in the POST request sent to the server. I was expecting to see it as the value to a payload property of your options object.
UrlFetchApp documentation (https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#fetchurl,-params) seems to indicate that Content-Type should be specified in the contentType property of your options object (as opposed to explicitly including a Content-Type header).
I've not looked at the Coinbase API documentation in detail (https://docs.pro.coinbase.com/#place-a-new-order), but body seems okay. You'll also want to make sure the HMAC computation for the CB-ACCESS-SIGN request header is as described in the documentation (https://docs.pro.coinbase.com/#signing-a-message).

Invalid parameter: JSON must contain an entry for 'default' or 'APNS_SANDBOX'. => APNS Error in Scala (lift framework)

I'm getting APN Invalid parameter: JSON must contain an entry for 'default' or 'APNS_SANDBOX'. the log is here
And the code block is here:
how to fix this? this is built in scala lift framework.
This is the example in javascript. In the same way, we have to use. Need to use cases for
1.APNS_SANDBOX
2.APNS
3.default
// Setup SNS Client
const snsClient = new SNS();
// whatever your full endpoint arn is. (from createPlatformEndpoint)
const endpointArn = 'arn:aws:sns:...';
// any extra data you want passed along with the message
const payload = {
someCustomKey: 'someCustomValue'
};
// send it
snsClient.publish({
TargetArn: endpointArn,
MessageStructure: 'json', // so we can put in a custom payload and message
Message: JSON.stringify({
default: `DEFAULT MESSAGE ${message}`,
APNS_SANDBOX: JSON.stringify({
aps: {
alert: `IOS Sandbox SPECIFIC MESSAGE ${message}`,
},
payload,
}),
APNS: JSON.stringify({
aps: {
alert: `IOS Prod SPECIFIC MESSAGE ${message}`,
},
payload,
}),
}),
}).promise().then(() => {
console.log('Notification sent!');
}).catch((err) => {
console.log('Failed to send with:', err);
});
Used this link for reference

Slack API call to postMessage not working

I'm just trying to make a simple postMessage call from a google apps script with an image attached, but I get the following response:
"{"ok":false,"error":"invalid_arg_name"}"
Here is the function that creates the payload:
function getPostMessagePayload(fileUrl) {
var content = {
"channel":"#data-vis",
"token": ACCESS_TOKEN,
"text":"Chart update:",
"attachments": [
{
"title": "Chart",
"fallback": "Fallback",
"text": "Testing chart",
"image_url": fileUrl
}
]
};
return content;
}
And here is where I make the request:
var POST_MESSAGE_ENDPOINT = 'https://slack.com/api/chat.postMessage';
function performPostMessage(payload) {
var res = UrlFetchApp.fetch(
POST_MESSAGE_ENDPOINT,
{
method: "post",
payload: JSON.stringify(payload),
muteHttpExceptions: true,
}).getContentText();
return res;
}
It's impossible to tell what the actual problem is. I've tried making my token obviously incorrect, the URL obviously incorrect, and deleting/adding random args and it gives the same response every time.
When I use the webhook to do this rather than the API, it works fine.
My app has the following permissions in Slack:
chat:write:bot
incoming-webhook
Problem
You are sending a JSON object as payload with your POST request, whilst the contentType parameter of the fetch() method is defaulted to application/x-www-form-urlencoded.
Solution 1
In addition to JSON.stringify(), to ensure the payload is sent correctly, wrap it in an encodeURIComponent() built-in function. If the issue persists, continue to solution 2.
Update to solution 1
Nearly forgot how fetch() method treats objects passed to payload with default x-www-form-urlencoded content type. Remove the JSON.stringify() entirely (and add encodeURI() / encodeURIComponent() if needed).
Solution 2
Slack API supports application/json content type of POST requests. In your case it might be easier to send the request with contentType parameter set to application.json (note that you will have to move authorization from payload to headers):
//fetch part;
var res = UrlFetchApp.fetch(
POST_MESSAGE_ENDPOINT,
{
method : 'post',
contentType : 'application/json',
headers : {
Authorization : 'Bearer ' + ACCESS_TOKEN
},
payload : JSON.stringify(payload),
muteHttpExceptions : true,
})
//payload part;
var payload = {
"channel" : "#data-vis",
"text" : "Chart update:",
"attachments" : [
{
"title" : "Chart",
"fallback" : "Fallback",
"text" : "Testing chart",
"image_url" : fileUrl
}
]
};
Useful links
fetch() method reference;
postMessage method reference (Slack API);

ExtJs, how to send JSON on store.load() using POST method

I need to send JSON object during read operation on store. Headers and method are set correctly.
var proxyDefinition = {
type : 'rest',
api : {
read : '/some/url'
},
actionMethods : {
create : 'POST',
read : 'POST',
update : 'PUT',
destroy : 'DELETE'
},
reader : {
type : 'json'
}
};
var store = Ext.create('Ext.data.Store', {
proxy : proxyDefinition,
model : 'SomeModel'
});
// this needs to send JSON
store.load({
params : {
filter: [] // some filtering rules
}
});
Problem is that POST body is sent as url encoded query string, not JSON object with property "filter".
ExtJs version 4.2.2
It is likely that you are looking for proxy config option paramsAsJson:true

Call Web Service method that insert an object from jquery ajax

I have a web service method similiar to this:
#Path("/insert_update")
#POST
#Consumes({ MediaType.APPLICATION_JSON })
#Produces({ MediaType.APPLICATION_JSON })
public Object insert(User obj) {
...(insert and return object)
}
And I want to call this method from jquery, using ajax. I've tried something like this:
var rootURL = "http://Path/to/my/web/service";
function insertUpdate() {
var user = {'name' : $("#name").val(),
'surname' : $("#surname").val(),
'surname1' : $("#surname1").val(),
'usertxt' : $("#usertxt").val(),
'password' : $("#password").val() };
$.ajax({
url : rootURL + "/insert_update",
type : "POST",
contentType: 'json',
dataType : "json",
data : user,
success : function(data) {
alert(JSON.stringify(data));
},
error : function(data) {
}
});
}
Is this code correct? When I try to use it I get this response:
Failed to load resource: Request header field Content-Type is not allowed by Access-Control-Allow-Headers.
XMLHttpRequest cannot load ... . Request header field Content-Type is not allowed by Access-Control-Allow-Headers.
I hope you can help me.
Greetings.
UPDATE
The web service is in the same machine, but in other port. I run the web service project on a WebSphere Application Server and then I only open the HTML file to test my code.
I have other method I don't have problem with, like this:
#Path("/all")
#GET
#Produces(MediaType.APPLICATION_JSON)
public Object all() {
...(get all users)
}
And the JQuery method for this code:
function all() {
$.ajax({
url : rootURL + "/all",
type : "GET",
dataType : "json",
success : function(data) {
$("#tabla tbody:last").empty();
$.each(data.data, function(i, item) {
$("#tabla tbody:last").append("<tr><td>"+item.id+"</td><td>"+item.name+
"</td><td>"+item.surname+"</td><td>"+item.surname1+"</td><td>"
+item.usertxt+"</td><td>"+item.password+"</td></tr>");
});
},
error : function(data) {
}
});
}
This works fine, I have no problem...but I had to donwload an extension for Chrome to test locally, Allow-Control-Allow-Origin.
Why with GET method I have no problem and with POST method yes???
Greetings.