Batch Delete Request with Google REST api getting Bad Request error - javascript

I am trying to delete multiple files at once from my google drive using the REST API. I found this SO Question-bulk deletion Google Drive API, I have tried this solution without the npm package using fetch.
This is what I have at the moment.
const boundary = 'END_OF_PART';
const separation = `\n--'${boundary}'\n`;
const ending = `\n--'${boundary}'--`;
const requestBody = files.reduce((accum, current) => {
accum += separation +
'Content-Type: application/http\n\n' +
`DELETE https://www.googleapis.com/drive/v2/files/${current.id}
\nAuthorization: Bearer ${this.getToken()}`
return accum
}, '') + ending
const _multiPart = [];
files.forEach((file) => {
const obj = {
"Content-Type": "application/http",
body: `DELETE https://www.googleapis.com/drive/v2/files/${file.id}\n`,
};
_multiPart.push(obj);
});
const url = new URL('https://www.googleapis.com/batch/drive/v3');
const requestOptions = {
method: 'POST',
headers: {
"Content-Type": "multipart/mixed",
'Authorization' : `Bearer ${this.getToken()}`
},
body: requestBody,
multipart: _multiPart,
};
await fetch(url, requestOptions);
When I run the deletion I get the id's of the files but the end result is Error 400 bad request. Documentation is scarce for this process. What is it that I am doing wrong here and how can I fix it to get this to work?
End result that I am looking for is deleting a large amount of files from my google drive.
Can anyone point me in the right direction on this ?.
EDIT: I just tried a solution at this SO Question: Bulk delete files on Google Drive with raw XMLHttpRequest
And it did delete 100 files, but the response I got back was Code 500, Internal error.
Why am I getting this response and again why is my previous code not working at all ?

I believe your goal is as follows.
In your script, files is an array including the file IDs like ["fileId1", "fileId2",,,].
In your goal, you want to delete files with the batch requests using the array files by the fetch API of Javascript.
Your access token can be used for deleting files and you have permission for deleting those files.
In this case, how about the following sample script? In order to use the batch requests with Javascript, I have created a library. Ref In this answer, I would like to use this library.
Sample script:
<script src="https://cdn.jsdelivr.net/gh/tanaikech/BatchRequest_js#master/batchrequest_js.min.js"></script>
<script>
const accessToken = "###"; // Please set your access token.
const files = ["fileId1", "fileId2",,,]; // Please set your file IDs.
const object = {
accessToken,
batchPath: "batch/drive/v3",
requests: files.map(id => ({ method: "DELETE", endpoint: "https://www.googleapis.com/drive/v3/files/" + id })),
};
Do(object)
.then((e) => console.log(e))
.catch((err) => console.log(err));
</script>
References:
Batch requests of official document
BatchRequest_js (Author: me)

Related

API says : 'Endpoint/ does not exist' Though Im using the same URL provided by the API creator

So Im working on a project for university assignment
Im trying to hook up a ChatBot API from RapidAPI.com.
Starting from the top - I copy pasted the code given by the developer, and no matter what it returns
/Endpoint/does not exist/
I have made some modifications, but if anyone can see why it may return that, I would highly appreciate it. Here is my code
function onButtonClick(){
//uses userInput, creates value.
const userInput = document.getElementById("userInput").value
const value = 0;
//basic url for API string to get parsed in to the API call
const apiString = "https://chatbot-chatari.p.rapidapi.com/?message=%2F";
console.log(apiString + "API STRING NO MESSAGE")
//basic url with message added on, known as value.
const apiStringWithMessage = apiString + value;
console.log(apiStringWithMessage + "API STRING WITH MESSAGE")
//obselete
//JSON.stringify(apiStringWithMessage);
//setting up options, contains API GET / POST method etc.
//Sets up API key and Host URL
const options = {
method: 'POST',
headers: {
'X-RapidAPI-Key': 'myapikey',
'X-RapidAPI-Host': 'chatbot-chatari.p.rapidapi.com'
}
};
//fetch uses URL with message hardcoded (right now), combined with options.
//try catches to find errors, or show result.
fetch('https://chatbot-chatari.p.rapidapi.com/?message=%2FHi!', options)
.then(response => response.json())
.then(response => console.log(response))
.catch(err => console.error(err));
}

