Google Apps Script - SpreadsheetApp.openByUrl() no error but loads nothing - google-apps-script

if i use SpreadsheetApp.getActiveSpreadsheet() it works but i can't run this script with a minute-based trigger because it doesn't have an active spreadsheet.
i tried to use SpreadsheetApp.openByUrl() which runs manually inside the script editor and also runs without error from the minute-based trigger.
my problem is that no cells are updated on my actual sheet which it is supposed to output onto. i think that it's not marking the emails as read either but i receive so many constantly already that it's hard to check at the moment.
https://jsfiddle.net/29Ls3me4/1/
function myFunction() {
//var ss = SpreadsheetApp.getActiveSpreadsheet();
var ss = SpreadsheetApp.openByUrl("https://docs.google*****************************/edit");
var sheet = ss.getSheetByName("sheet1");
var threads = GmailApp.search ('label:unread "Thank you for your order!" -fwd: -re: -failure'); //search string
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();
var to = messages[j].getTo();
var dateString =
dat.getUTCFullYear() + "/" +
("0" + (dat.getUTCMonth()+1)).slice(-2) + "/" +
("0" + dat.getUTCDate()).slice(-2);
var name = messages[j].getSubject();
var invoicenumber = name.match(/\d/g);
if(invoicenumber == null){
invoicenumber = "null";
} else {
invoicenumber = invoicenumber.join("");
}
ss.appendRow([invoicenumber, dateString, to, sub, msg])
}
threads[i].markRead();
//threads[i].markUnread();
}
}

ok simple coding eyeballs
ss.appendRow()
should've been
sheet.appendRow()

Related

Copy paste if Date = Today Google Sheets API

I am new to google script (and Javascript in general) and am trying to create a "Macro" which loops through a large table of data (Titled "Form response 1"), searches each row to see if the data in the 'To-arrive-date" column matches todays date. If the dates match, I want to copy-paste it into another sheet titled "Email". Below is the script I have written so far, but I keep getting an error stating that an unexpected "Var" is on line 15. However, I thought this var needed to be there for the variable "SrcRange"? Any help would be wonderful, thank you.
var sSheet = SpreadsheetApp.getActiveSpreadsheet();
var srcSheet = sSheet.getSheetByName("Form Responses 1");
var tarSheet = sSheet.getSheetByName("Email");
var lastRow = srcSheet.getLastRow();
var Tsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Form Responses 1");
var date = new Date();
Tsheet.getRange(2, 11).setValue(date);
for (var i = 2; i <= lastRow; i++) {
var cell = srcSheet.getRange("C" + i);
var val = cell.getValue();
if (val == SrcSheet.getRange(2, 11).getValues()
var srcRange = srcSheet.getRange("A" + i + ":F" + i);
var tarRow = tarSheet.getLastRow();
tarSheet.insertRowAfter(tarRow);
var tarRange = tarSheet.getRange("A" + (tarRow+1) + ":F" + (tarRow+1));
srcRange.copyTo(tarRange);
}
}
-Evan
Issue
Your IF statement inside the loop is incomplete. It lacks closing parenthesis as well as opening curly brace. I also noticed and commented out unnecessary codes and corrected a few specifically with regards to new Date() method.
Solution
Please see modified code below. Note that I only modified a few part of the code to make it work. I haven't done any optimization(if applicable). Also, this code is working fully on my end.
function myFunction() {
var sSheet = SpreadsheetApp.getActiveSpreadsheet();
var srcSheet = sSheet.getSheetByName("Form Responses 1");
var tarSheet = sSheet.getSheetByName("Email");
var lastRow = srcSheet.getLastRow();
var tSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Form Responses 1");
var date = new Date().toDateString();
tSheet.getRange(2, 11).setValue(date);
for (var i = 2; i <= lastRow; i++) {
var cell = srcSheet.getRange("C" + i);
var val = new Date(cell.getValue().toString()).toDateString();
Logger.log(val+" "+date)
if (val == date){
Logger.log("test")
var srcRange = srcSheet.getRange("A" + i + ":F" + i);
var tarRow = tarSheet.getLastRow();
// tarSheet.insertRowAfter(tarRow);
var tarRange = tarSheet.getRange("A" + (tarRow+1) + ":F" + (tarRow+1));
srcRange.copyTo(tarRange);
}
}
}

Get email details based on the dates in google sheets

