What am I doing wrong in this Angular HTTP request? - javascript

I'm getting an error from dropbox api:
Error in call to API function "files/download": HTTP header "Dropbox-API-Arg": could not decode input as JSON.
let url = 'https://content.dropboxapi.com/2/files/download'
let headers = new Headers({ });
headers.append('Authorization', 'Bearer ...');
headers.append('Dropbox-API-Arg', '/readme.txt');
let options = new RequestOptions({ headers: headers });
this.http
.get(url, options)
.subscribe(this.fileContent)
this is the example they put on their api:
curl -X POST https://content.dropboxapi.com/2/files/download \
--header "Authorization: Bearer <get access token>" \
--header "Dropbox-API-Arg: {\"path\": \"/Homework/math/Prime_Numbers.txt\"}"
I might have gotten the headers wrong in angular I've never used them before.
Edit: path variable is a string equal to a file path. i.e. "readme.txt"

Did a quick google and found this: https://www.dropboxforum.com/t5/API-support/HTTP-header-quot-Dropbox-API-Arg-quot-could-not-decode-input-as/td-p/173822
Essentially the format for the variable path isn't in accordance to what the api expects.
I've added the utility function the link provides:
var charsToEncode = /[\u007f-\uffff]/g;
function http_header_safe_json(v) {
return JSON.stringify(v).replace(charsToEncode,
function(c) {
return '\\u'+('000'+c.charCodeAt(0).toString(16)).slice(-4);
}
);
}
EDIT
Your path variable should look like this:
var path = {
path: '/readme.txt'
};

Related

Trouble with Chainlink External Adapter making an API call to Spotify

