In my Project I send Multipart form-data from angular side to nodejs. the format of data i received is
{ name: 'customer.test.14',
email: 'test14#gmail.net',
website: 'www.google.com',
contact_name: 'Vijay',
contact_number: '+123456789022',
profile: 'Testing',
provider_category: 'exchange',
services_offered: 'Testing',
description: 'Test',
image:
[ { size: 1474,
type: 'image/png',
path: 'bc31dac580a7c2086f306fe0b9b5182d/',
basename: 'icon_dd_chart_grey.png' } ] }
I want to send data this to another api in nodejs. but api does not upload image.
here is my code
var request = require('request');
var api_url = global.common.base_url + 'vcard/1.0.0/visit_card/' + req.param('uuid') +'/';
console.log(req.body);
request({
url: api_url,
method: 'PUT',
headers: {
'Content-Type': 'multipart/form-data;',
'Authorization': 'Bearer '+req.cookies.apitoken
},
json: req.body,
}, function(error, response, body) {
if(response.statusCode == 200 && !error){
res.end(JSON.stringify(body));
}else{
res.send(response.statusCode, { error: body });
}
});
You can archive this using "Okhttp3". Please refer this video tutorial form reference and usage and documentation.
Eg: upload two bodies (json and a image) to a single endpoint at the same time:
const okhttp = require('okhttp');
var MimeBuilder = okhttp.MimeBuilder;
var Request = okhttp.Request;
var RequestBody = okhttp.RequestBody;
var RequestBuilder = okhttp.RequestBuilder;
var FormEncodingBuilder = okhttp.FormEncodingBuilder;
var MultiPartBuilder = okhttp.MultiPartBuilder;
let json = JSON.stringify({title:'test'});
var image = fs.readFileSync(path.resolve(__dirname, 'test.jpg'));
let mp_body = new MultiPartBuilder().addPart(RequestBody.create(json, 'Content-Type: application/json; charset=UTF-8'))
.addPart(RequestBody.create(image, new MimeBuilder().contentType('image/jpeg').contentTransferEncoding('binary').build()))
.type(MultiPartBuilder.FORMDATA).build();
new RequestBuilder().url('https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart')
.header('Authorization', 'Bearer OAUTH2_TOKEN_HERE')
.POST(mp_body).buildAndExecute().then(console.log).catch(console.error);
Related
I'm trying to create an app with the Spotify API, but can't seem to get it to work. The error I'm getting is that 'request' is undefined and I've replaced it with JQuery too and that doesn't work either. Can anyone tell me why I might be getting that error and how to fix it? Should I be running it inside node.js in cmd?
var client_id = '?';
var client_secret = '?';
var authOptions = {
url: 'https://accounts.spotify.com/api/token',
headers: {
'Authorization': 'Basic ' + (new Buffer(client_id + ':' + client_secret).toString('base64'))
},
form: {
grant_type: 'client_credentials'
},
json: true
};
request.post(authOptions, function(error, response, body) {
if (!error && response.statusCode === 200) {
var token = body.access_token;
}
else {
console.log(JSON.stringify(error))
}
});
The spotify documentation is out of date, as request is deprecated, and should no longer be used.
Instead, you can make a request with built-in Node.js libraries, as mentioned in the documentation.
It should be run with node.js, i.e. node <filename>
const https = require('https')
const client_id = 'CLIENT_ID'
const client_secret = 'CLIENT_SECRET'
const reqBody = JSON.stringify({
grant_type: 'client_credentials'
})
const authOptions = {
hostname: 'accounts.spotify.com',
port: 443,
path: '/api/token',
method: 'POST',
headers: {
'Authorization': 'Basic ' + (new Buffer.from(client_id + ':' + client_secret).toString('base64')),
'Content-Type': 'application/json',
'Content-Length': reqBody.length
}
}
const req = https.request(authOptions, res => {
console.log(`statusCode: ${res.statusCode}`)
res.on('data', d => {
process.stdout.write(d)
})
})
req.write(reqBody);
req.end();
I'm using the sandbox API at the moment, and I can query the products, including individually, but if I try and place a buy order, the response I get is { message: 'Product not found' }.
Here's my code:
async function cb_request( method, path, headers = {}, body = ''){
var apiKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx',
apiSecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx',
apiPass = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx';
//get unix time in seconds
var timestamp = Math.floor(Date.now() / 1000);
// set the request message
var message = timestamp + method + path + body;
//create a hexedecimal encoded SHA256 signature of the message
var key = Buffer.from(apiSecret, 'base64');
var signature = crypto.createHmac('sha256', key).update(message).digest('base64');
//create the request options object
var baseUrl = 'https://api-public.sandbox.pro.coinbase.com';
headers = Object.assign({},headers,{
'CB-ACCESS-SIGN': signature,
'CB-ACCESS-TIMESTAMP': timestamp,
'CB-ACCESS-KEY': apiKey,
'CB-ACCESS-PASSPHRASE': apiPass,
'USER-AGENT': 'request'
});
// Logging the headers here to ensure they're sent properly
console.log(headers);
var options = {
baseUrl: baseUrl,
url: path,
method: method,
headers: headers
};
return new Promise((resolve,reject)=>{
request( options, function(err, response, body){
if (err) reject(err);
resolve(JSON.parse(response.body));
});
});
}
async function main() {
// This queries a product by id (successfully)
try {
console.log( await cb_request('GET','/products/BTC-USD') );
}
catch(e) {
console.log(e);
}
// Trying to place a buy order here (using the same id as above) returns { message: 'Product not found' }
var buyParams = {
'type': 'market',
'side': 'buy',
'funds': '100',
'product_id': 'BTC-USD'
};
try {
var buy = await cb_request('POST','/orders',buyParams);
console.log(buy);
}
catch(e) {
console.log(e);
}
}
main();
I've tried sending the params in the body, which responds with invalid signature, even when stringified. I've also tried using the params shown in the API docs, but that responds with product not found too.
Any ideas? TIA
As j-petty mentioned you need to send data as request body for POST operation as described in the API documentation so this is why you get "product not found".
Here is working code based on what your shared:
var crypto = require('crypto');
var request = require('request');
async function cb_request( method, path, headers = {}, body = ''){
var apiKey = 'xxxxxx',
apiSecret = 'xxxxxxx',
apiPass = 'xxxxxxx';
//get unix time in seconds
var timestamp = Math.floor(Date.now() / 1000);
// set the request message
var message = timestamp + method + path + body;
console.log('######## message=' + message);
//create a hexedecimal encoded SHA256 signature of the message
var key = Buffer.from(apiSecret, 'base64');
var signature = crypto.createHmac('sha256', key).update(message).digest('base64');
//create the request options object
var baseUrl = 'https://api-public.sandbox.pro.coinbase.com';
headers = Object.assign({},headers,{
'content-type': 'application/json; charset=UTF-8',
'CB-ACCESS-SIGN': signature,
'CB-ACCESS-TIMESTAMP': timestamp,
'CB-ACCESS-KEY': apiKey,
'CB-ACCESS-PASSPHRASE': apiPass,
'USER-AGENT': 'request'
});
// Logging the headers here to ensure they're sent properly
console.log(headers);
var options = {
'baseUrl': baseUrl,
'url': path,
'method': method,
'headers': headers,
'body': body
};
return new Promise((resolve,reject)=>{
request( options, function(err, response, body){
console.log(response.statusCode + " " + response.statusMessage);
if (err) reject(err);
resolve(JSON.parse(response.body));
});
});
}
async function main() {
// This queries a product by id (successfully)
try {
console.log('try to call product------->');
console.log( await cb_request('GET','/products/BTC-USD') );
console.log('product------------------->done');
}
catch(e) {
console.log(e);
}
var buyParams = JSON.stringify({
'type': 'market',
'side': 'buy',
'funds': '10',
'product_id': 'BTC-USD'
});
try {
console.log('try to call orders------->');
var buy = await cb_request('POST','/orders', {}, buyParams);
console.log(buy);
console.log('orders----------------------->done');
}
catch(e) {
console.log(e);
}
}
main();
You need to send a POST request to the /orders endpoint and include the body in the request payload.
There are some example answers in this question.
var options = {
baseUrl: baseUrl,
url: path,
method: method,
headers: headers
json: true,
body: body
}
request.post(options, function(err, response, body){
if (err) reject(err);
resolve(JSON.parse(response.body));
});
It's worth mentioning that the sandbox API has different results than the production API. Consider the following CURLs.
Sandbox API:
❯ curl --request GET \
--url https://api-public.sandbox.exchange.coinbase.com/products/ETH-USD \
--header 'Accept: application/json'
{"message":"NotFound"}%
Production API:
❯ curl --request GET \
--url https://api.exchange.coinbase.com/products/ETH-USD \
--header 'Accept: application/json'
{"id":"ETH-USD","base_currency":"ETH","quote_currency":"USD","base_min_size":"0.00029","base_max_size":"2800","quote_increment":"0.01","base_increment":"0.00000001","display_name":"ETH/USD","min_market_funds":"1","max_market_funds":"4000000","margin_enabled":false,"fx_stablecoin":false,"max_slippage_percentage":"0.02000000","post_only":false,"limit_only":false,"cancel_only":false,"trading_disabled":false,"status":"online","status_message":"","auction_mode":false}%
You'll notice that the paths are identical but you get different results so keep that in mind. For testing purposes BTC-USD can be used.
I wish to upload files in the form of a stream into Azure Storage but I don't want to use Azure SDK instead I want to do it in a more generic way using REST API and not BlobServiceClient.
Is there a way to do so?
The reference links for the same can be found here:
https://learn.microsoft.com/en-us/azure/storage/common/storage-samples-javascript?toc=/azure/storage/blobs/toc.json#blob-samples
https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/storage/storage-blob/samples/javascript/advanced.js#L74
But the links mentioned here propose a solution using Azure SDK. I want to do it without Azure SDK
Here's the code:
const CryptoJS = require("crypto-js");
const request = require("request");
const fs = require("fs");
const account = process.env.ACCOUNT_NAME || "";
const key = process.env.ACCOUNT_KEY || "";
const containerName = "demo";
const blobName = "dummyfile.txt";
var strTime = new Date().toUTCString();
// read file to Stream
var filePath = `${__dirname}/README.md`;
const readStream = fs.createReadStream(filePath);
var stat = fs.statSync(filePath);
string_params = {
verb: "PUT",
"Content-Encoding": "",
"Content-Language": "",
"Content-Length": stat.size,
"Content-MD5": "",
"Content-Type": "application/octet-stream",
Date: "",
"If-Modified-Since": "",
"If-Match": "",
"If-None-Match": "",
"If-Unmodified-Since": "",
Range: "",
CanonicalizedHeaders:
"x-ms-blob-type:BlockBlob\nx-ms-date:" +
strTime +
"\nx-ms-version:" +
"2020-04-08\n",
CanonicalizedResource: `/${account}/${containerName}/${blobName}`,
};
var strToSign = `${string_params["verb"]}\n${string_params["Content-Encoding"]}\n${string_params["Content-Language"]}\n${string_params["Content-Length"]}\n${string_params["Content-MD5"]}\n${string_params["Content-Type"]}\n${string_params["Date"]}\n${string_params["If-Modified-Since"]}\n${string_params["If-Match"]}\n${string_params["If-None-Match"]}\n${string_params["If-Unmodified-Since"]}\n${string_params["Range"]}\n${string_params["CanonicalizedHeaders"]}${string_params["CanonicalizedResource"]}`;
var secret = CryptoJS.enc.Base64.parse(key);
var hash = CryptoJS.HmacSHA256(strToSign, secret);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
var auth = `SharedKey ${account}:` + hashInBase64;
const options = {
url: `https://${account}.blob.core.windows.net/${containerName}/${blobName}`,
headers: {
Authorization: auth,
"x-ms-blob-type": "BlockBlob",
"x-ms-date": strTime,
"x-ms-version": "2020-04-08",
"Content-Type": "application/octet-stream",
"Content-Length": stat.size,
},
body: readStream,
};
function callback(error, response, body) {
console.log(response.statusCode);
console.log(response.statusMessage);
if (!error && response.statusCode == 200) {
console.log(error);
console.log(response);
console.log(body);
}
}
request.put(options, callback);
The error which I am getting is:
TypeError: Cannot read property 'statusCode' of undefined
Edit: The problem was solved by Pamela's code + the issue I found was there's was an error in initializing .env variables.
You could use Put Blob Rest API to upload a stream. There is a sample using node.js.
const CryptoJS = require("crypto-js");
const request = require("request");
const fs = require('fs');
const account = "account-name";
const key = "account-key";
var strTime = new Date().toUTCString();
var filePath = 'your-file-path';
const readStream = fs.createReadStream(filePath);
var stat = fs.statSync(filePath);
string_params = {
'verb': 'PUT',
'Content-Encoding': '',
'Content-Language': '',
'Content-Length': stat.size,
'Content-MD5': '',
'Content-Type': 'application/octet-stream',
'Date': '',
'If-Modified-Since': '',
'If-Match': '',
'If-None-Match': '',
'If-Unmodified-Since': '',
'Range': '',
'CanonicalizedHeaders': 'x-ms-blob-type:BlockBlob\nx-ms-date:' + strTime + '\nx-ms-version:' + '2020-04-08\n',
'CanonicalizedResource': `/${account}/containername/myblob`
}
var strToSign = `${string_params['verb']}\n${string_params['Content-Encoding']}\n${string_params['Content-Language']}\n${string_params['Content-Length']}\n${string_params['Content-MD5']}\n${string_params['Content-Type']}\n${string_params['Date']}\n${string_params['If-Modified-Since']}\n${string_params['If-Match']}\n${string_params['If-None-Match']}\n${string_params['If-Unmodified-Since']}\n${string_params['Range']}\n${string_params['CanonicalizedHeaders']}${string_params['CanonicalizedResource']}`
console.log(strToSign);
var secret = CryptoJS.enc.Base64.parse(key);
var hash = CryptoJS.HmacSHA256(strToSign, secret);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
var auth = `SharedKey ${account}:` + hashInBase64;
console.log(auth)
const options = {
url: `https://${account}.blob.core.windows.net/containername/myblob`,
headers: {
Authorization: auth,
'x-ms-blob-type': 'BlockBlob',
"x-ms-date": strTime,
"x-ms-version": "2020-04-08",
'Content-Type': "application/octet-stream",
'Content-Length': stat.size
},
body: readStream
};
function callback(error, response, body) {
console.log(response.statusCode);
console.log(response.statusMessage);
if (!error && response.statusCode == 200) {
console.log(error);
console.log(response);
console.log(body);
}
}
request.put(options, callback);
You can try using Azure REST API for the Blob Operations. You can find REST API's for Blob here - Operations on Blob
The question is how are you going to handle stream upload at runtime. Azure SDK supports the stream upload. However in case of REST API, you'll need to handle that by yourself.
Uploading stream or parallel data you'll need some wrapper around this REST API Calls to achieve that
Hope you find this useful.
I want to to bulk translocation and for that I uploaded the.csv file, its worked for me if I am using curl command but when I used its on node code its showing me error "file not uploaded"
Regarding to curl I am using that code which is working for me :-
curl -F 'data=#/var/www/html/achupload.csv' https://sandbox.usaepay.com/api/v2/bulk_transactions -H "Authorization: Basic X3llMVI3Mk9PdzFHOXBqcW1GaVp2NHJINjRc="
and this is my node code which are showing me error message :-
var request = require('request');
var headers = {
'Authorization': 'Basic X3llMVI3Mk9PdzFHOXBqcW1GaVp2NHJINjRc='
};
var dataString = '#/var/www/html/achupload.csv';
var options = {
url: 'url',
method: 'POST',
headers: headers,
data: dataString
};
console.log("options====",options);
function callback(error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
}
else{
console.log("notttttttttttt================",response.body);
}
}
request(options, callback);
How about this modification?
Modification points:
File content is retrieved with fs.createReadStream().
The file is sent as formData.
Modified script:
From:
var request = require('request');
var headers = {
'Authorization': 'Basic ###'
};
var dataString = '#/var/www/html/achupload.csv';
var options = {
url: 'url',
method: 'POST',
headers: headers,
data: dataString
};
To:
var fs = require('fs'); // Added
var request = require('request');
var headers = {
'Authorization': 'Basic ###'
};
var dataString = {data: fs.createReadStream('/var/www/html/achupload.csv')}; // Modified
var options = {
url: 'url',
method: 'POST',
headers: headers,
formData: dataString // Modified
};
Note:
In this modified script, 'Authorization': 'Basic ###' was used. Please be careful this. When you use this, please replace ### to yours.
References:
fs.createReadStream()
multipart/form-data (Multipart Form Uploads)
If this didn't resolve your issue, I apologize.
I'm trying to send http post request using native node js http request.
I'm using the following code but nothing happens:
var http = require('http');
var options = {
hostname: '192.168.1.134',
port: '8082',
path: '/api',
method: 'POST',
headers: {'content-type': 'application/json',
'cache-control': 'no-cache'}
};
callback = function(response)
{
var result = [];
response.on('data', function (chunk)
{
result.push(chunk);
});
response.on('end', function ()
{
console.log("LOCAL END" + result);
});
}
var req = http.request(options, callback);
req.write(JSON.stringify(
{
customer: 'customer',
deviceIndicator: 'id',
userId: 'id2',
lastVersion: 999
}), 'utf8' ,
function(data)
{
console.log('flushed: ' + data);
});
req.end();
console.log(" - trying to post to example - done" );
But if i'm adding the following dummy calls i'm getting an answer from my local server as expected:
var options1 = {
hostname: 'www.google.com',
port: '80',
path: '/',
headers: {'cache-control': 'no-cache'}
};
callback1 = function(response1) {
var str = ''
response1.on('data', function (chunk) {
str += chunk;
});
response1.on('end', function () {
console.log("GOOGLE END" + str);
});
}
var req1 = http.request(options1, callback1);
req1.end();
console.log("sent to google - done");
What am i doing wrong?
Make sure 192.168.1.134:8082 is reachable and responding (using a browser, curl or wget) then try adding a content-length header:
var http = require('http');
var payload = JSON.stringify({
customer: 'customer',
deviceIndicator: 'id',
userId: 'id2',
lastVersion: 999
});
var options = {
hostname: '192.168.1.134',
port: 8082,
path: '/api',
method: 'POST',
headers: {
'content-length': Buffer.byteLength(payload), // <== here
'content-type': 'application/json',
'cache-control': 'no-cache'
}
};
var req = http.request(options, function(response) {
var result = [];
response.on('data', function(chunk) {
result.push(chunk);
});
response.on('end', function () {
console.log('LOCAL END' + result);
});
});
req.write(payload);
req.end();
Eventually, I discovered that the problem was with the device itself which had some kind of problem..
When sent http request to a direct ip address nothing happened but when sent to an address that need dns server it is working...
Unfortunately, I don't have any additional info about this bug...