Question
Below google script running fine but the file uploaded send via email is corrupted or blank while getting through email.. Attached filename, content type are same as uploaded... but getting file cannot be opened.. text files are fine... Could any one can help in this regard.
Code.gs
function doGet() {
return HtmlService.createHtmlOutputFromFile('index')
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function processForm(formObject) {
var myFile = formObject.myFile;
var FileBytes = myFile.getBytes();
var FileType = myFile.getContentType();
var FileName = myFile.getName();
var FileToSend = {
fileName: FileName,
content: FileBytes,
mimeType: FileType
};
// Logger.log(FileType);
var FileBytes2 = [100, 97, 121, 32, 108, 97, 32, 110, 111, 105, 32, 100, 117, 110, 103, 32, 98, 101, 110, 32, 116, 114, 111, 110, 103];
var FileToSend2 = {
fileName: 'test222.txt',
content: FileBytes2,
mimeType: 'text/plain'
};
var FileToSend3 = {
fileName: 'test333.txt',
content: 'noi dung ben trong',
mimeType: 'text/plain'
};
GmailApp.sendEmail('email@domain', '6 Attachment example', '6 Please see the attached file.', {
attachments: [FileToSend, FileToSend2, FileToSend3],
name: '6 Automatic Emailer Script'
});
return FileName;
}
index.html
<html>
<head>
<base target="_top">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<script>
// Prevent forms from submitting.
function preventFormSubmit() {
var forms = document.querySelectorAll('form');
for (var i = 0; i < forms.length; i++) {
forms[i].addEventListener('submit', function(event) {
event.preventDefault();
});
}
}
window.addEventListener('load', preventFormSubmit);
function handleFormSubmit(formObject) {
google.script.run.withSuccessHandler(updateUrl).processForm(formObject);
}
function updateUrl(filename) {
var div = document.getElementById('output');
div.innerHTML = filename;
}
</script>
</head>
<body>
<form action="#" id="myForm" onsubmit="handleFormSubmit(this)" method="post" enctype="multipart/form-data">
<div class="file-field input-field">
<div class="btn">
<span>File</span>
<input name="myFile" type="file" multiple>
</div>
<div class="file-path-wrapper">
<input class="file-path validate" type="text" placeholder="Upload one or more files">
</div>
</div>
<input type="submit" value="Submit" />
</form>
<div id="output"></div>
</body>
</html>
To solve your issue, in the handleFormSubmit
function, I took an array buffer and transformed it into a string containing the file data and pass it to your processForm
function, in order for that logic to be handled in the frontend instead of the backend, google.script.run is a little picky with the values you can pass as arguments. Therefore, your handleFormSubmit
function will look like this now:
const handleFormSubmit = async (formObject) => {
// Get all the file data
let file = formObject.myFile.files[0];
// Get binary content, we have to wait because it returns a promise
let fileBuffer = await file.arrayBuffer();
// Get the file content as binary and then pass it to string
const data = (new Uint8Array(fileBuffer)).toString();
// Pass the file meta data and the content
google.script.run.withSuccessHandler(updateUrl).processForm(file.name, file.type, data);
}
As for the backend function processForm
, you will need to transform the data
string into a binary data array again, that's why I use JSON.parse("[" + data + "]")
. Now, your processForm
will look like this:
function processForm(name, type, data) {
var fileToSend = {
fileName: name,
// Convert the string to a Binary data array
content: JSON.parse("[" + data + "]"),
mimeType: type
};
GmailApp.sendEmail('email@domain', '6 Attachment example', '6 Please see the attached file.', {
attachments: [fileToSend],
name: '6 Automatic Emailer Script'
});
return "this file " + name + " has just been sent to your email";
}