Downloading Sqlite backup file from google drive ends up with a corrupt file nodejs + Vue

I am working on a backup system with Google Drive v3 REST API. I upload a sqlite backup file to a folder on Google Drive. That works. I am able to upload and list the files in the folder.
So now I am working on restoring that file in my application. But when I download the file and write the response stream I end up with a corrupted db file. When I open it up in notepad ++ I see that any special characters such as ^ etc are all squares and the file is like 2 mb bigger than what was uploaded.
I have been at this for two days now and cannot figure out why the file is not writing 1:1 copy of what is downloaded
this is my current code for the download ..
async restoreGoogleDriveDatabase(fileId){
const url = encodeURI(`https://www.googleapis.com/drive/v3/files/${fileId}?alt=media`);
const options = {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + this.getToken()
},
}
await fetch(url, options).then(async response => response.text())
.then(arrayBuffer => {
const path = require('path').join(window.process.env.ProgramData, 'Home Inventory');
fs.writeFile(`${path}\\HomeInventory1.db`, arrayBuffer, function () {
console.warn('file created');
});
});
},
Looking for any kind of help that would get me back on the right track.
The issue seems to be with character encoding
The simplest fix is to fetch the result as an arrayBuffer, and write out the arrayBuffer using "binary" encoding
Like so
const fs = require('node:fs/promises');
async restoreGoogleDriveDatabase(fileId) {
const url = encodeURI(`https://www.googleapis.com/drive/v3/files/${fileId}?alt=media`);
const options = {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + this.getToken()
},
}
try {
const response = await fetch(url, options);
const arrayBuffer = await response.arrayBuffer();
const path = require('path').join(window.process.env.ProgramData, 'Home Inventory');
await fs.writeFile(`${path}/HomeInventory1.db`, Buffer.from(arrayBuffer, "binary"));
console.warn('file created');
} catch (err) {
console.error(err);
}
},
The code above uses async/await correctly, and also uses fs/promises instead of fs, since already using async/await it makes sense to use the Promise version of fs methods
The important changes are
response.arrayBuffer()
To get the response as an arrayBuffer
and in fs.writeFile use
Buffer.from(arrayBuffer, "binary")
To write the data "as-is" to the file

how do you add data to .json file

How would you add data to a .json file that is already on a website? I kinda of get how you add data to a .json locally but if I need to send it to a file that has already been created and hosted.
This is my code so far in my server.js file
router.post('/themes', async (ctx) => {
const results = await fetch(`https://`+ ctx.cookies.get("shopOrigin") + `/admin/themes.json`, {
headers: {
"X-Shopify-Access-Token": ctx.cookies.get('accessToken'),
},
})
.then(response => response.json());
ctx.body = {
status: 'success',
data: results
};
});
and this is the code in my frontend .js file
async function getUser() {
const query = [
{
"theme": {
"name": "Lemongrass",
"src": "https://codeload.github.com/Shopify/skeleton-theme/zip/master"
}
}
]
var url = "/themes";
var method = 'post';
fetch(url, { method: method, body: query})
.then(response => response.json())
.then(json => console.log(json))
};
I can pull the data aka the themes on my console, however, I need to send the data so I can create a new theme.
you're not very clear but if I understand you properly you're saying
step 1 - you called an endpoint and got a response as JSON
step 2 - you modified it and you want to send that data to a different endpoint.
assuming I'm correct above, this is the answer
let assume after step 1 the data returned is this
let response = [1,2,3,4]
and to modified it to
let newData = [{value: 1},{value: 2},{value: 3},{value: 2}]
then in step - 2 send newData instead of response.
what to take away?
if you make any modifications to a data from an endpoint then it's safer to save your modifications to a new variable in this case newData

Get Steam Community Market price history with node.js

