javascript send local file to api - javascript

I'm developing an electron app which must call an api to replace (update) file X in server by file Y which is in my computer.
The user download file X from Server in order to edit it, (this file will be named file Y in my computer).
When the user finish to edit file Y, i check if both files X and Y are differents and i call the api in order to replace file X by file Y. I don't need to put file Y in a form before calling api, i want to do it without form.
Only my request payload is different from what i expect to have, there is no problem in my request headers
I expect to have something like that
and i get this
Here is what i do
const fs = require('fs');
let fileY = fs.readFileSync(path.resolve('gitignore.txt'));
let form = new FormData();
form.append("type", "jur_document");
form.append("file", fileY, 'gitignore.txt');
form.append("saveActionType", "SAVEMAJOR");
form.append("attributes", "MIMETYPE=text/plain");
let settings = {
"async": true,
"url": `${Constante.URL}/documents`,
"method": "POST",
"type": "POST",
"headers": {
// "Content-Type": "text/plain",
"Authorization": sessionStorage.getItem('authorization')
},
"processData": false,
"contentType": false,
"mimeType": "multipart/form-data",
"data": form
};
$.ajax(settings)
.done((response) => {
console.log(response);
}).fail(err => {
console.log(err);
});
}

i finally get the solution
I read my file and create a blob which i use to recreate my file
const fs = require('fs');
let buffer = fs.readFileSync(`${app.getAppPath()}/test.txt`);
let fileY = new File([new Uint8Array(buffer)], 'test.txt', {
type: 'text/plain'
});
form.append("file", fileY);
and here is ajax settings
let settings = {
"url": `${Constante.URL}/documents`,
"type": "POST",
"headers": {
"Authorization": sessionStorage.getItem('authorization')
},
"processData": false,
"contentType": false,
"data": form
};

Related

Possible to create an account system with restdb.io? AJAX jQquery method

I'm fairly new to APIs in general, I managed to post data into restdb but how can i go about creating a system to log in based on the user/account data that i posted previously? what i'm thinking is using get and checking if any email and password matches but that does not sound efficient to code or im not sure if its possible to. could someone point me in the right direction
This is how my post function looks
$(document).ready(function () {
const APIKEY = ".";
$("#account-submit").on("click", function (e) {
//prevent default action of the button
e.preventDefault();
let name = $("#name").val();
let contactEmail = $("#contact-email").val();
let studentID = $("#student-id").val();
let password = $("#password").val();
var jsondata = {
"name": name,
"email": contactEmail,
"studentid": studentID,
"password": password,
};
var settings = {
"async": true,
"crossDomain": true,
"url": "https://nerdge-d48f.restdb.io/rest/account",
"method": "POST",
"headers": {
"content-type": "application/json",
"x-apikey": ".",
"cache-control": "no-cache"
},
"processData": false,
"data": JSON.stringify(jsondata)
}
$.ajax(settings).done(function(response) {
console.log(response);
$("#account-submit").prop("disabled", false);
});
})
}
)

Getting a callback after a request has been completed in a Gmail Add On in Apps Script

