I am new to App Script. My code is below. I have been trying to take data out of an email and put it into different columns in google sheets. I have managed to achieve this and it works but because labels are applied to threads I get duplicates!
I have tried to figure out how to stop this from happening by using the email ID, date etc but I haven't been successful. Any help would be greatly appreciated.
function email_sheet() {
var ss = SpreadsheetApp.openById("");
var sheet = ss.getSheetByName("Sheet1");
var label = GmailApp.getUserLabelByName("ChosenLabel");
var threads = label.getThreads();
for (var i = 0; i < threads.length; i++) {
var messages = threads[i].getMessages();
for (var j = 0; j < messages.length; j++) {
var date = messages[j].getDate();
var body = messages[j].getPlainBody();
var name = "";
var accnum = "";
var paytype ="";
var amount = "";
var status = "";
/** Break Down the Email */
if(body.indexOf("Recipient : ")>0) {
var end = body.substring(body.indexOf("Recipient : ")+12,body.length);
name = end.substring(0, end.indexOf("\n"));
}
if(body.indexOf("AN")>0) {
var end = body.substring(body.indexOf("AN")+2,body.length);
account = end.substring(0, end.indexOf("\n"));
var [accnum, paytype] = account.split(" ");
}
if(body.indexOf("Amount : ")>0) {
var end = body.substring(body.indexOf("Amount : ")+9,body.length);
amount = end.substring(0, end.indexOf("\n"));
}
if(body.indexOf("Transaction Status : ")>0) {
var end = body.substring(body.indexOf("Transaction Status : ")+21,body.length);
status = end.substring(0, end.indexOf("\n"));
}
sheet.appendRow([date, name, accnum, paytype, amount, status]);
}
threads[i].removeLabel(label);
threads[i].addLabel(GmailApp.getUserLabelByName("All Transactions"))
}
} ```
You can for instance limit to unread mails and at the end mark them as already read, for instance
function mail() {
var requete ="is:unread {label:ChosenLabel label:OtherLabel}"
var ss = SpreadsheetApp.getActive().getSheetByName("Mail");
var threads = GmailApp.search(requete);
for (var i = 0; i < threads.length; i++) {
var messages = threads[i].getMessages();
for (var j = 0; j < messages.length; j++) {
var msg = messages[j].getPlainBody();
var sub = messages[j].getSubject();
var dat = messages[j].getDate();
ss.appendRow([dat, sub, msg])
}
}
GmailApp.markThreadsRead(threads);
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 months ago.
Improve this question
I want to extract the content from an xlsx gmail attachment via google apps script. And then put the information into a Google Sheet. It's working fine for CSV files, but I don't get the content of a xlsx file.
Unlike csv files, xlsx file data cannot be directly inserted into a spreadsheet
What you can do instead:
Save the attachment on your disc in its original mimeType
Convert it to a Google Sheets document with e.g. Drive.Files.copy
Delete the excel file from your disc
Sample:
function GmailToDrive() {
var threads = GmailApp.getInboxThreads();
var message = threads[0].getMessages()[0];
var attachment = message.getAttachments()[0];
var blob = attachment.getAs(attachment.getContentType());
blob.setName(attachment.getName())
var excel = DriveApp.createFile(blob);
Drive.Files.copy({mimeType: MimeType.GOOGLE_SHEETS}, excel.getId());
excel.setTrashed(true)
}
Note that Drive is an advances service that needs to be enabled beforehand.
You can extract data directly from MS Excel files stored in Google Drive or in Gmail attachment without any upload or conversion to Google Spreadsheet. ππΎπ₯³
Since xlsx workbooks are zipped XML files you can unzip the xlsx blob, process the XML files and extract data needed like this.
/**
* Parsing MS Excel files and returns values in JSON format.
*
* #param {BlobSource} blob the blob from MS Excel file
* #param {String[]} requiredSheets the array of required sheet names (if omitted returns all)
* #return {Object} Object of sheet names and values (2D arrays)
*/
function parseMSExcelBlob(blob, requiredSheets){
var col_cache = {};
var forbidden_chars = {
"<": "<",
">": ">",
"&": "&",
"'": "'",
""": '"'
};
blob.setContentType("application/zip");
var parts = Utilities.unzip(blob);
var relationships = {};
for( var part of parts ){
var part_name = part.getName();
if( part_name === "xl/_rels/workbook.xml.rels" ){
var txt = part.getDataAsString();
var rels = breakUpString(txt, '<Relationship ', '/>');
for( var i = 0; i < rels.length; i++ ){
var rId = breakUpString(rels[i], 'Id="', '"')[0];
var path = breakUpString(rels[i], 'Target="', '"')[0];
relationships[rId] = "xl/" + path;
}
}
}
var worksheets = {};
for( var part of parts ){
var part_name = part.getName();
if( part_name === "xl/workbook.xml" ){
var txt = part.getDataAsString();
var sheets = breakUpString(txt, '<sheet ', '/>');
for( var i = 0; i < sheets.length; i++ ){
var sh_name = breakUpString(sheets[i], 'name="', '"')[0];
sh_name = decodeForbiddenChars(sh_name);
var rId = breakUpString(sheets[i], 'r:id="', '"')[0];
var path = relationships[rId];
if( path.includes("worksheets") ){
worksheets[path] = sh_name;
}
}
}
}
requiredSheets = Array.isArray(requiredSheets) && requiredSheets.length && requiredSheets || [];
var worksheets_needed = [];
for( var path in worksheets ){
if( !requiredSheets.length || requiredSheets.includes(worksheets[path]) ){
worksheets_needed.push(path);
}
}
if( !worksheets_needed.length ) return {"Error": "Requested worksheets not found"};
var sharedStrings = [];
for( var part of parts ){
var part_name = part.getName();
if( part_name === "xl/sharedStrings.xml" ){
var txt = part.getDataAsString();
txt = txt.replace(/ xml:space="preserve"/g, "");
sharedStrings = breakUpString(txt, '<t>', '</t>');
for( var i = 0; i < sharedStrings.length; i++ ){
sharedStrings[i] = decodeForbiddenChars(sharedStrings[i]);
}
}
}
var result = {};
for( var part of parts ){
var part_name = part.getName();
if( worksheets_needed.includes(part_name) ){
var txt = part.getDataAsString();
var cells = breakUpString(txt, '<c ', '</c>');
var tbl = [[]];
for( var i = 0; i < cells.length; i++ ){
var r = breakUpString(cells[i], 'r="', '"')[0];
var t = breakUpString(cells[i], 't="', '"')[0];
if( t === "inlineStr" ){
var data = breakUpString(cells[i].replace(/ xml:space="preserve"/g, ""), '<t>', '</t>')[0];
data = decodeForbiddenChars(data);
}else if( t === "s" ){
var v = breakUpString(cells[i], '<v>', '</v>')[0];
var data = sharedStrings[v];
}else{
var v = breakUpString(cells[i], '<v>', '</v>')[0];
var data = Number(v);
}
var row = r.replace(/[A-Z]/g, "") - 1;
var col = colNum(r.replace(/[0-9]/g, "")) - 1;
if( tbl[row] ){
tbl[row][col] = data;
}else{
tbl[row] = [];
tbl[row][col] = data;
}
}
var sh_name = worksheets[part_name];
result[sh_name] = squareTbl(tbl);
}
}
function decodeForbiddenChars(txt){
for( var char in forbidden_chars ){
var regex = new RegExp(char,"g");
txt = txt.replace(regex, forbidden_chars[char]);
}
return txt;
}
function breakUpString(str, start_patern, end_patern){
var arr = [], raw = str.split(start_patern), i = 1, len = raw.length;
while( i < len ){ arr[i - 1] = raw[i].split(end_patern, 1)[0]; i++ };
return arr;
}
function colNum(char){
if( col_cache[char] ) return col_cache[char];
var alph = "ABCDEFGHIJKLMNOPQRSTUVWXYZ", i, j, result = 0;
for( i = 0, j = char.length - 1; i < char.length; i++, j-- ){
result += Math.pow(alph.length, j) * (alph.indexOf(char[i]) + 1);
}
col_cache[char] = result;
return result;
}
function squareTbl(arr){
var tbl = [];
var x_max = 0;
var y_max = arr.length;
for( var y = 0; y < y_max; y++ ){
arr[y] = arr[y] || [];
if( arr[y].length > x_max ){ x_max = arr[y].length };
}
for( var y = 0; y < y_max; y++ ){
var row = [];
for( var x = 0; x < x_max; x++ ){
row.push(arr[y][x] || arr[y][x] === 0 ? arr[y][x] : "");
}
tbl.push(row);
}
return tbl.length ? tbl : [[]];
}
return result;
}
Using the function parseMSExcelBlob(blob, requiredSheets) you can put the data in a gsheet.
function getDataFromGmail(){
var threads = GmailApp.getInboxThreads();
var message = threads[0].getMessages()[0];
var attachment = message.getAttachments()[0];
var blob = attachment.copyBlob();
// if second parameter is not provided all sheets will be parsed
var data = parseMSExcelBlob(blob, ["Funny corgi names"]);
// here we have the data in 2D array
var tbl = data["Funny corgi names"];
// putting data into the sheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName("Corgi names");
sh.clearContents();
sh.getRange(1, 1, tbl.length, tbl[0].length).setValues(tbl);
}
Also find it in this GitHub repo.
i use the following code in Google Apps Script and i wanna get all messages in the inbox. This code gives "Cannot convert Array to number[][]. (line 19, file "Code")" error. How can i fix this code?
var myspreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var mysheet = myspreadsheet.getSheets()[0];
var start = 0;
var max = 19;
var count = 0;
while (count < 7) {
var threads = GmailApp.getInboxThreads(start, max);
var messages = GmailApp.getMessagesForThreads(threads);
//var froms = [];
messages.get
for (var i = 0; i < threads.length; i++) {
var thisThread = threads[i];
var messages = thisThread.getMessages();
var messageCount = thisThread.getMessageCount();
for ( var m = 0; m<=messageCount; m++) {
var lastMessage = messages[m];
froms = ([lastMessage.getId(), lastMessage.getSubject(), lastMessage.getTo(), lastMessage.getFrom(), lastMessage.getCc(), JSON.stringify(lastMessage.getDate()), lastMessage.getReplyTo()]);
mysheet.getRange(1, 1, froms.length, 7).setValues(froms);
froms = [];
}
}
start = start + 100;
count++;
}
}
Try changing this: froms = ([lastMessage.getId(), lastMessage.getSubject(), lastMessage.getTo(), lastMessage.getFrom(), lastMessage.getCc(), JSON.stringify(lastMessage.getDate()), lastMessage.getReplyTo()]);
to this: froms = ([[lastMessage.getId(), lastMessage.getSubject(), lastMessage.getTo(), lastMessage.getFrom(), lastMessage.getCc(), JSON.stringify(lastMessage.getDate()), lastMessage.getReplyTo()]]);
But really I think you have even bigger problems with your script.
I'd use something like this. But I can't test it very well because I don't keep a lot of junk in my inbox.
function emailsStuff() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheets()[0];
sh.clearContents();
var threads=GmailApp.getInboxThreads()
for(var i=0;i<threads.length;i++) {
var messages=GmailApp.getMessagesForThread(threads[i]);
for(var j=0;j<messages.length;j++) {
var msg=messages[j];
sh.appendRow([msg.getId(), msg.getSubject(), msg.getTo(), msg.getFrom(), msg.getCc(), JSON.stringify(msg.getDate()), msg.getReplyTo()]);
}
}
}
I have a string where |||| means next to it is the directory. ||| means the user is allowed to access this directory and || means the files allocated to these users follow.
I need to find allocated file names of a specific user from this string. I have tried to split the string and assign values to an array but I am not able to get the result I'm looking for.
This is the string:
||||Root|||adil001,km11285c,km61052,km61639c,adil001,kl04707c,km47389,km58184,km61052,kq61023c,adil001,km11285c,km61052,km61639c,||LimitTest_20140528164643.xlsx,testTask2_20140528140033.xlsx,||||1400842226669|||adil001,km11285c,km61052,km61639c,adil001,kl04707c,km47389,km58184,km61052,kq61023c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,||LimitTest_20140528164643.xlsx,testTask2_20140528140033.xlsx,testTask1_20140528135944.xlsx,testTask2_20140528140033.xlsx,||||1401191909489|||adil001,km11285c,km61052,km61639c,adil001,kl04707c,km47389,km58184,km61052,kq61023c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,adil001,kl04707c,km47389,km58184,km61052,kq61023c,||LimitTest_20140528164643.xlsx,testTask2_20140528140033.xlsx,testTask1_20140528135944.xlsx,testTask2_20140528140033.xlsx,LimitTest_20140528164643.xlsx,
And here is my attempt:
function getData() {
var user = 'km11285c';
var value = "||||Root|||adil001,km11285c,km61052,km61639c,adil001,kl04707c,km47389,km58184,km61052,kq61023c,adil001,km11285c,km61052,km61639c,||LimitTest_20140528164643.xlsx,testTask2_20140528140033.xlsx,||||1400842226669|||adil001,km11285c,km61052,km61639c,adil001,kl04707c,km47389,km58184,km61052,kq61023c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,||LimitTest_20140528164643.xlsx,testTask2_20140528140033.xlsx,testTask1_20140528135944.xlsx,testTask2_20140528140033.xlsx,||||1401191909489|||adil001,km11285c,km61052,km61639c,adil001,kl04707c,km47389,km58184,km61052,kq61023c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,adil001,kl04707c,km47389,km58184,km61052,kq61023c,||LimitTest_20140528164643.xlsx,testTask2_20140528140033.xlsx,testTask1_20140528135944.xlsx,testTask2_20140528140033.xlsx,LimitTest_20140528164643.xlsx,";
var users = null;
var files = null;
var Dir = value.split("||||");
var arrayLength = Dir.length;
for (var i = 0; i < arrayLength; i++) {
users = Dir[i].split("|||");
}
return users;
}
console.log(getData());
and the jsFiddle
I changed your jsfiddle example a bit so maybe you need to change the code here and there, but something like this should work:
function buildTree(data) {
var tree = [];
var dirs = data.split("||||");
// Remove the first entry in the array, since it should be empty.
dirs.splice(0, 1);
for (var i = 0; i < dirs.length; ++i) {
var tempArray = dirs[i].split("|||");
var dirName = tempArray[0];
var usersAndFiles = tempArray[1];
tempArray = usersAndFiles.split("||");
var users = tempArray[0];
var files = tempArray[1];
var treeDir = { name: dirName };
treeDir.users = users.split(",");
treeDir.files = files.split(",");
tree.push(treeDir);
}
return tree;
}
function getData() {
var user = 'km11285c';
var value="||||Root|||adil001,km11285c,km61052,km61639c,adil001,kl04707c,km47389,km58184,km61052,kq61023c,adil001,km11285c,km61052,km61639c,||LimitTest_20140528164643.xlsx,testTask2_20140528140033.xlsx,||||1400842226669|||adil001,km11285c,km61052,km61639c,adil001,kl04707c,km47389,km58184,km61052,kq61023c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,||LimitTest_20140528164643.xlsx,testTask2_20140528140033.xlsx,testTask1_20140528135944.xlsx,testTask2_20140528140033.xlsx,||||1401191909489|||adil001,km11285c,km61052,km61639c,adil001,kl04707c,km47389,km58184,km61052,kq61023c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,adil001,kl04707c,km47389,km58184,km61052,kq61023c,||LimitTest_20140528164643.xlsx,testTask2_20140528140033.xlsx,testTask1_20140528135944.xlsx,testTask2_20140528140033.xlsx,LimitTest_20140528164643.xlsx,";
var tree = buildTree(value);
for (var i = 0; i < tree.length; ++i) {
var dir = tree[i];
if (dir.users.indexOf(user) >= 0) {
console.log("User '" + user + "' has access to directory '" + dir.name + "', which contains these files: " + dir.files.join(","));
}
}
}
getData();