I'm having trouble getting the price history of an item from Steam. By looking at other questions I've managed to learn a nifty way to construct a link which indeed gives me the price history of an item, my problem is that you have to be logged in to Steam to aquire this data. How do I view this data as if I'm logged in through an http-request? I've read other threads where they talked about browser sessions and how someone in my situation should set cookies of ones session-id but I haven't managed to get it to work in node. The status code I'm getting is 400.
This is my code:
const https = require('https');
const options = {
host: 'steamcommunity.com',
path: '/market/pricehistory/?country=SE&currency=3&appid=730&market_hash_name=CS20%20Case',
method: 'GET',
headers: {
'Cookie': `steamLoginSecure=THE SESSION ID I GOT FROM WRITING
"document.cookie" IN THE DEV CONSOLE`
}
}
const req = https.request(options, res => {
console.log(res.statusCode);
console.log(res.headers);
let body = '';
res.on('data', data => {
body += data;
});
res.on('end', () => console.log(body));
}).on('error', error => console.log(error));
req.end();
I'm not sure if there's anything wrong in my code or how to go about to solve this issue I'm having. I really appreciate any help I can get.
It seems like Steam has removed the 'steamLogin' cookie, thus explaining why so many people this past year have been encountering issues when using it in their code. Instead, you want to use the 'steamLoginSecure' cookie.
First you need be logged in to https://steamcommunity.com. Second you want to find the 'steamLoginSecure' cookie and copy what it contains. For chrome that would be:
Settings > Advanced > Privacy and security > Site Settings > Cookies and site data > See all cookies and site data > steamcommunity.com > steamLoginSecure
Now copy the content of 'steamLoginSecure' and have it as a cookie in your headers.
This is the final code I ended up with:
const https = require('https');
const options = {
host: 'steamcommunity.com',
path: '/market/pricehistory/?country=SE&currency=3&appid=730&market_hash_name=CS20%20Case',
method: 'GET',
headers: {
'Cookie': 'steamLoginSecure=THE CONTENT OF "steamLoginSecure" HERE'
}
}
const req = https.request(options, res => {
console.log(res.statusCode);
console.log(res.headers);
let body = '';
res.on('data', data => {
body += data;
});
res.on('end', () => console.log(body));
}).on('error', error => console.log(error));
req.end();

put request works for one api but not for another api

I tested with two apis for axios put.
for one api its working fine where as with another api it throws an error.
for one api its showing request as options eventhough I gave as put and I am seeing 403 forbidden error
for this api i am facing the issue 'http:///sports/sportsId',
I debugged but still I am not able to find the issue.
is it a back-end issue
can you tell me how to fix it, providing my code snippet below
savesports = () => {
console.log("savesports---->");
console.log(this.state.sports);
let savesports = this.state.sports;
savesports.updatedBy = 'xxx';
savesports.priceRuleDescription = "test description";
let data = {
name: "yyyy",
email: "sda#gmail.com",
phone: "2321313"
};
axios
.put("https://jsonplaceholder.typicode.com/users/1", data)
.then(r => console.log("dada", r));
console.log(JSON.stringify(savesports));
axios
.put(
'http:///sports/sportsId',
savesports
// { headers: { 'Content-Type': 'application/json' } }
)
.then(r => console.log(r))
.catch(e => console.log(e));
//this.toggleDrawer("right", false);
this.setState({ right: false });
this.setState({ snackBarOpen: true });
setTimeout(() => {
this.setState({ snackBarOpen: false });
}, 6000)
};
1. Check if URL is right
I would first check if the URL is right.
Try changing http:///sports/sportsId to http://sports/sportsId if that's actually the URL you are requesting to.
2. Avoid name confusion
Both the method name and the put data variable name are the same (savesports). I would change the put data variable name to something meaningful like
let sportsData = this.state.sports;
sportsData.updatedBy = 'xxx';
sportsData.priceRuleDescription = 'test description';
3. Check authentication
403 might also be to auth error. I would check if the endpoint requires any authentication token or headers.

Categories

Resources