I made an external adapter from the Javascript External Adapter Template from Chainlink, trying to use the Client Credentials flow for Spotify's API to return artist data, documentation listed below.
https://developer.spotify.com/documentation/general/guides/authorization-guide/#client-credentials-flow
https://developer.spotify.com/console/get-artist/
and I am able to make the call just fine with this code through Axios
but when I try to run the same call through the External Adapter which uses Axios for it's API calls as well, I get this error.
Here is a snippet of the main code of the external adapter from index.js
const customParams = {
artist: [''],
endpoint: false
}
const createRequest = (input, callback) => {
// The Validator helps you validate the Chainlink request data
const apiID = process.env.API_ID
const apiKey = process.env.API_KEY
let token = 'BQDlkzka093OuR4tL7XyaI-Tag4R166FQGBSogBP6hEBxhsCjH8XfMRqs_apKFk0T87FGIrwPtT1bkuGCeE';
const validator = new Validator(callback, input, customParams)
const jobRunID = validator.validated.id
const endpoint = validator.validated.data.endpoint
const artistID = validator.validated.data.artist.toUpperCase()
const url = `https://api.spotify.com/v1/artists/${artistID}`
const params = {
artistID
}
// curl -X "GET" "https://api.spotify.com/v1/artists/5K4W6rqBFWDnAN6FQUkS6x" -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Bearer authtoken"
// This is where you would add method and headers
// you can add method like GET or POST and add it to the config
// The default is GET requests
// method = 'get'
// headers = 'headers.....'
const head = {
'Accept' : 'application/json',
'Content-Type' : 'application/json',
'Authorization' : 'Bearer ' + token
}
const config = {
url,
headers: head
}
console.log("config:", config)
and this is the command I am running in the terminal to pass in the Spotify Artist ID
curl -X POST -H "content-type:application/json" "http://localhost:8080/" --data '{ "id": 0, "data": { "": "5K4W6rqBFWDnAN6FQUkS6x"} }'
-Edit-
Just to show that the code isn't all totally wrong, I am able to make a call through the external adapter to this url https://jsonplaceholder.typicode.com/posts/5, passing in the 5 with this command.
curl -X POST -H "content-type:application/json" "http://localhost:8080/" --data '{ "id": 0, "data": { "": "5"} }'
The issue was with this line, making the artist ID all uppercase.
const artistID = validator.validated.data.artist.toUpperCase() // Changed this
const artistID = validator.validated.data.artist // To this

POST multipart/form-data with file data from URL using javascript?

I'm trying to call an API using javascript that contains a file in the POST request. The file is located at another URL that I have to grab before calling the API. I think I need to use a fetch to get the file data as a blob and then pass it along to the post request.
I have a working example in CURL but can't work out the syntax to translate it into JS.
Working example in CURL:
curl -X POST -H 'Authorization: Token token=****' -H 'Content-Type: multipart/form-data'
-H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' -F file=#/User/somefile.pdf -F file_name=nameForFile
-F is_shared=true -F targetable_id=1 -F targetable_type=Lead -X POST "https://endpoint.com/api/documents"
Javascript:
var formData = new FormData();
fetch("http://wheremyfileis.com/file.pdf")
.then(response => response.blob())
.then(fileData => {
var fileBlob = new Blob((fileData );
formData.append("targetable_id", 1);
formData.append("targetable_type", "Lead");
formData.append("file", fileBlob);
var headers = {"Authorization": "Token token=***", "Content-Type":"multipart/form-data"};
var options = { headers: headers, body: "Hello world"};
var url = "https://endpoint.com/api/documents";
client.request.post(url, options)
.then (
function(data) { console.log(data); },
function(error) {console.log(error);}
);

Implement curl post request in JavaScript Fetch API

I'm trying to implement this post request using curl in the JS Fetch API:
curl --user apikey:{my_secret_apikey} --request POST --header "Content-Type: application/json" --data "{\"text\":[\"Hello\"],\"model_id\":\"en-es\"}" "{my_secret_url}/v3/translate?version=2018-05-01"
I'm having trouble implementing the API key.
I tried this, but it doesn't work. I get a 401 unauthorized error back from the server.
fetch(url, {
method: "POST",
headers: { 'Content-Type': 'application/json' },
user: {
"apikey": blablabla_api_key
}
body: {
"text": [term],
"model_id": "en-hi"
}
}).then(res ........
Any help is appreciated!
edit: if you have any other suggestion as to how to implement this post request into JS using some other HTTP library, that helpful too!
Edited code with auth header:
let headers = new Headers();
headers.append('Authorization', 'Basic ' + btoa("apikey" + ":" + "my_api_key"));
headers.append('Content-Type', 'application/json');
fetch(url, {
method: "POST",
headers: headers,
body: {
"text": ["Hello"],
"model_id": "en-es"
}
}).then(result => {
console.log(result);
resolve(result.translations[0].translation);
}).catch(err => console.log(err));
This results in a 400 Bad Request error, even though the curl request works fine.
hopefully, I am not too late with answering your question.
I encountered the same problem as you did and my solution was to encode the authorization into base64.
https://observablehq.com/#mbostock/fetch-with-basic-auth#:~:text=To%20use%20basic%20authentication%20with,result%20in%20a%20401%20error.
I am using Node.js, so I needed to use a Buffer for the encoding process.
If I understood your problem correctly, you'd have to do the following:
let buffer = Buffer.from(apikey:{my_secret_apikey})
let base64data = buff.toString('base64')
Your authorization header should then be set to something like this:
headers: {'Authorization': `Basic ${base64data}`}
This helped me a to solve at least the problem I was struggling with. Hope it works for you as well!

Can't upload video through Imgur API with javascript on client

I have a problem with using Imgur API. I received clientId for anon uploading of media files. Then I tried to use this credentials for API requests. I had problems with using 'https://api.imgur.com/3/upload' route for uploading from the client browser Javascript, but then I found that 'https://api.imgur.com/3/image' works as expected with images uploading (in base64 format), but not working as expected with video uploading (in binary format, because of base64 returns error), after changing method of sending video in binary format doing few requests I managed to receive 200 response code, but the only info I received (besides status info) was 'ticket' field, and nothing else (no error message or code). And I don't know how to use this info to get access to the uploaded video. This type of response not documented anywhere and I'm not really sure it should be working like it is now. Can you please help me with this case? Maybe someone had a similar situation. I have attached 'har' request info from Chrome so that you could see how I made a request, maybe I did mistake somewhere. Really waiting for your answer, thanks!
HAR request info
Send file function:
sendFile = async (fileObj) => {
const myHeaders = new Headers();
myHeaders.append('Authorization', uploadCredentials);
const formData = new FormData(),
{
type
} = fileObj,
fileTitle = fileObj.file.name.split('.').shift(),
splitDataMarker = ';base64,';
let fileData;
if (type === 'image') {
const indexOfMarker = fileObj.data.indexOf(splitDataMarker),
indexOfDataStart = indexOfMarker ? indexOfMarker + splitDataMarker.length : 0;
fileData = fileObj.data.substr(indexOfDataStart);
formData.append('type', 'base64');
} else if (type === 'video') {
formData.append('type', 'file');
const res = await fetch(fileObj.data);
fileData = await res.blob();
}
formData.append(type, fileData);
formData.append('name', fileObj.file.name);
formData.append('title', fileTitle);
const requestOptions: any = {
method: 'POST',
headers: myHeaders,
body: formData,
redirect: 'follow',
};
try {
const res = await fetch(uploadUrl, requestOptions),
data = await res.json();
return data;
} catch (error) {
throw Error(error);
}
},
Your question is answered here: https://stackoverflow.com/a/57240243
In short: for videos you need to use the /upload api endpoint and include a file with a name of video.
If you are including the file as a base64 encoded value in the POST body then you need to set the type to base64, if it is attached, then you need to set the type to file:
# If base64 body data:
curl --location --request POST 'https://api.imgur.com/3/upload' --header 'Authorization: Client-ID 3a49f81624b9a16' --data 'image=R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7&type=base64&disable_audio=0'
CLIENT_ID=3a49f81624b9a16; curl --location --request POST 'https://api.imgur.com/3/upload' --header "Authorization: Client-ID $CLIENT_ID" --data 'image=R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7&type=base64&disable_audio=0'
# If reading file (in this case, from stdin:
echo 'R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' | base64 --decode | curl --location --request POST 'https://api.imgur.com/3/upload' --header "Authorization: Client-ID $CLIENT_ID" -F 'type=file' -F 'disable_audio=0' -F 'image=#-'
In both examples above, for a video, change image= to video=

How to use Stripe's secret key and publishable key?

I would like to connect with the Stripe API using a https call using the https library.
var https = require('https');
I have gotten the secret key and publishable key and put it inside a object:
var stripe = {
secret_key: 'secret_key_given_in_the_dashboard',
publishable_key: 'publishable_key_given_in_the_dashboard'
}
I am now in the part of creating the requestDetail object:
var requestDetails = {
'protocol' : 'https:',
'hostname' : 'api.stripe.com',
'method' : 'POST', //WHICH OF POST GET PUT DELETE SHOULD I USE?
'path' : '???????????????????????',// WHICH ENDPOINT SHOULD I USE?
'auth' : '???????????????????????',// SHOULD I USE THE SECRET AND PUBLISHABLE KEY HERE?
'headers' : {
'Content-Type' : 'application/x-www-form-urlencoded',
'Content-Length' : Buffer.byteLength(stringPayload)
}
};
I plan to make use of the requestDetails object in the call using https:
var req = https.request(requestDetails, function(res){
// Grab the status of the sent request
var status = res.statusCode;
//Callback successfully if the request went through
if(status == 200 || status == 201) {
callback(false);
} else {
callback('Status code returned was ' + status);
}
});
Where and how should I use the secret key and publishable key in order to make a call to the stripe API?
Which endpoint?
Which method (POST, GET, PUT,or DELETE)?
I would like to eventually create a order and pay through the STRIPE api.
But for now just any authenticated call through the stripe api will do as I need a sample format that works....
I'm not too sure where to add the secret key and publishable key....
You should install official stripe package (source: https://github.com/stripe/stripe-node), require the package and authenticate it using your secret key ( example from the github docs):
const stripe = require('stripe')('your_stripe_secret_key');
stripe.customers.create({
email: 'customer#example.com',
})
.then(customer => console.log(customer.id))
.catch(error => console.error(error));
The package is an abstraction to make the API requests for you.
More docs: https://stripe.com/docs/api?lang=node
However, if you want to use the https directly for Stripe API requests, which is not recommended, you can check the docs and examples for using the cURL, since it shows the endpoints for each example.
https://stripe.com/docs/api/authentication?lang=curl
try using fetch, 'Authorization': 'Bearer ' + sk.
My working example of retrieving a customer based on the customer_id:
const url = `https://api.stripe.com/v1/customers/${stripe_customer_id}`;
return await fetch(url, {
method: "get",
headers: {
"Content-Type": "application/json",
'Authorization': 'Bearer ' + sk,
}
})
.then(function(response) {
return response.json();
})
.then(function(response) {
// console.log(response);
return response;
});
};

Categories

Resources