I am using the below mentioned apps script to get the email details in google sheets based on the label name updated in the particular cell.
function getBaEmails() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var ss = sheet.getSheetByName("Raw Data");
var row = 2;
ss.getRange(2, 1, ss.getMaxRows() - 1, 4).clearContent();
var label = ss.getRange("F1").getValue();
var pattern = ss.getRange("F2").getValue();
var threads = GmailApp.search("in:" + label);
for (var i = 0; i < threads.length; i++) {
var messages = threads[i].getMessages();
for (var m = 0; m < messages.length; m++) {
var msg = messages[m].getBody();
if (msg.search(pattern) !== -1) {
ss.getRange(row,1).setValue(
Utilities.formatDate(messages[m].getDate(),"GMT","MM-dd-yyyy"));
ss.getRange(row,2).setValue(messages[m].getFrom());
ss.getRange(row,3).setValue(messages[m].getSubject());
var id = "https://mail.google.com/mail/u/0/#all/"
+ messages[m].getId();
ss.getRange(row,4).setFormula(
'=hyperlink("' + id + '", "View")');
row++;
}
}
}
};
I am trying to update the apps script which helps to get the email details based on the dates.
For example : I need a email details from 08/01/2019 to 08/30/2019.
It would be great, if anyone help me to update the apps script.
Thanks in advance.
Try something like this:
You can always test your queries in Gmail
function gmailSearch(label,after,before) {
var label=label||'qs-vendors-google';
var after=after||'2019/01/01';
var before=before||'2019/08/01';
var html='';
var qry=Utilities.formatString('label:%s after:%s before:%s',label,after,before);
var results=GmailApp.search(qry);
for(var i=0;i<results.length;i++) {
var msgs=results[i].getMessages()
for(j=0;j<msgs.length;j++) {
html+=Utilities.formatString('<strong>Date:</strong> %s <strong>From: </strong> %s <strong>Subject: </strong> %s<br />',msgs[j].getDate(),msgs[j].getFrom(),msgs[j].getSubject());
}
}
var userInterface=HtmlService.createHtmlOutput(html).setWidth(1000);
SpreadsheetApp.getUi().showModelessDialog(userInterface, 'Search Results')
}

Logging Google mail in Google sheet, Google Apps Script

HELP! I’m using a script I basically cribbed from Tom Woodward at Bionice Teaching to record email messages in a spreadsheet.
http://bionicteaching.com/auto-logging-email-via-google-script/
I need to add a column that collects any labels that have been attached to the messages. I need to get this done for my work, but I'm brand new to Google Apps Script and really need someone to hold my hand... Essentially doing it for me, then teaching me what it was you did. I really appreciate any help you can give me in any case. Thanks
Here is what I’m using:
function myFunction() {
//this is just the stuff that recognizes what spreadsheet you're in
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var sheet = ss.getSheetByName("data"); //gets the right sheet
//this chunk gets the date info
var today = new Date();
var dd = today.getDate()-1;
var mm = today.getMonth()+1; //January is 0 DO NOT FORGET THIS
var yyyy = today.getFullYear();
var yesterday = yyyy + '/' + mm + '/' + dd;
//****************************************************
//searches your GMail for emails written after yesterday
var query = "after:" + yesterday;
var threads = GmailApp.search(query);
Logger.log('threads len ' + threads.length);
Logger.log(query);
for (var i = 0; i < threads.length; i++) {
var messages = threads[i].getMessages();
Logger.log(messages);
for (var m = 0; m < messages.length; m++) {
var supportStats = [];
//here's where you decide what parts of the email you want
var from = messages[m].getFrom(); //from field
Logger.log(from);
var time = messages[m].getDate();//date field
Logger.log(time);
var subject = messages[m].getSubject();//subject field
Logger.log(subject);
var body = messages[m].getPlainBody();//body field
Logger.log(body);
var mId = messages[m].getId();//id field to create the link later
var mYear = time.getFullYear();
var mMonth = time.getMonth()+1;
var mDay = time.getDate();
var messageDate = mYear + '/' + mMonth + '/' + mDay;
Logger.log('msg date ' + messageDate);
//decides what found emails match yesterday's date and push them to an array to write to the spreadsheet
if (messageDate === yesterday) {
supportStats.push(from);
supportStats.push(time);
supportStats.push(subject);
supportStats.push(body);
supportStats.push('https://mail.google.com/mail/u/0/#inbox/'+mId); //build the URL to the email
SpreadsheetApp.getActiveSheet().appendRow(supportStats); //writes to the spreadsheet
}
}
}
}
Here is the results I'm getting... Perfect!
Except I'd like one more column that adds the labels that are on each message. How do I do that?
spreatsheet results of Google Apps script mail->sheet
You can use this:
var labels = threads[i].getLabels();
GmailThread::getLabels()
GmailThread has labels, not GmailMessage. It returns an array of labels. Maybe use:
var labelsString = "";
var labelArray = []
for each (var label in labels)
{
labelArray.push(label.getName());
}
if (labelArray.length > 0)
{
labelsString = labelArray.join(',');
}
to insert into the row of the spreadsheet.
GmailLabel::getName()

