I have been working to create a filehandler to open file in sharepoint. I have implemented the Oauth to authorize the application.
Upto now i can access the file object as shown below:
{
"#odata.context":"https://graph.microsoft.com/v1.0/$metadata#shares('u%21aHR0cHM6Ly9yYXBpZHBsYXRmb3JtLnNoYXJlcG9pbnQuY29tL1NoYXJlZCUyMERvY3VtZW50cy9maWxlLnRlc3Q_dGVtcGF1dGg9ZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKdWIyNWxJbjAuZXlKaGRXUWlPaUl3TURBd01EQXdNeTB3TURBd0xUQm1aakV0WTJVd01DMHdNREF3TURBd01EQXdNREF2Y21Gd2FXUndiR0YwWm05eWJTNXphR0Z5WlhCdmFXNTBMbU52YlVBeE9XVXhNakE0WkMweU1qVm1MVFEzWVdNdE9XTXpaQzAzWXpaa00yVTVPVGxpWVdJaUxDSnBjM01pT2lJd01EQXdNREF3TXkwd01EQXdMVEJtWmpFdFkyVXdNQzB3TURBd01EQXdNREF3TURBaUxDSnVZbVlpT2lJeE5USTJNemt3TURnMElpd2laWGh3SWpvaU1UVXlOalEzTmpRNE5DSXNJbVZ1WkhCdmFXNTBkWEpzSWpvaU5IRTFlV0pCT1ZONlkyaHFaVmd3WWxKSWRFb3hjelF5YkdGYVUxRjRNRU12VVRsVlNGaG9ZVFJUVFQwaUxDSmxibVJ3YjJsdWRIVnliRXhsYm1kMGFDSTZJall6SWl3aWFYTnNiMjl3WW1GamF5STZJbFJ5ZFdVaUxDSmphV1FpT2lKYVJFa3lUVlJaTTA5WFZYUmFWRUpvV21rd01VMUVRWGRNVjFFMFRrUlJkRnB0V21wTmFsazBUVVJKZDFwVVJtMGlMQ0oyWlhJaU9pSm9ZWE5vWldSd2NtOXZablJ2YTJWdUlpd2ljMmwwWldsa0lqb2lUMWRWTTAxVVZUTk5SRUYwVFVSck1FNXBNREJaYW1NeVRGZEplVnBxUlhSUFJFazFXbFJDYlU1NlRYaFpWRmsxSWl3aWMybG5ibWx1WDNOMFlYUmxJam9pVzF3aWEyMXphVndpWFNJc0ltNWhiV1ZwWkNJNklqQWpMbVo4YldWdFltVnljMmhwY0h4aGJtbHphRUJ5WVhCcFpIQnNZWFJtYjNKdExtOXViV2xqY205emIyWjBMbU52YlNJc0ltNXBhU0k2SW0xcFkzSnZjMjltZEM1emFHRnlaWEJ2YVc1MElpd2lhWE4xYzJWeUlqb2lkSEoxWlNJc0ltTmhZMmhsYTJWNUlqb2lNR2d1Wm54dFpXMWlaWEp6YUdsd2ZERXdNRE5pWm1aa1lXRXlOV0UyT1RoQWJHbDJaUzVqYjIwaUxDSjBkQ0k2SWpBaUxDSjFjMlZRWlhKemFYTjBaVzUwUTI5dmEybGxJam9pTXlKOS5hV0U1WTFGalVYQjNUVkpMYmtWSFMzWkJXVGgxUTJGNE5IRnFTM0U1UTBscGRrNTFZMEZIY0dsd1p6MA')/driveItem/$entity",
"#microsoft.graph.downloadUrl":"https://{tenant}.sharepoint.com/_layouts/15/download.aspx?UniqueId=2d7dfb93-1fae-402a-8219-0126a74d4a37&Translate=false&tempauth=eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdWQiOiIwMDAwMDAwMy0wMDAwLTBmZjEtY2UwMC0wMDAwMDAwMDAwMDAvcmFwaWRwbGF0Zm9ybS5zaGFyZXBvaW50LmNvbUAxOWUxMjA4ZC0yMjVmLTQ3YWMtOWMzZC03YzZkM2U5OTliYWIiLCJpc3MiOiIwMDAwMDAwMy0wMDAwLTBmZjEtY2UwMC0wMDAwMDAwMDAwMDAiLCJuYmYiOiIxNTI2MzkwMDg3IiwiZXhwIjoiMTUyNjM5MzY4NyIsImVuZHBvaW50dXJsIjoiaEdpb1hmbXZjT3cveFJkMWRYNnlMV3d0dHhXSVlkeXg3UERXbmR5MFE0OD0iLCJlbmRwb2ludHVybExlbmd0aCI6IjEyNCIsImlzbG9vcGJhY2siOiJUcnVlIiwiY2lkIjoiWVdZMVlUSmhOR010WldOak15MDBaV1l4TFdJellXSXRPR1ZsWkRNM1pqZGtZekpqIiwidmVyIjoiaGFzaGVkcHJvb2Z0b2tlbiIsInNpdGVpZCI6Ik9XVTNNVFUzTURBdE1EazBOaTAwWWpjMkxXSXlaakV0T0RJNVpUQm1Oek14WVRZNSIsImFwcF9kaXNwbGF5bmFtZSI6IkJQTU4gVEVTVCIsInNpZ25pbl9zdGF0ZSI6IltcImttc2lcIl0iLCJhcHBpZCI6IjMwN2M5NmZkLTZiZTAtNDJiYi1hODNhLWE2ZDFhMGQyMTE4YiIsInRpZCI6IjE5ZTEyMDhkLTIyNWYtNDdhYy05YzNkLTdjNmQzZTk5OWJhYiIsInVwbiI6ImFuaXNoQHJhcGlkcGxhdGZvcm0ub25taWNyb3NvZnQuY29tIiwicHVpZCI6IjEwMDNCRkZEQUEyNUE2OTgiLCJzY3AiOiJhbGxwcm9maWxlcy5yZWFkIiwidHQiOiIyIiwidXNlUGVyc2lzdGVudENvb2tpZSI6bnVsbH0.aDNPQi9rWmVxSFVmemNCV3d5OUpUTTROcFd2WmxKUGdySmV4ZWxkWDU5ST0&ApiVersion=2.0",
"createdDateTime":"2018-05-09T15:02:38Z",
"eTag":"\"{2D7DFB93-1FAE-402A-8219-0126A74D4A37},2\"",
"id":"01P7SZWCUT7N6S3LQ7FJAIEGIBE2TU2SRX",
"lastModifiedDateTime":"2018-05-09T15:02:40Z",
"name":"file.test",
"webUrl":"https://{tenant}.sharepoint.com/Shared%20Documents/file.test",
"cTag":"\"c:{2D7DFB93-1FAE-402A-8219-0126A74D4A37},2\"",
"size":13453,
"createdBy":{
"user":{
"email":"anish#{tenant}.onmicrosoft.com",
"displayName":"Anish Duwal"
}
},
"lastModifiedBy":{
"user":{
"email":"anish#{tenant}.onmicrosoft.com",
"displayName":"Anish Duwal"
}
},
"parentReference":{
"driveId":"b!AFdxnkYJdkuy8YKeD3MaaVPyxX7gqyZNrG2Ojd27BJ6-8E-AHhORQ6Fx04pQ_BGq",
"driveType":"documentLibrary",
"id":"01P7SZWCV6Y2GOVW7725BZO354PWSELRRZ",
"path":"/drives/b!AFdxnkYJdkuy8YKeD3MaaVPyxX7gqyZNrG2Ojd27BJ6-8E-AHhORQ6Fx04pQ_BGq/root:"
},
"file":{
"mimeType":"application/octet-stream",
"hashes":{
"quickXorHash":"1D02as0SaS8K4jo+JF1b5S6PUjo="
}
},
"fileSystemInfo":{
"createdDateTime":"2018-05-09T15:02:38Z",
"lastModifiedDateTime":"2018-05-09T15:02:40Z"
}
}
However I get the 403 error upon requesting the content using #microsoft.graph.downloadUrl
Any help would be highly appreciated. Thanks
Update
I am using express to call the api. The below request returns the file object response as shown above.
if(requestBody.items) {
let [driveItem] = JSON.parse(requestBody.items);
try {
let content = await request.get(`${driveItem}`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
res.render('test', {content: content});
} catch(e) {
res.render('test', {content: e.message});
}
}
but upon requesting the content it throws 403
let fileobject = JSON.parse(content);
let file = await request.get(`${fileobject["#microsoft.graph.downloadUrl"]}`)
I also tried adding content to the url directly, but it didn't work too.
if(requestBody.items) {
let [driveItem] = JSON.parse(requestBody.items);
try {
let content = await request.get(`${driveItem}/content`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
res.render('test', {content: content});
} catch(e) {
res.render('test', {content: e.message});
}
}
I use these methods to get access token.
async function getAccessToken(code, callback) {
let jsonAuth = await request.post({
url: 'https://login.microsoftonline.com/common/oauth2/token',
formData: {
'grant_type' : 'authorization_code',
'code' : code,
'client_id' : config.clientId,
'client_secret' : config.clientSecret,
'redirect_uri' : 'https://simpliapp.herokuapp.com/'
}
});
callback(jsonAuth);
}
function getAuthorizationCode(res) {
res.writeHead(302, {
'Location': `https://login.microsoftonline.com/common/oauth2/authorize?response_type=code&client_id=${config.clientId}&resource=${encodeURIComponent('https://graph.microsoft.com/')}&redirect_uri=${encodeURIComponent('https://simpliapp.herokuapp.com/')}`
});
res.end();
}
Related
My api is as follows..
const { URL, URLSearchParams } = require("url");
async callSendApi(requestBody) {
let url = new URL(`${API_URL}/${PAGE_ID}/messages`);
url.search = new URLSearchParams({
access_token: `${PAGE_ACCESS_TOKEN}`,
});
console.warn("Request body is\n" + JSON.stringify(requestBody));
let response = await axios.post(url, {
headers: { "Content-Type": "application/json" },
body: JSON.stringify(requestBody),
});
if (!response.ok) {
consoleconst`Unable to call Send API: ${response.statusText}`,
await response.json();
}
}
The error I get :
message: 'Unknown path components: /messagesaccess_token="access_token"
I cannot find any wrong in this api. but still I get above error.. so I tried following...
async callSendApi(requestBody) {
let url = new URL(`${API_URL}/${PAGE_ID}/messages`);
console.warn("Request body is\n" + JSON.stringify(requestBody));
let response = await axios.post(url, {
headers: { "Content-Type": "application/json" },
body: JSON.stringify(requestBody),
access_token: `${PAGE_ACCESS_TOKEN}`,
});
if (!response.ok) {
consoleconst`Unable to call Send API: ${response.statusText}`,
await response.json();
}
}
then I get a error saying that cannot set headers after sending to the client..
please help!
I have this code below, using the npm.js api request
let inputContent = {
prompt: req.body.prompt
}
inputContent.prompt = JSON.stringify(inputContent.prompt)
request.post({
url: 'https://my.api.com/',
headers : {
"content-type": "application/json",
},
body: {
"prompt": inputContent.prompt,
"max_tokens": 4000
},
json: true
}, function(err, httpResponse, body) {
if (err) {
console.log(err)
} else {
console.log("body response is")
console.log(body)
}
})
I expect a response through body, but it keeps returning undefined. I also tried using form instead of body, and i tried removing json. Could anyone offer some advice?
So i been trying to get access to the reddit api.
I registered to reddit. verified my mail. opened an app and got my credentials.
Followed this official documentation and also came across to this tutorial
All my efforts have failed and don't get any respond.
I am using nodejs. but also tried in postman and failed.
Tried 2 options using fetch and using axios:
const axios = require('axios');
const fetch = require('node-fetch')
const { URLSearchParams } = require('url')
class RedditApi {
clientId2 = "get ur own credentials by opening an app here https://www.reddit.com/prefs/apps";
clientSecret2 = "get ur own credentials by opening an app here https://www.reddit.com/prefs/apps";
authenticationUrl = `https://www.reddit.com/api/v1/access_token`;
BASE_URL = 'https://www.reddit.com/';
tokenAuth = null;
tokenExpirationTime = null;
currencyObj = null;
constructor(currencyObj) {
this.currencyObj = currencyObj;
console.log("constructor service")
}
async getAuthToken() {
const bodyParams = new URLSearchParams({
grant_type: "https://oauth.reddit.com/grants/installed_client",
device_id: "DO_NOT_TRACK_THIS_DEVICE"
});
console.log(this.clientId2, 'this.clientId');
debugger;
const headersObj = {
'Authorization': `Basic ${Buffer.from(`${this.clientId2}:`).toString('base64')}`,
'Content-Type': 'application/x-www-form-urlencoded',
};
let response = null;
try {
response = await axios.post(this.authenticationUrl,
bodyParams,
{
headers: headersObj
});
debugger;
} catch (error) {
debugger;
console.error(error);
console.log(error.stack);
return null;
}
}
async getAuthToken2() {
try {
// Creating Body for the POST request which are URL encoded
const params = new URLSearchParams()
params.append('grant_type', 'https://www.reddit.com/api/v1/access_token')
params.append('device_id', 'DO_NOT_TRACK_THIS_DEVICE')
// Trigger POST to get the access token
const tokenData = await fetch('https://oauth.reddit.com/grants/installed_client', {
method: 'POST',
body: params,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': `Basic ${Buffer.from(`${this.clientId2}:`).toString('base64')}` // Put password as empty
}
}).then(res => {
debugger;
return res.text()
})
debugger;
if (!tokenData.error) {
debugger;
res.send(trendingResult)
}
res.status(tokenData.error).send(tokenData.message)
} catch (error) {
debugger;
console.log(error)
}
}
}
module.exports = RedditApi;
when using axios i get this respond: "Request failed with status code 401"
When using fetch i get this respond: "'403 Forbidden\nRequest forbidden by administrative rules.\n\n'"
Anybody knows what is the problem and how can i fix it?
Many thanks!
I'm using axios and an API to get a page's HTML, editing the HTML, and putting it back via a POST request to the API. I'm successful in retrieving and editing the HTML but I can't figure out how to put it back/change the webpage's HTML.
I tried using a PUT request instead of a POST request, but I get a 405 error that the PUT method is not allowed for the webpage.
axios.get(url, {
auth: {
username: USERNAME,
password: PASSWORD
},
headers: {
'Content-Type': 'application/json'
}
})
.then( (response) => {
version = response.data.version.number;
body = response.data.body.storage.value;
// takes the body HTML and formats all the links
newBody = middleware.formatLinks(body);
data = {
"type": "page",
'version': {'number': version + 1},
'body': {
'storage': {
'value': newBody,
'representation': 'storage'
}
}
}
// put the body HTML back into the page
axios.post(url, {
data: {
"type": "page",
'version': {'number': version + 1},
'body': {
'storage': {
'value': newBody,
'representation': 'storage'
}
}
}
}, {
auth: {
username: USERNAME,
password: PASSWORD
},
headers: {
'Content-Type': 'application/json'
}
})
.then( (response) => {
console.log(response.data);
})
.catch( (error) => {
console.log(error);
})
})
.catch( (error) => {
console.log(error);
})
I expect the page to now be updated with all the links formatted to my liking. However the page is unchanged. When I console.log(response.data) after making the post request, the output is a string of newBody, when I expect it to be the JSON object
data: {
'type': 'page',
'version': {'number': version + 1},
'body': {
'storage': {
'value': newBody,
'representation': 'storage'
}
}
}
As mentioned in my comment in #Aman Raj's answer, I have the code working in python but translating it to nodejs was giving me issues. So I circumvented my problem by calling my python script in nodejs with the python-shell package.
let {PythonShell} = require('python-shell');
...
const formatLinks = (id) => {
let options = {
mode: 'text',
pythonOptions: ['-u'], // get print results in real-time
scriptPath: './python/', // path to my python scripts
// pass in the page id, username, and password to API request
args: [id, USERNAME, PASSWORD]
};
PythonShell.run('script.py', options, (err, results) => {
if (err) throw err;
// results is an array consisting of messages collected during execution
console.log('results: %j', results);
});
}
Your code seems fine. It may be possible that you are accessing an API which does not support editing it.
The HyperText Transfer Protocol (HTTP) 405 Method Not Allowed response
status code indicates that the request method is known by the server
but is not supported by the target resource.
I'm learning nodejs and trying to make an API call. The API uses JWT to authenticate.
I created these functions to sign a token:
function token() {
const payload = {
iat: Math.floor(new Date() / 1000),
exp: Math.floor(new Date() / 1000) + 30,
sub: "api_key_jwt",
iss: "external",
jti: crypto.randomBytes(6).toString("hex")
};
return new Promise((resolve, reject) => {
jwt.sign(payload, privatekey, { algorithm: "RS256" }, function(
err,
token2
) {
if (err) reject(err);
else resolve(token2);
});
});
}
exports.genToken = async function() {
const header = {
"x-api-key": api
};
const data = {
kid: api,
jwt_token: await token()
};
async function authorization(req, res) {
try {
const auth = await rp({
url: authurl,
method: "POST",
headers: header,
body: data
});
res.send(auth.body);
} catch (error) {
res.send(404).send();
}
}
return {
"x-api-key": api,
Authorization: "Bearer " + authorization()
};
};
This works fine. Then I created a function to make the API call:
const token = require("./index").genToken;
const rp = require("request-promise");
exports.getOrderBook = function(res, error) {
const full_url = url + "order_book";
const auth = token();
rp({
url: full_url,
method: "GET",
headers: auth,
body: {
market: "btceur"
},
json: true
})
.then(function(response) {
res(response);
})
.catch(function(err) {
error(err);
});
};
And I call it using Express:
routes.get("/orderbook", async (req, res, next) => {
try {
const book = await orders.getOrderBook();
res.send(book);
} catch (error) {
next(error);
}
});
However, when I call my API, it shows an error in console:
TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be one of
type string or Buffer. Received type object.
I guess the error is something with the token generation, because if I console.log(auth) in the getOrderBook function, it shows Promise { <pending> }, so probably an object is being passed as the jwt token.
Is it really the problem? I tried a lot of different solutions that I found on internet, however the concept of Async/Await is new to me, and I'm having some troubles to figure it out.
Thanks a lot in advance guys!
Since getToken is an anync function, the return is wrapped in a Promise as well so you would need another anync/await:
exports.getOrderBook = async function() {
let response;
try {
const full_url = url + "order_book";
const auth = await token();
response = await rp({
url: full_url,
method: "GET",
headers: auth,
body: {
market: "btceur"
},
json: true
});
} catch (e) {
// handle error
throw e
// or console.error(e)
}
return response;
};
In this line as well Authorization: "Bearer " + authorization(), authorization is returning a promise
const bearer = await authorization()
return {
"x-api-key": api,
Authorization: "Bearer " + bearer
};
For error handling wrap entire thing in try..catch block
exports.genToken = async function() {
try {
const header = {
"x-api-key": api
};
const data = {
kid: api,
jwt_token: await token()
};
async function authorization(req, res) {
let auth;
try {
auth = await rp({
url: authurl,
method: "POST",
headers: header,
body: data
});
// res object not available
// res.send(auth.body);
} catch (error) {
// res object not available, better throw error and handle in your middleware
// res.send(404).send();
}
return auth
}
const bearer = await authorization()
} catch (e) {
// handle error
}
return {
"x-api-key": api,
Authorization: "Bearer " + bearer
};
}