I am trying to send a pdf as a response in the lua application. I am new to lua. So I am not able to understand the concept.
return {
headers = {
["content-type"] = 'attachment; name="arc_demo.pdf"',
["Content-Type"] = "application/pdf",
["content-disposition"] = 'attachment;filename="arc_demo.pdf"',
["content-description"] = 'test binary file',
["content-transfer-encoding"] = "BASE64",
},
}
Can anyone has an idea?
Related
I want to upload a file to Firebase hosting file upload via REST with Apps Script. Been trying to find a solution for days to no avail :( would highly appreciate any recommendations.
I'm following the official documentation here:
https://firebase.google.com/docs/reference/hosting/rest/v1beta1/sites.versions/populateFiles
And I can successfully get the upload URL using this code:
function getUploadURL() {
const YOUR_PROJECT_ID = 'sites/url-shortener-e42ec/versions/dd393a80797d713d';
let postUrl = 'https://firebasehosting.googleapis.com/v1beta1/YOUR_PROJECT_ID:populateFiles';
postUrl = postUrl.replace('YOUR_PROJECT_ID', YOUR_PROJECT_ID);
const options = {
method: 'post',
headers: {
Authorization: `Bearer ${ScriptApp.getOAuthToken()}`,
},
muteHttpExceptions: true
};
const response = UrlFetchApp.fetch(postUrl, options);
Logger.log(response);
}
which returns the following:
{
"uploadUrl": "https://upload-firebasehosting.googleapis.com/upload/sites/url-shortener-e42ec/versions/dd393a80797d713d/files"
}
And this is where I get kinda lost because I'm not quite sure on what to do next. The documentation says:
map (key: string, value: string)
A set of file paths to the hashes corresponding to assets that should be added to the version.
A file path to an empty hash will remove the path from the version.
Calculate a hash by Gzipping the file then taking the SHA256 hash of the newly compressed file.
But if I add a payload with a file hash to the call like so:
{
"files": {
"/teste": "3f0749957a1c4d91ed18b8e9df122709974e4e9c94c57f9245794c21dd76d4bd"
}
}
...then I get the error:
{
"error": {
"code": 400,
"message": "Precondition check failed.",
"status": "FAILED_PRECONDITION"
}
}
PART 2 :
The next issue I found is, now that I have the upload URL, I will need to actually upload the file, and according to their documentation I should:
Perform a multipart POST of the Gzipped file contents to the URL using a forward slash and the hash of the file appended to the end.
which I tried with the following apps script code:
function convert(hash) {
return hash.map(byte => ('0' + (byte & 0xFF).toString(16)).slice(-2)).join('');
}
function postFile() {
var files = DriveApp.getFilesByName('abc.txt');
let gzip;
let hash;
if (files.hasNext()) {
var file = files.next();
gzip = Utilities.gzip(file.getBlob());
hash = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, gzip.getBytes());
}
let postUrl = 'https://upload-firebasehosting.googleapis.com/upload/sites/url-shortener-e42ec/versions/dd393a80797d713d/files/' + convert(hash);
/*
var textBlob = Utilities.newBlob("abc");
const gzip = Utilities.gzip(textBlob);
const hash = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, gzipFile.getBytes());
*/
const data = {
"files": {
"/test.txt": convert(hash)
}
};
const options = {
method: 'post',
headers: {
Authorization: `Bearer ${ScriptApp.getOAuthToken()}`,
accept: 'application/json',
contentType: 'application/json'
},
muteHttpExceptions: true,
payload: JSON.stringify(data)
};
const response = UrlFetchApp.fetch(postUrl, options);
Logger.log(response);
}
... and get the following error:
Couldn't process request (status=412): File url-shortener-e42ec/dd393a80797d713d/0b3b82379e00a1994a46452e8cfd8b2c43ee8599f169a9ee4176253f1a8de469 can't be uploaded.
Appreciate all the help I can get. Thanks in advance!
I am using a service account in google apps script so i can not use the normal google apps script api.
So i use the drive rest api for creating, moving, copy etc. but i am able to upload a file with the rest api. It uploads a file but it is without content or with wrong content.
This is my code:
var contentType = data.substring(5, data.indexOf(';')),
bytes = Utilities.base64Decode(data.substr(data.indexOf('base64,') + 7)),
blob = Utilities.newBlob(bytes, contentType, file);
var service = getService();
if (service.hasAccess()) {
var url = 'https://www.googleapis.com/upload/drive/v3/files?uploadType=media';
var data = {
name: name,
mimeType: "application/pdf",
parents: [parent]
};
var options = {
method: 'post',
contentType: 'application/json',
body: blob ,
payload: JSON.stringify(data),
muteHttpExceptions: true,
headers: {
Authorization: 'Bearer ' + service.getAccessToken()
}
};
var response = UrlFetchApp.fetch(url, options);
var result = JSON.stringify(response.getContentText());
Logger.log(JSON.stringify(result, null, 2));
return result["id"];
} else {
Logger.log(service.getLastError());
}
Thanks
When uploading files using Drive API, you need to use the files.create method. You can see the javascript code reference in Basic uploads where it is used. Also note that the App Script uploading files uses the Drive v2 version of files.insert instead of files.create.
I used that method to send some files through mail, but I'm having issues to send PDF files, they are not enconding back.
function sendEmail() {
var files = [
"1X0YYxxtnKJtkn9BhoBcSb265acOYOnWJytQeBKEvfqU",
"12r6Owm616Ioqj9EfOgkNqPgXNi88f_chdPRyBcSC2EM"
];
var attachments = [];
for (var f in files) {
var file = DriveApp.getFileById(files[f]);
attachments.push({
"type": file.getMimeType(),
"name": file.getName(),
"content": Utilities.base64Encode(file.getBlob().getAs('application/pdf').getBytes())
});
}
MailApp.sendEmail('mail#gmail.com', 'Attachment example', 'Two files are attached.', {
name: 'Automatic Emailer Script',
attachments: attachments
});
}
I like to use dropzone.js for file upload to a REST-like server. While dropzone.js can switch the request method to PUT, it still sends something like a mulitpart file upload. My server expects raw data as body for the a single ressource PUT method, so the files uploaded will have multipart seperators included.
How can I tell dropzone.js to put the raw data into the request body, no more no less?
Please refer this answer that I wrote: https://stackoverflow.com/a/38734015/3746828
Add below options, then working.
myDropzone.options.sending = function(file, xhr) {
var _send = xhr.send;
xhr.send = function() {
_send.call(xhr, file);
}
}
Below is another method that patches xhr with a params function passed in as an option to Dropzone. This method will also work for chunked files. The chunked execution path below also adds the headers required for a resumable file upload using the OneDrive API as documented here: https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_createuploadsession?view=odsp-graph-online
const CHUNK_SIZE=10485760 //10MiB
Dropzone.options.dropzone = {
method: "put",
headers: {
'Cache-Control': null,
'X-Requested-With': null
},
filesizeBase: 1024,
maxFilesize: 102400, // 100G in MB, max onedrive filesize
chunking: true,
chunkSize: CHUNK_SIZE,
params: function(files, xhr, chunk) {
if (chunk) {
const chunk_start = (chunk.index * CHUNK_SIZE)
xhr.setRequestHeader('Content-Range',
'bytes ' + chunk_start
+ '-' + (chunk_start + chunk.dataBlock.data.size - 1)
+ '/' + files[0].size)
var _send = xhr.send
xhr.send = function() {
_send.call(xhr, chunk.dataBlock.data)
}
} else {
var _send = xhr.send
xhr.send = function() {
_send.call(xhr, files[0])
}
}
}
}
For this HTML5 phone App I have to use the OneDrive REST API.
I managed to upload the file, but the file up on the server is not in .jpg format and won't display in a jpg viewer. After logging in through the REST API and getting a token back, I used XMLHttpRequest to PUT the file. I've tried passing it up as an ArrayBuffer and as a base64 encoded string. In each case the file makes it there, but is not decoded properly. I figured I needed to tell the webserver how to decode the file with "request.setRequestHeader('Content-Type', 'image/jpg')" ,but I get back the following error message from the OneDrive server:
"error": {
"code": "request_body_invalid_media_type",
"message": "The Content-Type header 'text/plain' isn't supported."
}
this.uploadFile = function (token, fileUri,fileName, fileTools, success, fail) {
var me = app.log('||Microsoft.uploadFile||');
fileTools.readFileContent(fileUri, 'dataUrl', gotData, fileError);
function fileError(err) {
app.logError(me + '::fileError:::' + err);
}
function gotData(base64String) {
var request = new XMLHttpRequest;
app.log(me + '::token::' + token);
request.open("PUT", "https://apis.live.net/v5.0/me/skydrive/files/" + fileName + "?access_token=" + token, true);
request.setRequestHeader('Content-Type', 'text/plain');
//request.setRequestHeader('Content-Type', 'image/jpg');
//request.setRequestHeader('Content-Transfer-Encoding', 'base64;charset=utf-8');
request.onload = function (e) {
app.log(request.responseText);
success(e);
};
request.onerror = function (e) {
app.log(me + '::7::');
fail(e.error.message);
};
app.log(me + '::8::' + base64String.substr(0,100));
var b = new Base64Stuff();
var aBuffer = b.base64ToBuffer(b.removeBase64jpgHeader(base64String));
request.send(aBuffer);
//request.send(base64String);
}
}
try
request.setRequestHeader('Content-Type', '');