I am using the below google apps script to search recent email from a particular mail address in my inbox. This email has no labels and this script is trying to look at all mails. How to minimize the search for an email and pull out the recent one.
function myFunction()
{
var searchterm = 'myemail#mydomain.com';
var threads = GmailApp.search(searchterm);
var messages = GmailApp.getMessagesForThreads(threads);
for (var i = 0; i < threads.length; i++)
{
for (var j = 0; j < messages[i].length; j++)
{
var mailFrom = messages[i][j].getFrom();
}
}
}
How about this sample script?
Modification points :
For var threads = GmailApp.search(searchterm);, threads[0] is the latest thread.
When From is only the particular mail address, it retrieves the mail.
When thread[0] is processed by loop using forEach(), the lower element is newer one.
The script reflected these is as follows.
Script :
var mailAddress = "myemail#mydomain.com";
var mailFrom;
var thread = GmailApp.search("from:" + mailAddress);
thread[0].getMessages().forEach(function(message) {
var f = message.getFrom();
var d = message.getDate();
if (!~f.indexOf(mailAddress)) return;
mailFrom = [f, d];
});
Result :
[name <myemail#mydomain.com>, Sat Jan 1 12:34:56 GMT 2017]
When the process time is measured, I confirmed that this script brought the improvement about 30% for your sample script. Although I don't know whether this is the best, if this is useful for you, I'm glad.
If I misunderstand your question, I'm sorry.
You may use the following search term:
var searchterm = "from: myemail#mydomain.com newer:"+parseInt(date/1000);
where date is the time value of javascript date variable. For example current date can be calculated as:
date = new Date().getTime();
This searchterm would return the email threads that are newer than the above date
Related
Hi I'm trying to measure how many people responded yes to my events for Q1 on a spreadsheet. I'm using the Google Calendar API on a Google Sheet.
I see Google Apps Scripts has ways to check guest status but I don't understand how it would work. These events are 1 on 1 so there's always only 2 guests (me and the client). So If I see 2 "Yes" I know they attended. However if I could also see the guest's email/name that would be even better, but I know that's a lot to ask.
Here's my formula, thank you so much!
function getEvents() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var cal = CalendarApp.getCalendarById("mysheet")
var events = cal.getEvents(new Date("1/1/2020 12:00 AM "), new Date("4/30/2020 11:59 PM"))
for(var i=0;i<events.length;i++){
var title = events[i].getTitle();
var date = events[i].getStartTime();
//doesn't work....var guests = events[i].getGuestStatus();
var description = events[i].getDescription();
Logger.log(title);
ss.getRange(i+2,1).setValue(title)
ss.getRange(i+2,2).setValue(date)
//doesn't work....ss.getRange(i+2,3).setValue(guests)
ss.getRange(i+2,4).setValue(description)
}
}
To get the guest status you need to retrieve events[i].getGuestList(), loop through the guest list and retrieve for each guest guests[j].getGuestStatus()
Sample
...
var title = events[i].getTitle();
var date = events[i].getStartTime();
var guests = events[i].getGuestList();
var guestInfo = "";
for (var j = 0; j < guests.length; j++) {
var guest = guests[j].getEmail();
var status = guests[j].getGuestStatus();
Logger.log(guest);
guestInfo += guest+": " + status + ", ";
}
Logger.log(guestInfo);
...
I am writing a Google Apps script to create a calendar event based on automated emails I receive for jobs. I am using regex expressions to extract information that I need to populate the event in Google Calendar. So far, I have everything functioning as expected except for one function, getEndTime(), which should find the end time of the job, but presently returns null any time it's called. All of my other functions using exec() work fine.
I have read many other questions regarding exec() returning null and have fixed common issues, such as removing the 'g' tag and resetting the lastIndex to 0 before calling exec(). I have also checked my regex expression using regex101.com with the Javascript option, which shows the match that I expect for my text.
My regex expression that works on regex101, but not in my code is:
/(Substitute\s+Report\s+Times:\s+[0-9_ ]*:[0-9_ ]*\s+[A-Z_ ]*\s+-\s+)([0-9_ ]*:[0-9_ ]*\s+(AM|PM))(\r|\n)/
My code is:
function findJobs() {
//Searches Gmail for substitute jobs and creates an event on the calendar
//Gets emails with 'NewJobs' label
var label = GmailApp.getUserLabelByName("NewJobs");
var threads = label.getThreads();
for (var i = 0; i < threads.length; i++){
var messages = threads[i].getMessages();
Logger.log("Thread " + i);
for (var j = 0; j < messages.length; j++) {
Logger.log("Message " + j);
//gets email body in plain text
var body = messages[j].getPlainBody();
Logger.log("Getting body..." + j);
//gets school name
var school = getSchool(body);
Logger.log(school);
//gets start time
var starttime = getStartTime(body);
Logger.log(starttime);
//gets end time
var endtime = getEndTime(body);
Logger.log(endtime);
//gets teacher name
var teacher = getTeacher(body);
Logger.log(teacher);
//gets school address
var address = getLocation(body);
Logger.log(address);
//gets date
var startdate = getDate(body);
Logger.log(startdate);
CalendarApp.getDefaultCalendar().createEvent("Subbing - " + school, new Date(startdate + " " + starttime), new Date(startdate + " " + endtime), {location: address, description: teacher});
//threads[j].removeLabel(label);
}
}
Logger.log("--Done--");
}
function getSchool(text){
//Gets the school name from an assignment email
//Regular expression for school name
var regex = /(School\s+:\s+)([a-zA-Z0-9_ ]*)(\r|\n)/;
regex.lastIndex = 0;
var match = regex.exec(text)[2];
return match;
}
function getDate(text){
//Gets the start date from an assignment email
//Regular expression for start date
var regex = /(Date:\s+)([0-9_ ]*\/[0-9_ ]*\/[0-9_ ]*)(\r|\n)/;
regex.lastIndex = 0;
var match = regex.exec(text)[2];
return match;
}
function getStartTime(text){
//Gets the start time from an assignment email
//Regular expression for start time
var regex = /(Substitute\s+Report\s+Times:\s+)([0-9_ ]*:[0-9_ ]*\s+(AM|PM))/;
regex.lastIndex = 0;
var match = regex.exec(text)[2];
return match;
}
function getEndTime(text){
//Gets the end time from an assignment email
//Regular expression for end time
var regex = /(Substitute\s+Report\s+Times:\s+[0-9_ ]*:[0-9_ ]*\s+[A-Z_ ]*\s+-\s+)([0-9_ ]*:[0-9_ ]*\s+(AM|PM))(\r|\n)/;
regex.lastIndex = 0;
Logger.log("End Time reset index...");
var match = regex.exec(text)[2];
Logger.log("End Time exec...");
return match;
}
function getTeacher(text){
//Gets the teacher name from an assignment email
//Regular expression for teacher name
var regex = /(Teacher\s+:\s+)([a-zA-Z0-9_ ]*,[a-zA-Z0-9_ ]*)(\r|\n)/;
regex.lastIndex = 0;
var match = regex.exec(text)[2];
return match;
}
function getLocation(text){
//Gets the location from an assignment email
//Regular expression for location
var regex = /(Address:\s+)(.*)(\r|\n)/;
regex.lastIndex = 0;
var match = regex.exec(text)[2];
return match;
}
Here is an typical email I receive:
You have been assigned as a substitute for a job starting on 9/21/2017.
The following are the details of the job:
*************
Job Summary
*************
Starting On : 9/21/2017
School : School Site
Title : Pre School Teacher
Teacher : Name, Teacher
Substitute : Name, Substitute
Confirmation # : 123456
**********
Job Days
**********
School
---------------------------------------
School Site
Date: 9/21/2017
Employee Times: 8:00 AM - 3:30 PM
Substitute Report Times: 8:00 AM - 3:30 PM
***********************************
School Contact Information
***********************************
School Site
-----------------------------------------------------------
Address: 123 Main Ave Anytown , USA 555555
Phone: 5555555555
-----------------------------------------------------------
**********************
Special Instructions
**********************
Please do not reply to this system generated message. If you need help or have additional questions, please send an email to abc#abc.com
Thank you for using the substitute assignment system. Powered by Aesop
The pattern you're using seems overly complicated. I can't say for sure what's causing it to fail, but my guess would be the (\r|\n) at the end (note that you can just type [\r\n] instead if you really want to do this).
Give this pattern a try:
Substitute Report Times:.+ - (\d{1,2}:\d{1,2} [AP]M)
This assumes that the end time is always preceded by a hyphen and a space, which looks to be the case from the sample text you provided.
I'm a junior javascript/google-apps-script developer and I wanted to add some functionality to some of my worksheets at Google Sheets. I'm working with many URLs and need to track what time they were last modified by the author.
I've built some script which I thought will work but apparently (after some reading) needs some professional touch.
The idea is to iterate through a column of URLs (2500~) and output each URL's modified date (from its meta-data) into a cell from the right. Here is my code:
function iteration1() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
**//The list to iterate on.**
var sheet = ss.getSheetByName("Fund List");
**//The column of which the links are stored**
var urls = sheet.getRange("D2:D150").getValues();
for (var row = 0; row < urls.length; row++) {
for (var col = 0; col < urls[row].length; col++)
**//Varifying if there is a URL within the cell**
if (urls[row][col] != '') {
**//Storing each URL in a new array**
var url = UrlFetchApp.fetch(urls[row][col].valueOf());
**//Parsing the meta-data of the URL into an array**
var tweets = JSON.parse(url);
**//Retrieve the link modification date from the meta-data array & outputs to the cell from the right respectivley.**
sheet.getRange(row+2, 13).setValue(Logger.log(tweets[4][2]).getLog());
}
}
}
For Example: the link http://documents.financialexpress.net/Literature/37773008.pdf
Its meta-data is:
{Accept-Ranges=bytes, X-Robots-Tag=noindex, nofollow, noarchive,nosnippet, Cache-Control=max-age=604800, Server=Microsoft-IIS/7.0, ETag="01827159b1d11:0", Access-Control-Allow-Origin=*, Access-Control-Allow-Methods=GET,PUT,POST,DELETE,OPTIONS, Last-Modified=Wed, 18 May 2016 23:00:00 GMT, Content-Length=113029, Access-Control-Allow-Headers=Content-Type, Date=Thu, 01 Sep 2016 11:43:52 GMT, Content-Type=application/pdf}
I only need the Last-Modified field Date within this meta-data array and output it to the cell from the right.
Thanks in advance for the helpers! great community here!
I have added a screenshot of my current code and the debugger mode which gives an example of the links I'm working on:
From what I see from the google documentation ( https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#fetch(String) ) the result you are storing in the variable url isn't a string.
JSON.parse accept a string and transform it into a javascript Object/Array/String/whatever
You need to use instead of JSON.parse(url), JSON.parse(url.getContentText('utf-8')) as documented here : https://developers.google.com/apps-script/reference/url-fetch/http-response
After few days working on it, I have managed to retrieve the value for the Last-Modified date key per each URL within my sheet.
My code:
function iteration1() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
//The Google sheet to access
var sheet = ss.getSheetByName("Sheet Name");
//The array of URLs to check
var urls = sheet.getRange("D2:D150").getDisplayValues();
for (var row = 0; row < urls.length; row++) {
for (var col = 0; col < urls[row].length; col++) {
if (urls[row][col].toString() != '') {
//Converting each URL to string and retrieving its Properties into a new Array
var url = UrlFetchApp.fetch(urls[row][col].toString());
var tweets = url.getAllHeaders();
//Forming an array of Properties by Keys & Values
var userProperties = PropertiesService.getUserProperties();
userProperties.setProperties(tweets);
var tweetsKeys = Object.keys(tweets);
}
}
//Retrieving the link modification date from the property meta-data & outputs it as a String to the cell from the right respectivley.
sheet.getRange(row+2, 12).setValue(userProperties.getProperty(tweetsKeys[7]));
}
}
Thank you very much for your responses!
I am trying to write a script in google sheets that will send one of two different emails based on the response to a multiple choice question. I can get my if/else statement to send either one or the other of the emails but it will not recognize the text of the multiple choice answer and send the correct email.
Here is the full script:
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = 1;
// Fetch the range of cells A2:B3
var dataRange = sheet.getRange(startRow, 1, numRows, 8)
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var title = row[1]; // First column
var startDate = row[3]; // Second column
var endDate = row[4];
var description = row[2];
var location = row[6];
var eventImport = row[5];
var emailAddress = row[7];
var multchoice = row[8];
if (multchoice == "Part Time") {
var subject = "New Hire Part Time Email - " + startDate;
var emailBody = "Congradulations"
var htmlBody = "Congradulations! Part time person"
MailApp.sendEmail (emailAddress, subject, emailBody);
} else {
var subject = "New Hire Appointment - " + startDate;
var emailBody = "Congratulations! We are excited"
var htmlBody = "Congratulation! </i><br/> <br/> We are excited"
MailApp.sendEmail(emailAddress, subject, emailBody);
}
}
}
I believe the problem is here:
if (multchoice == "Part Time")
Any help is greatly appreciated! I am a novice
It looks like you are assigning your variables starting with '1' I stead of '0'. Start assigning them with 0 and counting up.
Without an example sheet to use, I won't be able to do a whole lot of debugging for you.
However, Apps Script comes with it's own debugger. Select the function you wish you debug and click the Little bug icon beside the play button.
Click on the sidebar where you want to set a breakpoint, where the code will stop executing.
Once it hits that breakpoint you can see all the variables currently within your scope. So the array, value, and i variables are visible to you.
Use this to your advantage and debug your code to find out where the issue is. Alternatively, you can use Logger.log() to log values at certain points within your code and then read back through the logs to try and determine where the problem lies.
The problem is not with your if/else statement. The problem is with how you are assigning your variables from your row[] array. While you use regular numbers in the getRange() function, the range that is returned is an array of those cells. Arrays always start with an index of [0]. Change var multchoice = row[8] to var multchoice = row[7] and your if/else statement will work (you'll want to change all of your other references, too).
i am new to Google apps script, i want to create string of random characters in the code given below in variable body2.
function myfunction() {
var files = DriveApp.getFiles();
while (files.hasNext(`enter code here`)) {
Logger.log(files.next().getName());
}
var recipient = Session.getActiveUser().getEmail();
var subject = 'A list of files in your Google Drive';
var body1 = Logger.getLog();
var body2;
for(var i=0;i<6;i++)
{
body2[i]=BigNumber.tostring("Math.floor(Math.random()*11)");
}
body=body1+body2;
MailApp.sendEmail(recipient, subject, body);
};
but when i run this function, it says "TypeError: Cannot find function tostring in object 0. (line 12, file "Code") " i can't understand how to solve this error?
Why we have to multiply random by 11 , can it be multiplied with any integer number?
what if i want that string in only capital letters.!
Some other question
1) i don't have enough knowledge of JavaScript, is it good to learn GAS directly?
2) i can't find proper written material or documentation for GAS , the material available at Google's official site is seems to be updating time by time , what to do then ? any link to material would help me .!
I guess I just figured
function randomStr(m) {
var m = m || 15; s = '', r = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (var i=0; i < m; i++) { s += r.charAt(Math.floor(Math.random()*r.length)); }
return s;
};
Hope someone finds it helpful.
As for a random string use this its better:
Math.random().toString(36). 36 is the base thus will use letters and numbers in the string.
As for gas documentation, the official page is pretty complete. It changes because it constantly improves and adds new services.
I have this charIdGeneration() in my GAS library
function charIdGenerator()
{
var charId ="";
for (var i = 1; i < 10 ; i++)
{
charId += String.fromCharCode(97 + Math.random()*10);
}
//Logger.log(charId)
return charId;
}