Google Apps Script: Retrieve Date from Spreadsheet and write to Contacts - google-apps-script

Using Google Apps script, I'm trying to take a date written in a spreadsheet and add it as a date field to a Contact. Specifically, I cannot seem to convert the month of the javascript date read from the spreadsheet into a month enum that the contact.addDate method can use.
var months = ContactsApp.Month.values;
var birthdate = new Date( spreadsheet_date );
var month = months[ birthdate.getMonth() ];
contact.addDate(ContactsApp.Field.BIRTHDAY,
month, birthdate.getDate(), birthdate.getFullYear() );

There are lots of ways to approach, as I see a switch is the easiest, there's no one-liner though, as there's no month name built into Javascript:
var month = birthdate.getMonth();
switch(month){
case 0:
month = ContactsApp.Month.JANUARY;
break;
case 1:
month = ContactsApp.Month.FEBRUARY;
break;
[...]
case 11:
month = ContactsApp.Month.DECEMBER
break;
}

another pattern...
var arr = [
CalendarApp.Month.JANUARY,
CalendarApp.Month.FEBRUARY,
CalendarApp.Month.MARCH,
...
];
var month = arr[birthdate.getMonth()];

See how I'm doing it in this post of a different question I have, here
Google Contact "Birthday" field not showing when set from Apps Script.
You need a mapping from the enum to the month name. This will avoid the long switch statement. This solution was initially provided to me by #tehhowch.

var month = months[ birthdate.getMonth() ];
var monthAsInt={JANUARY:1,FEBRUARY:2,MARCH:3,APRIL:4,MAY:5,JUNE:6,JULY:7
,AUGUST:8,SEPTEMBER:9,OCTOBER:10,NOVEMBER:11,DECEMBER:12}[month];
as a function;
function monthToInt(month) {
return {JANUARY:1,FEBRUARY:2,MARCH:3,APRIL:4,MAY:5,JUNE:6,JULY:7
,AUGUST:8,SEPTEMBER:9,OCTOBER:10,NOVEMBER:11,DECEMBER:12}[month];
}

Related

Price at Particular Date and Time

How to I query price at a particular date and time using Alphavantage API.
For eg: I tried this:
https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=^INFY&interval=1min&outputsize=compact&apikey=***********
However I want to pass both Date and Time and need the HIGH for that particular minute for that symbol.
I am using the Excel 365 Add-On but I can use Google Sheets as well.
Possible?
The url will give you a json. You have then to parse it and then apply a formula to retrieve the max value and date/hour/minute it occurs. To parse the json, try with your own api key :
function getAllDataJSON(code) {
var url = 'https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol='+code+'&interval=1min&apikey='+YOURAPIKEY
var data = JSON.parse(UrlFetchApp.fetch(url).getContentText())['Time Series (1min)']
var resultat = []
for (var elem in eval(data)){
resultat.push([elem,eval(data[elem]['1. open']),eval(data[elem]['2. high']),eval(data[elem]['3. low']),eval(data[elem]['4. close']),eval(data[elem]['5. volume'])])
}
return resultat
}
If you want extended period, the answer will be a csv file
function getAllDataCSV(code){
// last month : slice=year1month1 (by default) ... until slice=year2month12 (farthest month from today)
// interval : 1min
var url = 'https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY_EXTENDED&slice=year1month1&symbol='+code+'&interval=1min&apikey='+apikey
var csv = UrlFetchApp.fetch(url).getContentText();
return Utilities.parseCsv(csv)
}

APP-SCRIPT Condition to check if date entered is before today's date

var date = Utilities.formatDate(new Date(), "GMT-8", "m/dd/yyyy")
if (formS.getRange("B7").getValue() != " " && formS.getRange("B7").getValue() != date)
{
SpreadsheetApp.getUi().alert("Please Enter A Valid Date");
return
}
Trying to make the condition above check if the cell is not empty and that it does not contain a date prior to Today's Date
function myfunk() {
const ss = SpreadsheetApp.getActive();
const formS = ss.getSheetByName('formS');
const dtv = new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate()).valueOf();
if (!formS.getRange("B7").isBlank() && new Date(formS.getRange("B7").getValue()).valueOf() < dtv) {
SpreadsheetApp.getUi().alert("Please Enter A Valid Date");
return;
}
}
Checking Dates in Apps Script
In general you can use the Date object as you would in normal JavaScript code. There are just one main thing to bear in mind if your script needs to be sensitive to timezones.
The timezone is defined in the manifest:
This cannot be changed dynamically. So if you need to be sensitive to them, then you will need to manage the offsets in your code.
Your script
This line:
var date = Utilities.formatDate(new Date(), "GMT-8", "m/dd/yyyy")
Returns a string. Not a date object, so you can't compare it to another date object, such as what is returned from a sheet value if it is formatted as a date.
You could use Regex or split to get the year and month and compare it that way, but then you may run into issue when you use the script on the 1st of January. This is because by simply comparing the year, month and date of 31/12/2021 with 01/01/2022, then your conditional statements would be a bit tricky. Possible, but maybe a bit hard to read.
Initializing to midnight
What follows is one approach to take to carry out this comparison in a relatively simple way.
It seems convenient to get a date object initialized to 00:00:00 of today. Then you can quickly compare the date using Unix time.
var now = new Date()
now.setHours(0)
now.setMinutes(0)
now.setSeconds(0)
now.setMilliseconds(0)
You can also do this in a more concise way like this:
var now = new Date()
now.setHours(0,0,0,0);
Then you can use the getTime() method on the date objects to get Unic time in milliseconds and compare them.
var dateToCheck = formS.getRange("B7").getValue()
if (
!(dateToCheck instanceof Date) || // If value is not instance of a Date object
dateToCheck.getTime() <= now.getTime() // If date is before 00:00:00 today.
) {
SpreadsheetApp.getUi().alert("Please Enter A Valid Date");
return
}
}
Which seems like a concise way to do the comparison you are looking for.
References
Apps Script Dates
JS Date object

