Get Last email from thread and fetch csv attachment - google-apps-script

I an trying to get last email thread csv attachment ID but I am having difficulties working out the code. Anyone able to help?
var searcher = "Automail-"+CurrentDateFormat+".csv";
var searchedThreads = GmailApp.search( 'subject:""'+searcher+'""')[0];
var id = searchedThreads.getId();
var dateMessage = GmailApp.getMessageById(id).getDate();
var contentmessage = GmailApp.getMessageById(id).getPlainBody();
var attachtextLength = GmailApp.getMessageById(id).getAttachments()[0].getDataAsString().length;
if (attachtextLength >= 150){
var attachtext = GmailApp.getMessageById(id).getAttachments()[0].getDataAsString();
UpdateSheet(attachtext);

If you are looking for the last thread matched of multiple threads....
var searchedThreads = GmailApp.search( 'subject:""'+searcher+'""');
searchedThreads = searchedThreads[searchedThreads.length-1];
If you are looking for the last attachment ....
var attachtext = GmailApp.getMessageById(id).getAttachments();
attachtext = attachtext[attachtext.length-1].getDataAsString();
Hope it helps.

Related

Google forms list items with dynamic goto section

I found this answer posted here earlier.
function GoToPage() {
var form = FormApp.openById('MY FORM');
var spreadsheet = SpreadsheetApp.openById("MY SPREADSHEET");
var sheet = spreadsheet.getSheetByName("MY SHEET");
var list = form.getItemById("MY MULTIPLE CHOICE ID").asListItem()
var pagebreak01 = form.getItemById("PAGE BREAK ID 1").asPageBreakItem();
var pagebreak02 = form.getItemById("PAGE BREAK ID 2").asPageBreakItem();
var pagebreak03 = form.getItemById("PAGE BREAK ID 3").asPageBreakItem();
var choice1 = sheet.getRange("RANGE 1 FROM MY SHEET").getValues();
var choice2 = sheet.getRange("RANGE 2 FROM MY SHEET").getValues();
var choice3 = sheet.getRange("RANGE 3 FROM MY SHEET").getValues();
list.setChoices([
list.createChoice(choice1, pagebreak01),
list.createChoice(choice2, pagebreak02),
list.createChoice(choice3, pagebreak03)]);
}
when using a range larger than 1 in the choice# variables, this makes just one choice with all the items in the range separated by commas. how can I use this to make a list of choices that has a dynamic range?
My exact choices should be:
"** Add Location **" , goto newLocation section of form.
location 1, goto next section.
location 2, goto next section.
location 3, ect....
If you select new location and fill out the form to add a new location the script then adds that location name to the choices for the next time you fill out the form. so this list is continually growing larger.
function updateForm() {
var locationForm = form.getItemById("413015265").asListItem();
var equipmentForm = form.getItemById("2123556695").asListItem();
var newLocation = form.getItemById('231469190').asPageBreakItem();
var newItem = form.getItemById('90044295').asPageBreakItem();
var gotoIssue = form.getItemById('1493817332').asPageBreakItem();
var gotoLocation = form.getItemById('1425783734').asPageBreakItem();
var locations = tblLocations.getRange(2,2,tblLocations.getLastRow()-1,1).getValues();
var items = tblItems.getRange(2,2,tblItems.getLastRow()-1,1).getValues();
items = items.sort();
locations = locations.sort();
locationForm.setChoices([
locationForm.createChoice("** Add Location **",newLocation),
locationForm.createChoice(locations,gotoIssue)
]);
equipmentForm.setChoices([
equipmentForm.createChoice("** Add Item **",newItem),
equipmentForm.createChoice(items,gotoLocation)
]);
}
after running the above script I ended up with only 2 choices. 1 new location/item entry which works correctly, and 1 entry with all the current locations/items in the spreadsheet already, separated by commas. Can i just run a foreach loop inside the setChoices command?
function updateForm() {
var locationForm = form.getItemById("413015265").asListItem();
var equipmentForm = form.getItemById("2123556695").asListItem();
var newLocation = form.getItemById('231469190').asPageBreakItem();
var newItem = form.getItemById('90044295').asPageBreakItem();
var gotoIssue = form.getItemById('1493817332').asPageBreakItem();
var gotoLocation = form.getItemById('1425783734').asPageBreakItem();
var locations = tblLocations.getRange(2,2,tblLocations.getLastRow()-1,1).getValues();
var items = tblItems.getRange(2,2,tblItems.getLastRow()-1,1).getValues();
var locationChoices = [];
var itemChoices = [];
locationChoices[0] = locationForm.createChoice("** Add Location **",newLocation);
itemChoices[0] = equipmentForm.createChoice("** Add Item **",newItem);
items = items.sort();
locations = locations.sort();
for (var i=0;i<tblLocations.getLastRow()-1;i++){
locationChoices[i+1]= locationForm.createChoice(locations[i],gotoIssue);
}
locationForm.setChoices(locationChoices);
for (var i=0;i<tblItems.getLastRow()-1;i++){
itemChoices[i+1]= equipmentForm.createChoice(items[i],gotoLocation);
}
equipmentForm.setChoices(itemChoices);
}
I was able to figure it out. It's probably not the most beautiful solution but it works. :)

How can I use a variable as a parameter in getSheetByName?

I have the following code which generates some gslides slides from data in a spreadsheet. The code is attached to the gslides file and it works when the parameters for link/year are entered as strings. However, these parameters will sometimes vary from a set list (e.g. pull from a different sheet or from a different file) so the code sometimes needs to be edited.
I want to share this with colleagues who don't know how to use app scripts and so tried to edit it so that the link/year can be pulled from a textbox in one of the slides in the gslides file. They are pulling through ok but when I try to use it as a parameter I get an error for line 11 (var values = sheet.getRange('F2:aa2').getValues();) as the sheet returns as null.
I've tried wrapping it in quotes (" ' " + year + " ' ") but that doesn't work either.
Please let me know if I need to include more info or a link to the sheets/slides files.
function generateStarters() {
var deck = SlidesApp.getActivePresentation();
var slides = deck.getSlides();
var link = slides[2].getPageElements()[2].asShape().getText().asString()
var year = slides[2].getPageElements()[4].asShape().getText().asString()
var dataSpreadsheetUrl = link
var ss = SpreadsheetApp.openByUrl(dataSpreadsheetUrl);
var sheet = ss.getSheetByName(year);
var values = sheet.getRange('F2:aa2').getValues();
var templateSlide = slides[1];
var presLength = slides.length;
values.forEach(function(page){
if(page[0]){
var Q1 = page[0];
var A1 = page[1];
var Q2 = page[4];
var A2 = page[5];
var Q3 = page[8];
var A3 = page[9];
var Q4 = page[12];
var A4 = page[13];
var QK = page[16];
var AK = page[17];
var QF = page[20];
var AF = page[21];
templateSlide.duplicate(); //duplicate the template page
slides = deck.getSlides(); //update the slides array for indexes and length
newSlide = slides[3]; // declare the new page to update
var shapes = (newSlide.getShapes());
shapes.forEach(function(shape){
shape.getText().replaceAllText('{{q1}}',Q1);
shape.getText().replaceAllText('{{a1}}',A1);
shape.getText().replaceAllText('{{q2}}',Q2);
shape.getText().replaceAllText('{{a2}}',A2);
shape.getText().replaceAllText('{{q3}}',Q3);
shape.getText().replaceAllText('{{a3}}',A3);
shape.getText().replaceAllText('{{q4}}',Q4);
shape.getText().replaceAllText('{{a4}}',A4);
shape.getText().replaceAllText('{{qk}}',QK);
shape.getText().replaceAllText('{{ak}}',AK);
shape.getText().replaceAllText('{{qf}}',QF);
shape.getText().replaceAllText('{{af}}',AF);
});
presLength = slides.length;
newSlide.move(presLength);
}
});
} ```
The string from the slides file seems to always have a space at the end (from the textbox) so I just needed to add an extra line of code to remove that space.

How to extract the url from a cell Spreadsheet to string and use DocumentApp.openByUrl

In a Spreadsheet cell I have a link to a Google doc and I want to recuperate it in order to open the Google Doc and modify it. So in my cell I've put this format https://docs.google.com/document/d/1Gb48I...... (without the /edit in the end) and I've tried
var body = '=HYPERLINK("'data[n][COLUMN_URL-1]'+'/edit'")'.getBody();
var body = '=HYPERLINK("'data[n][COLUMN_URL-1]'+'/edit'")'.getBody();
// this one works but I want to use data[n][COLUMN_URL-1] because I have several Google Docs links
var body = DocumentApp.openByUrl('https://docs.google.com/document/d/1Gb48IXos......../edit').getBody();
if(body){
//edit the Google doc
If you have ideas what to do thank you because with the concatenation of the /edit(3rd line of code) it works
Edit: The cell is not formatted(hyperlinked)/formula i have only the https://...
Edit 2: I've tried with a code from Suhail Ansari thank you but I have an error that the document is missing and I don't have nothing for the logs if you have others ideas:
var COLUMN_URL = 10 ;
function getIdFrom(url) {
var id = "";
var parts = url.split(/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/);
if (url.indexOf('?id=') >= 0){
id = (parts[6].split("=")[1]).replace("&usp","");
return id;
} else {
id = parts[5].split("/");
//Using sort to get the id as it is the longest element.
var sortArr = id.sort(function(a,b){return b.length - a.length});
id = sortArr[0];
return id;
}
}
var sheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(SHEET_NAME);
var numRows = sheet.getLastRow();
var lastColumn = sheet.getLastColumn();
var data = sheet.getRange(1,1,numRows,lastColumn).getDisplayValues();
for(n=1;n < data.length;n++) {
var URL =data[n][COLUMN_URL-1];
Logger.log('The URL ',URL);
var id = getIdFrom(URL);
Logger.log('The ID ',id);
var body = DocumentApp.openById(id).getBody();
if(body)
{......//edit Google Doc
This is the 10 column with the URLs from the Google Docs
In fact I have docs.google.com/open?id=1qo0B_HCbjcBrYyJ ... as URL for the others rows I tried to do by hand for 3rd one as you can see in the picture
Edit 3: So I am very confused in this moment because the column I have in the spreadsheet commes from a loop where I put the URL of the Google Docs in the cell like this : var trange = sheet.getRange.. trange.setValue(doc.getUrl()); and now if i look at the table i have the links in this format
https://docs.google.com/open?id=1RYRVotAq6IOz5tys1krnENfgN_pU0KYuUzR24i
so now if i want to get back the Google Doc I have the following :
// var body = DocumentApp.openByUrl('https://docs.google.com/open?id=1Xb4QjiWwpn2TJ8-9kkIhU6m1rgmb48g6xYVopN').getBody();
//var body = DocumentApp.openByUrl('https://docs.google.com/1Xb4QjiWwpn2TJ8-9kkIhU6m1rgmb48g6xYVopN/edit').getBody();
var body = DocumentApp.openByUrl('https://docs.google.com/document/d/1Xb4QjiWwpn2TJ8-9kkIhU6m1rgmb48g6xYVopN/edit').getBody();
only the 3rd one works.Where I am doing wrong? Because I want to
for(n=1;n < data.length;n++) {... make a loop for and var URL =
data[n][COLUMN_URL-1];
You could add some code for getting the Doc ID from the URL and then open the doc by using
DocumentApp.openById(id);
Here is a link to do that.
A sample code below with help from the above linked answer:
function myFunction() {
var URL = SpreadsheetApp.getActiveSheet().getRange('A1').getValue();
var id = getIdFrom(URL);
var doc = DocumentApp.openById(id);
var body = doc.getBody();
Logger.log(body.getText());
}
function getIdFrom(url) {
var id = "";
var parts = url.split(/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/);
if (url.indexOf('?id=') >= 0){
id = (parts[6].split("=")[1]).replace("&usp","");
return id;
} else {
id = parts[5].split("/");
//Using sort to get the id as it is the longest element.
var sortArr = id.sort(function(a,b){return b.length - a.length});
id = sortArr[0];
return id;
}
}
Demo Google Sheet

Google apps script search sheet for value is not working like expected

I would like to search my google sheet for a value, the value that I am looking for is an ID for customers; 'SGK - xxx' is the format of the ID (xxx is a number).
I am currently using the following code:
var data = spr.getDataRange().getValues();
for(n=0;n<data.length;++n){
if(data[n][0].toString().match(CustomerNumber)==CustomerNumber){
data[n][19] = emailCustomer
var KlantNR = data[n][0];
var Email = data[n][3];
var Stad = data[n][10];
var Taalschool = data[n][11];
var Cursus = data[n][12];
var Weken = data[n][13];
var Accommodatie1 = data[n][15];
var TypeAccommodatie = data[n][16];
var TypeKamer = data[n][17];
var VertrekDatum1 = data[n][18];
};
}
Logger.log(data)
spr.getRange(1,1,data.length,data[0].length).setValues(data);
For example: When I search on 'SGK - 4', this code returns 'SGK - 499'. How can I edit this code to return the correct value?
.match(CustomerNumber)
When I remove that line of code it works fine..

Parsing XML Data that I receive from UrlFetch

I want to parse the data I get from UrlFetch into a spreadsheet, but all I'm getting is undefined can someone show me what i'm doing wrong
The xml is at the address https://dl.dropbox.com/u/11787731/Minecraft/bans.xml
function runevery15mins() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("MC Bans");
sheet.clearContents();
var banURL = "https://dl.dropbox.com/u/11787731/Minecraft/bans.xml";
var banXML = UrlFetchApp.fetch(banURL).getContentText();
var banDOC = Xml.parse(banXML, false);
var mcuser = banDOC.bans;
var x = 0;
for(var c=0; c>mcuser.length;c++){
var name = mcuser.getElement("username")[c].getText();
var date = mcuser.getElement("date")[c].getText();
var reason = mcuser.getElement("reason")[c].getText();
var duration = mcuser.getElement("duration")[c].getText();
}
sheet.appendRow([name, date, reason, duration]);
}
You have some small errors in your code.
For example, the second argument in the for loop needs to be c<mcuser.length.
Using the Xml service documentation, this worked for me
function runevery15mins() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("MC Bans");
sheet.clearContents();
var banURL = "https://dl.dropbox.com/u/11787731/Minecraft/bans.xml";
var banXML = UrlFetchApp.fetch(banURL).getContentText();
var banDOC = Xml.parse(banXML, false);
// Get all the child nodes from the document element that are 'user' nodes
var mcusers = banDOC.getElement().getElements('user');
for(var c=0; c<mcusers.length;c++){
var user = mcusers[c];
var name = user.getElement('username').getText();
var date = user.getElement('date').getText();
var reason = user.getElement('reason').getText();
var duration = user.getElement('duration').getText();
sheet.appendRow([name, date, reason, duration]);
}
}
Note for example that the sheet.appendRow line is INSIDE the loop, not outside as you had it before. I also deleted the X variable, since I didn't see any purpose for it.
I also created a user variable, which is an XmlElement, to make it easier to understand how to get the different contents of each node.
You were almost there.
Looks like there was another array you needed to drill down into. Also, your call back to the spreadsheet should be in the loop. Try this:
...
var mcuser = banDOC.bans.user;
for(var i in mcuser){
var name = mcuser[i].getElement("username").getText();
var date = mcuser[i].getElement("date").getText();
var reason = mcuser[i].getElement("reason").getText();
var duration = mcuser[i].getElement("duration").getText();
sheet.appendRow([name, date, reason, duration])
}