First of all what I am trying to do is accomplish the following.
Note: this is not my add-on.
How is this script generated? I cannot find any information about script.google.com/macros.
After this tab is closed, the add-on gets a callback that looks like this:
As I don't understand the flow my questions are:
How does the add-on script know that the tab is being closed?
How is the script created?
At which endpoint does the script call the google add-on?
The following is my add-on script:
function insertDocumentToRMS(e){
var url = "https://test.signumid.hr/v/1/rms";
var object = {
"data" : e.parameters.file.toString()
}
var payload = JSON.stringify(object);
var headers = {
"Accept": "application/json",
"Content-Type": "application/json",
"Authorization": "Basic dXNlcm5hbWU6cGFzc3dvcmQ="
};
var options = {
"method": "POST",
"contentType": "application/json",
"headers": headers,
"payload": payload,
"muteHttpExceptions": true
};
var response = UrlFetchApp.fetch(url, options);
var data = JSON.parse(response.getContentText());
Logger.log(data);
var url2 = "https://test.signumid.hr/v/1/signer/document/storage/"+ data.recordNumber;
Logger.log(url2);
var object2 = {
"SignatureProvider": "SwisscomAis",
"SignatureProviderData": {
"SwisscomRequestData": {
"mobileNumber": "+41796063855",
"language": "en",
"message": "Matej PotpiĆĄiii!",
"jurisdiction": "ZERTES",
"signatureLevel": "AES"
}
},
"Documents": [
{
"SignatureOptions": {
"Reason": "Reason",
"Location": "Location",
"SignerContactInfo": "SignerContactInfo",
"SignerName": "SignerName"
},
"Document": e.parameters.file.toString()
}
]
}
var payload2 = JSON.stringify(object2);
var headers2 = {
"Accept": "application/json",
"Content-Type": "application/json",
"Authorization": "Basic dXNlcm5hbWU6cGFzc3dvcmQ="
};
var options2 = {
"method": "GET",
"contentType": "application/json",
"headers": headers2,
"payload": payload2,
"muteHttpExceptions": true
};
var response2 = UrlFetchApp.fetch(url2, options2);
Logger.log(response2);
let actionSign = CardService.newAction().setFunctionName('test');
var actionResponse = CardService.newActionResponseBuilder()
.setOpenLink(CardService.newOpenLink()
.setUrl("https://test.signumid.hr/v/1/signer/document/storage/"+ data.recordNumber)
.setOpenAs(CardService.OpenAs.OVERLAY)
.setOnClose(CardService.OnClose.RELOAD))
.build();
return actionResponse;
}
As you can see at the end (here), I am trying to use an actionBuilder with an actionResponse that has the property OnClose, but the only parameters on OnClose are: NOTHING and RELOAD. Can I pass an action somehow or what am I supposed to do to replicate the scenario that I mentioned above?
var actionResponse = CardService.newActionResponseBuilder()
.setOpenLink(CardService.newOpenLink()
.setUrl("https://test.signumid.hr/v/1/signer/document/storage/"+ data.recordNumber)
.setOpenAs(CardService.OpenAs.OVERLAY)
.setOnClose(CardService.OnClose.RELOAD))
.build();
Basically what the add-on is doing is a 'sign in workflow' to authorize scopes. If you want to replicate that workflow you can take a look at this sample provided by Google.
Aside from that you can submit a feature request to control browser events.
Looking for any alternative options I found this and this.
As for macros using Google Apps Script, you can look here.

how to send photo from telegram bot api (javascript)

I have a problem with sending the api via telegram text messages that arrive but the pictures are not arriving and I don't understand where the problem is
Is it possible to modify this code and make it send images?
var telegram_bot_id = "api";
var chat_id = "id";
var img;
var ready = function () {
img = document.getElementById("photo").value;
message = "photo: " + img ;
};
var sender = function () {
ready();
var settings = {
"async": true,
"crossDomain": true,
"url": "https://api.telegram.org/bot" + telegram_bot_id + "/sendPhoto",
"method": "POST",
"headers": {
"Content-Type": "application/json",
"cache-control": "no-cache"
},
"data": JSON.stringify({
"chat_id": chat_id,
"text": message
})
};
$.ajax(settings).done(function (response) {
console.log(response);
window.location.href = "index.html";
});
document.getElementById("photo").value = "";
return false;
};
In order to be able to send a photo via sendPhoto method, you have to send a proper picture file or a string represent a valid URL.
According to code you posted, you're sending into the HTTP request as body parameters the chat_id, the text message itself and that's it.
The sendPhoto method does not expect a text field, that's used in sendMessage method.
In your case, since you're trying to send via Telegram chatbot a picture taken from the HTML entity, which in this case is not the picture itself but its path on your webserver, you have to change the POST request body and to set the picture URL as parameter of the request itself.
To conclude, if you want to add the text message, the sendPhoto method allows you to add it but as caption.
For instance:
var telegram_bot_id = "api";
var chat_id = "id";
var img;
var ready = function () {
img = "http://your-website.com/imagepath/imagename.png";
};
var sender = function () {
ready();
var settings = {
"async": true,
"crossDomain": true,
"url": "https://api.telegram.org/bot" + telegram_bot_id + "/sendPhoto",
"method": "POST",
"headers": {
"Content-Type": "application/json",
"cache-control": "no-cache"
},
"data": JSON.stringify({
"chat_id": chat_id,
"photo": img,
"caption": message
})
};
$.ajax(settings).done(function (response) {
console.log(response);
window.location.href = "index.html";
});
return false;
};