Google App Script Card Service datepicker returns strange value

I have a simple script that creates and a Gmail Add on. Using Card Service the user can enter values that once submitted send the values to a Google Sheet. Everything works fine accept the date field which returns values such as {msSinceEpoch=1.6145568E12}. Attempts to use Utilities.formatDate fails to rectify this the default value of '1/1/1970' is returned. It is not clear to me why this is the case?
The Card Service includes the following for the date field:
section.addWidget(CardService.newDatePicker().setValueInMsSinceEpoch(Date.now())
.setFieldName('fieldD')
.setTitle(date));
This is followed by a standard action:
var action = CardService.newAction()
.setFunctionName('enterAction');
And a function which inserts the values in the Google Sheet:
function enterAction(e) {
var sheet = SpreadsheetApp.openById("SheetID").getActiveSheet();
....
var inputValues5 = e.formInput['fieldD'];
...
var values = [.....[inputValues5],...];
sheet.getRange(sheet.getLastRow() + 1,1,1,7).setValues([values]);
Any help appreciated.
can you try it like this?
section.addWidget(CardService.newDatePicker().setValueInMsSinceEpoch(new Date())
.setFieldName('fieldD')
.setTitle(date));
or
let newDate = new Date();
section.addWidget(CardService.newDatePicker().setValueInMsSinceEpoch(newDate)
.setFieldName('fieldD')
.setTitle(date));
Also not sure about the .setValueInMsSinceEpoch(), is there another function you can call?
1.6145568E12 is March 1st 2021 in milliseconds since the epoch (this is the expected format). I don't see your code for the formatDate statement, but something like this should work:
var fieldD = e.formInput['fieldD'];
var inputDate = new Date(fieldD.meetingTime.msSinceEpoch);
var inputValues5 = Utilities.formatDate(inputDate,
e.userTimezone.id,
"MM/dd/yyyy HH:mm:ss");

Validate phonenumbers to specific format using Google Sheet formula

I'm working with google sheets and would like to convert US phone numbers to the format:
1xxxyyyzzzz
eg 402-333-4444 should be turned into 14023334444
I have an apps script validator function which does this:
var numbers = 'INVALID'
if ( parsed_body.hasOwnProperty('PHONE') ) {
var phone = parsed_body['PHONE'].toString();
Logger.log(parsed_body);
numbers = phone.replace(/[^0-9]/g, "");
var firstChar = numbers.charAt(0);
if ( firstChar !== '1'){ numbers = '1'+ numbers}
Logger.log(numbers);
if ( numbers.length !== 11){ numbers = 'NOTELEVEN'};
}
parsed_body['PHONE']=numbers;
but I'd like to make the sheet do this. Is this possible ?
It works out to quite a long formula if you do it in a single formula, because you have to keep repeating the previous steps, unlike in the script version:
=if(len(if(left(regexreplace(""&D2,"[^0-9]",""))="1","","1")&regexreplace(""&D2,"[^0-9]",""))=11,
if(left(regexreplace(""&D2,"[^0-9]",""))="1","","1")&regexreplace(""&D2,"[^0-9]",""),"INVALID")
May be changed to an array formula:
=ArrayFormula(if(D2:D="","",if(len(if(left(regexreplace(""&D2:D,"[^0-9]",""))="1","","1")&regexreplace(""&D2:D,"[^0-9]",""))=11,
if(left(regexreplace(""&D2:D,"[^0-9]",""))="1","","1")&regexreplace(""&D2:D,"[^0-9]",""),"INVALID")))

google apps script convert string to object

I have a question about the date convert:
in sheet, I have a date '05/11/2018', I need to get next date 06/11/2018.
var end=Utilities.formatDate(new Date(coach_date.getTime()+1*3600000*24), 'GMT', 'dd/MM/yyyy');
var start = new Date();
var events = calendar.getEvents(start,end);
it shows the 'end' is string, not object. it has to be getEvents(object,object)
so I used end = new Date(end); it got '11/06/2018', change month from Nov to June.
How could I fix it, then use it on getevents() feature.
Thanks a lot.
Utilities.formatDate() converts the date object into a string. So, use
var end = coach_date.setDate(coach_date.getDate()+1);