Force refresh ImportXML

I want to force an importXML to auto-refresh every five minutes. This is the script I am trying to run and getting the error "Bad value (line 7, file "RefreshImports" . I do not know why. I found it here: Periodically refresh IMPORTXML() spreadsheet function
function RefreshImports() {
var lock = LockService.getScriptLock();
if (!lock.tryLock(5000)) return; // Wait up to 5s for previous
refresh to end.
var id = "[YOUR SPREADSHEET ID]";
var ss = SpreadsheetApp.openById(id);
var sheet = ss.getSheetByName("[SHEET NAME]");
var dataRange = sheet.getDataRange();
var formulas = dataRange.getFormulas();
var content = "";
var now = new Date();
var time = now.getTime();
var re = /.*[^a-z0-9]import(?:xml|data|feed|html|range)\(.*/gi;
var re2 = /((\?|&)(update=[0-9]*))/gi;
var re3 = /(",)/gi;
for (var row = 0; row < formulas.length; row++) {
for (var col = 0; col < formulas[0].length; col++) {
content = formulas[row][col];
if (content != "") {
var match = content.search(re);
if (match !== -1) {
// import function is used in this cell
var updatedContent = content.toString().replace(re2, "$2update=" +
time);
if (updatedContent == content) {
// No querystring exists yet in url
updatedContent = content.toString().replace(re3, "?update=" + time +
"$1");
}
// Update url in formula with querystring param
sheet.getRange(row + 1, col + 1).setFormula(updatedContent);
}
}
}
}
// Done refresh; release the lock.
lock.releaseLock();
// Show last updated time on sheet somewhere
sheet.getRange(7, 2).setValue("Rates were last updated at " +
now.toLocaleTimeString())
}
In the code where it says "[YOUR SPREADSHEET ID]", I am to enter the name of my spreadsheet correct? I do not know anything about this.
On [YOUR SPREADSHEET ID] you should add the spreadsheet id, not it's name.
The spreadsheet id for
https://docs.google.com/spreadsheets/d/1Xhgfr3z4EwPtjS4aahytU_3TOVxjNb8JvHo88h3nZaE/edit#gid=14522064
is
1Xhgfr3z4EwPtjS4aahytU_3TOVxjNb8JvHo88h3nZaE
I found it easier to use the URL instead the id, here is the bit of code:
var url = "URL OF SPREADSHEET";
var sheetName = "NAME OF SPECIFIC SHEET";
var ss = SpreadsheetApp.openByUrl(url);
var sheet = ss.getSheetByName(sheetName);

Stop recording to spreadsheet if Gmail Label exist

I like to record an email's Subject/Sender/Date/ID into a spreadsheet by it's label and add a "Recorded" label to the email once it's recorded into the spreadsheet. I like to run the script again without re-recording emails with the label "Recorded"
I can get it to the point of recording to spreadsheet and adding the label. but everything i run the script it grabs everything again.
function myFunction() {
var ss = SpreadsheetApp.getActiveSheet();
var searchlabel = GmailApp.getUserLabelByName("Test");
var newlabel = GmailApp.getUserLabelByName("Recored");
var threads = searchlabel.getThreads();
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].getBody();
var sub = messages[j].getSubject();
var from = messages[j].getFrom();
var dat = messages[j].getDate();
var id = messages[j].getId();
var current = new Date();
ss.appendRow([current, dat, sub, id, from])
}
threads[i].addLabel(newlabel);
}
}
I've search the forum and everything tends to suggest to remove the existing label and rename to a different label. But what i wantenter code here is to keep the existing label.
You should the search method since it lets you filter emails that belong to a particular label. Here's the modified version.
function myFunction() {
var ss = SpreadsheetApp.getActiveSheet();
var searchlabel = GmailApp.getUserLabelByName("Test");
var recordlabel = GmailApp.getUserLabelByName("Recorded");
var threads = GmailApp.search("label:Test -label:Recorded");
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].getBody();
var sub = messages[j].getSubject();
var from = messages[j].getFrom();
var dat = messages[j].getDate();
var id = messages[j].getId();
var current = new Date();
ss.appendRow([current, dat, sub, id, from])
}
threads[i].addLabel(recordlabel);
}
}
You can try replacing var threads with:
var threads = GmailApp.search('label:(Test -Recored)');
This searches for all labels with Test but not Recored.
You wouldn't need var searchlabel anymore.