Upload Image by ajax gives unsupported media type error

I am trying to upload an image to my server using jquery. I need to send image, filename and file url to backend. There for I have added these three fields in "data" (refer code). I am doing it like this(below code) but I am getting error in console saying "unsupported media file" 415. How should I solve it?
posterFile = e.target.files;
selectedPoster = posterFile[0];
uploadPoster() {
var blobPosterFile = selectedPoster;
console.log("U called me?")
var formData = new FormData();
formData.append("fileToUpload", blobPosterFile);
var that = this;
let token;
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.backend.example.name.com/api/v1/videos/",
"method": "POST",
processData: false,
contentType: false,
"credentials": 'include',
"headers": {
Authorization: "Token " + that.props.token_Reducer.token
},
"data": {
"Title": selectedFile.name,
"File": videoURL,
"Poster": formData
},
success:( response, textStatus, jQxhr )=> {
console.log("poster uploaded")
}
}
$.ajax(settings).done((response) => {
});
}
I am getting error saying "unsupported media type" 415

Posting multiple Photos to one post

I have been trying to create an application which needs multiple photos to be attached to one post. These are the following attempts i tried,
First i used facebook-node-sdk which JS SDK to achieve different functionality, but Official Js Sdk does't have option for file to upload, when then i moved to attaching/inserting photo itself to HTTP POST with the help of form-data, with the following code-
var form = new FormData();
form.append('file', fs.createReadStream(picPaths[0]));
form.append('message', "Hello"); //Put message
var ACCESS_TOKEN = "ACCESS_TOKEN";
var options = {
method: 'post',
host: 'graph.facebook.com',
path: '{Object-ID}/photos' + '?access_token=' + ACCESS_TOKEN,
headers: form.getHeaders(),
}
var request = https.request(options, function(res) {
console.log(res, false, null);
});
form.pipe(request);
request.on('error', function(error) {
console.log(error);
});
This works with one photo.
But as you can see in this github.com/Thuzi/facebook-node-sdk/issues/113 which i started, it is not possible to attach more than one photo.
So as mentioned by dantman i stated looking in batch process, which can be found developers.facebook.com/docs/graph-api/making-multiple-requests titled under Uploading binary data. The one thing that hits and give me hope is this one statement.
The attached_files property can take a comma separated list of attachment names in its value.
Note That (batching with photos) also is not possible with this library or JS SDK (Please correct me if i am wrong)
You can do post images with curl like this,
curl -F 'access_token=ACCESS_TOKEN' -F 'batch=[{"method":"POST","relative_url":"{Object-Id}/photos","body":"message=Test Post","attached_files":"file1"}]' -F 'file1=#image1' -F 'file2=#image2' https://graph.facebook.com
The above code posts with one image
So my question is this, it possible to attach multiple images/binary_files to the post with the help of curl, something like ..."attached_files":"file1,file2"... as suggested by docs, please help me with this problem and if you have already done this can you please post the snapshot of your code.
Thanks, Ravi
I finally figured out how.
So first, read the section here titled "Publishing a multi-photo post with uploaded photos": https://developers.facebook.com/docs/graph-api/reference/page/photos/#Creating
What it says is basically correct, however, it is not in JavaScript. Also, they don't emphasize enough an important step: You have to set "published" to "false" for the image you upload, for it to then be attachable to the post that gets created.
So anyway, here is the working code -- in JavaScript, and with "published" correctly set to false:
async function PostImageToFacebook(token, filename, mimeType, imageDataBlob, message) {
var fd = new FormData();
fd.append("access_token", token);
fd.append("source", imageDataBlob);
//fd.append("message", "photo message for " + filename);
fd.append("no_story", "true");
//fd.append("privacy", "SELF");
fd.append("published", "false");
// Upload image to facebook without story(post to feed)
let uploadPhotoResponse = await $.ajax({
url: "https://graph.facebook.com/me/photos?access_token=" + token,
type: "POST",
data: fd,
processData: false,
contentType: false,
cache: false
});
console.log(`Uploaded photo "${filename}": `, uploadPhotoResponse);
let uploadPhotoResponse2 = await $.ajax({
url: "https://graph.facebook.com/me/photos?access_token=" + token,
type: "POST",
data: fd,
processData: false,
contentType: false,
cache: false
});
console.log(`Uploaded photo "${filename}": `, uploadPhotoResponse2);
let makePostResponse = await $.ajax({
"async": true,
"crossDomain": true,
"url": "https://graph.facebook.com/v2.11/me/feed",
"method": "POST",
"headers": {
"cache-control": "no-cache",
"content-type": "application/x-www-form-urlencoded"
},
"data": {
"message": "Testing multi-photo post2!",
"attached_media[0]": `{"media_fbid":${uploadPhotoResponse.id}}`,
"attached_media[1]": `{"media_fbid":${uploadPhotoResponse2.id}}`,
"access_token": token
}
});
console.log(`Made post: `, makePostResponse);
}
The code above currently just uploads the same image twice, then attaches both to the new post. Obviously, in real world usage you would replace the data in the second photo-upload with a different image.
Anyway, to use the function, just call it like so:
function dataURItoBlob(dataURI) {
var byteString = atob(dataURI.split(",")[1]);
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ab], {type: "image/png"});
}
let imageDataURI = GetImageDataURIFromSomewhere();
let imageBlob = dataURItoBlob(imageDataURI);
PostImageToFacebook(fbToken, "some_filename", "image/png", imageBlob, window.location.href);
this is possible.
Note: This one is not an efficient way to do this but just for explaining purpose i am doing here,
The first hint that i got that it may be possible is from this post
Steps that i used:
Follow the doc to create custom open graph stories
Let's suppose you four image to attach (pic[1, 2, 3, 4])
First i staged them with the help of new facebook-node-sdk v1.1.0-alpha1 with the code something like this (with batch process).
FB.api( "", "post", {
batch: [
{
method: "POST",
relative_url: "me/staging_resources",
attached_files: "file1",
type:"image/png"
}, {
method: "POST",
relative_url: "me/staging_resources",
attached_files: "file2",
type:"image/png"
}, {
method: "POST",
relative_url: "me/staging_resources",
attached_files: "file3",
type:"image/png"
}, {
method: "POST",
relative_url: "me/staging_resources",
attached_files: "file4",
type:"image/png"
}],
file1: fs.createReadStream(picPaths[0]),
file2: fs.createReadStream(picPaths[1]),
file3: fs.createReadStream(picPaths[2]),
file4: fs.createReadStream(picPaths[3])
},
function(response) {
console.log(response);
});
Now from the response part get the url and dis the post with the same library. With the code something like this.
FB.api(
"me/objects/{app-namespace}:{custom-object}",
"post", {
"object": {
"og:title": "Sample Post",
"og:image[0]": {
"url": "fbstaging:{...}",
"user_generated": true
},
"og:image[1]": {
"url": "fbstaging:{...}",
"user_generated": true
},
"og:image[2]": {
"url": "fbstaging:{...}",
"user_generated": true
},
"og:image[3]": {
"url": "fbstaging:{...}",
"user_generated": true
}
}
},
function(response) {
console.log(response);
}
);
Now, with these two piece of code you will be able to push multiple images/photo to the single post.
Note: this can make more sense or can be done with the help of named batch process which is being described here.
Thanks,
Ravi

Categories

Resources