JSON.parse doesn't work with url links - javascript

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!

Related

Extract ranges from multiple workbooks / sheets

I have a range of cells (ex: L1:S22) which will send email alert when the values are > 0 in that particular range from active spreadsheet
So far its only sending from the active spreadsheet range. I want it to be called from all other workbooks which is stored in a folder and send email according to that
function CheckSales(){
var app = SpreadsheetApp;
var activeSheet = app.getActiveSpreadsheet().getActiveSheet();
var data=activeSheet.getDataRange().getValues();
var emailAddress=SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").getRange("B2").getValue();
var resultArr=[];
//To Loop through the whole data Rows
for(var i=1;i<data.length;i++)
{
//Takes columns from L to S (To loop through the Columns)
for(var j=11;j<19;j++)
{
var cellVal=data[i][j];
Logger.log(cellVal)
if(cellVal>0)
{
//Stores the Part No, Month Header Value of the Column, Cell Value which is greater then 0
resultArr.push([data[i][0],data[0][j],cellVal])
}
}
}
if(resultArr.length>0)
{
var subject = 'Range exceeded Alert';
//Creates a body through the obtained values
var body='';
for(var m=0;m<resultArr.length;m++)
{
body+="For Part No "+resultArr[m][0].toString()+" and Month "+resultArr[m][1].toString()+", Value is "+resultArr[m][2].toString()+"<br>";
}
MailApp.sendEmail({to:emailAddress,subject:subject,htmlBody:body});
}
}
now the output showing the part number which have exceeded the values after 6 months.
For Part No 60009257001 and Month 7MO, Value is 800
For Part No 60009259007 and Month 12MO, Value is 28032
For Part No 60009260011 and Month >18MO, Value is 74670
For Part No 60009260012 and Month 12MO, Value is 17600
For Part No 60009260013 and Month 10MO, Value is 26389
I expect the output to show all the part numbers from different workbooks
for (var i in activeSheet) {
SpreadsheetApp.setActiveSheet(activeSheet[i])
var sheet = app.getActiveSheet();
var data = activeSheet[i].getDataRange().getValues();
}
you can loop through the different data ranges in the same way as done here with "data" Variable.
For example,
var data=SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Battery').getDataRange().getValues();
//For Loop for data
data2=SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Other Sheet").getDataRange().getValues();
//for Loop for data2

fetch recent email from a specific mail address

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

If/Else Statement not working to send different emails

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).

Combine a Date & a Time Column in Google Sheets for a createEvent() function [duplicate]

This question already has an answer here:
How to merge date and time as a datetime in Google Apps Spreadsheet script?
(1 answer)
Closed 7 years ago.
I need to combine two columns into one dateTime column that can be reading by a createEvent function for startDate.
Column F is the date (mm-dd-yyyy) & Column G is the time (HH:mm PM/AM). I am currently combine them in Column H with the following code:
function conCat() {
var sheet = SpreadsheetApp.getActiveSheet();
var numberOfRows = sheet.getLastRow().toString();
var range = sheet.getRange(2,1,numberOfRows,12);
var values = range.getValues();
var consultedAlreadyFlag = sheet.getRange(2,10,numberOfRows,12);
var sheetName = sheet.getSheetName();
//show updating message
consultedAlreadyFlag.setFontColor('red');
var numValues = 0;
for (var row = 2; row < values.length.toString(); row++) {
//check to see if name and type are filled out - date is left off because length is "undefined"
if (values[row][3].length > 0) {
currentStatus = values[row][1];
//check if it's been entered before
if (values[row][9] != 'EMAIL_SENT'){
sheet.getRange(row+2,8,1,1).setValue('=F' +(row+2)+ '+G' +(row+2));
}
else{
//sheet.getRange(row+2,10,1,1).setValue('EMAIL_SENT');
}
numValues++;
}
//hide updating message
consultedAlreadyFlag.setFontColor('green');
}
}
This code isn't working because when someone submits the form, and the code combines the columns, I cannot get the format to come out as "mm-dd-yyyy HH:mm:ss" which I feel I need in order for my createEvent function to work.
How can I get it to combine the two columns to get the format I need?
I wouldn't bother trying to combine the two columns. There's no point in adding another column, I don't think. You can use JavaScript methods like setHours():
function fncAddToCalender() {
var theEventDate = //To Do - Get the Date
var startMin = value from sheet cell
theEventDate.setHours(15); //Sets event date to 3pm
theEventDate.setMinutes(startMin);
var cal = CalendarApp.getDefaultCalendar();
var event = cal.createEvent(calndrTitle, theEventDate, endDate, {
description : theDescrptn,
location : theLocation,
guests : guestToInvite,
sendInvites : true
});
};
The format in the spreadsheet is probably set to "date". And getting the values with Apps Script will probably return a value that's already in a date format. If you have the columns formatted as text, you'd need to change the values to a date.

How do I compare string data between cells in a google spreadsheet?

If I copy/paste the information into both cells my script runs correctly and matches the strings in the cells to the correct row for the user so I can lookup their email. If I let my google form fill the first cell however the data in the two cells no longer matches. I'm probably overlooking something obvious about comparing the strings but hopefully someone can point me in the right direction. Here is the code I have so far.
var rows = SpreadsheetApp.getActiveSheet().getLastRow();
var cell = SpreadsheetApp.getActiveSheet().getRange(rows, 2);
var value = cell.getValue().toString();
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheets()[1]);
var sheet;
var teacher;
var cc = "no match";
for(var h=1; h <= ss.getLastRow(); h++)
{
sheet = ss.getActiveSheet().getRange(h, 2);
teacher = sheet.getValue().toString();
if (value == teacher)
cc = ss.getActiveSheet().getRange(h, 1).getValue().toString();
}
Try to use watchdog (clicking on line number) or some message box to see what happens
i.e. Browser.msgBox(teacher); bebore testing the value of value ^^
and may be don t use the "value" as a variable name, it could generate problem to execute the script.

Categories