I want to know if there is a way, if there is something change in a specific cell automatic WhatsApp should send
First register in https://panel.rapiwha.com/landing/login.php.
Link your phone and get the API key from the web site.
Then try the below code in your Google Sheet.
//
function onEdit(e) {
var api_key="xxxxxxx"; //from the Rapiwah web site
var mob="919123456789"; // with country code without +
var s = e.source.getActiveSheet(), r ;
var shtn=s.getName();
if(shtn=="Plan") { //checks that we're on the correct sheet
r = e.range;
var old=e.oldValue;
var nval=r.getValue();
var linecol = r.getColumn();
var linerow = r.getRow();
if(linerow === 3 && linecol===4 ) { //checks the B3 cell was changed
var wpurl= 'https://panel.rapiwha.com/send_message.php?apikey='+api_key+'&number='+mob+'&text=Cell B3 in Plan Sheet changed from '+old+' to ' + nval;
var formurl3 = wpurl.replace(/#/g, "");
var formurl4 = formurl3.replace(/,/g, "");
var formurl = formurl4.replace(/ /g, "%20");
var response = UrlFetchApp.fetch(formurl);
}
}
}
//
Related
function getFirestore() {
var email="busdata-account#export-815a4.iam.gserviceaccount.com";
var key = "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDIBWAXxbEGco/p\nr6sEuBWiHJTayXcxD5bQjJNeMCHFnf3DlYxS9HPw3TG/vJBqwIMWKgd9waO9l4M1\nz3+P7obaOJ9OuwV30ZXrzE2F3+i8rnF009HxFGYIpHl3m6QffJ2nLnadfSik7HSv\nhDXHhQodgLkGidLXjLhPwb1hI7Cq96HFPPYqTu1oZqDgl9KMwyI+YgYIhoM+j4uo\n8nYkPErA2Q4hc3cI78Yl1mxAB5Ew1hnN8sPv3jtiXSm1irWI1MkITYcBteT9jRVm\ngR2Bvwu59XCqiX7jJ3fB41DpJcZq9oX6GpWfh846gKio0jaTGcjQx3SmlVUCEkgn\nIv/RKvy7AgMBAAECggEAYaqiQ6lPqa7Jz5jrwDektI4RLw2dihKrGPTzRlPpQaXG\nEbjVlnHvpOZU0uMff0i2GV33X3PsYHh5ZI6Hon+dUDPCsf5HCr0HX+ZX2i09Ztgk\n5R9CzV0g/0pUV09joc5G6qmY2IiTDoi45zT+z4gKKuK+Nc+ZaI+5NZSLxMFZE/lN\n2c6ANbDXA5aezAzit38LcAZ0QLp4VsOY4Hlh+JYjVrZNAbtllRYkuK7fq7bus+fs\nBbqWvKgqjChLwVu8efuUiOvN/kjV84TqRov9Kg7b+7ozl3HSYOfw6NTE9M/aZ54l\naav+YAnoBSWmgG2NuhOmzs2yFf1VctEmRxquKMZ1hQKBgQD0gCETgMxocFGedk1P\nxzL+0plIfnav9GK2n96Pi0rpnyId7xpDdVlfBnkwplgPHDELRIpdbPyjz4408Jn4\ndoV2jSsUKR4ziDxRos2MKFDqA7MJwLYgNa/1hqfpF8bbYR5g7vpPZyT3/gWC/Dni\nndUMIMq+ikxgv70RGXVSh21cLQKBgQDRbbKODtT03CIofDioLyCWsM/aoyvwvEQP\nBaCx7CkkpVXeuosHua9jUekfsSsbWwTGnuP9o5DDgpwkQVzNXIxZXm6rCVZP9PqC\n/mgKDRNAtfU5g07WWpoAbFiJ7b1nJQ40H+sifx5kucDz8DewMAZJdiwKHZ4a9RG9\nRfdEAYyFhwKBgDXGUIAHne2CdpERl+Np/m9JRmlJVzVP3L4p3ztW+Xz0gP5wbihU\nEPnzZIgsrcV0/9xokL4HkHE+3xoJqPOarbPrTIQ8nuXamtmhou+mllVBxwjoF6Zx\n6Gdp3FhJ4HSzoYjURr1cBCd++Rtb+ic7a3YlaDIMHMxSn3S5UrJ6ErVpAoGBALiN\n2/C1/1J8fxmARolnZmeFDtZUPs+ZiLxYMEE6pRMnJCHv777yEi4LK84C2cL0laPW\nt4F314WDHsgQVZCfgwrqXcoZo1c4wl4XhWV+Gj5HWv/AyAO7ucSvteJugB9aF0c1\n7Ybr0MPgsboGMXzxBUlNewe7C+4jkuthscHbP5MXAoGAUL6S6UEXvl1I1a3xbvHo\nv5wv+5fiP4ODq2XgNs6z4gFfTUrjb3CryHqg4I1OYPmq2d8UZ5mDkXPoSXmuz6Wr\nm57NW3d5Oio17vk2IXrzIFZ1MKEm8qu2aLzBCOEeY/fge6Lkyx0Z6ALpwbjPakZD\nrZLeFrU13pKQHKmLQknnoqk=\n-----END PRIVATE KEY-----\n";
var projectId = "export-815a4";;
return FirestoreApp.getFirestore(email,key,projectId);
}
function myFunction() {
const firestore=getFirestore();
var ss = SpreadSheetApp.getActiveSpreadsheet();
var sheetname = "busData";
var sheet = ss.getSheetByName(sheetname);
var lastRow = sheet.getLastRow();
var lastCol = sheet.getLastColumn();
var dataSR = 5;
var sheetRange = sheet.getRange(2,1,lastRow-dataSR+1,lastCol);
var sheetData = sheetRange.getValues();
var sourceLen = sheetData.length;
for(var i=0;i<sourceLen;i++){
if(sheetData[i][1] != ' '){
var data = {};
var sheetData = sheetRange[i][0];
data.place =sheetData[i][1];
data.busId= sheetData[i][2];
data.timeValue = sheetData[i][3];
data.hour = sheetData[i][4];
data.minute = sheetData[i][5];
data.slot = sheetData[i][6];
Logger.log(data);
firestore.createDocument("busData",data);
}
}
}
//enter image description here
//here is my excel sheet link: i am trying to load into firebase its giving an error //of semi-colomn but every semi-column is in its place . ac any one help.
//here is my excel sheet link:[text]//(https://docs.google.com/spreadsheets/d/1zVaLfQ1YC-aKJwzDAHmIBlzc2YfU4GpDnubBnNhOcRc/edit?usp=sharing)
Can anyone help me? I am doing this watching a Youtube video and I am a beginner.
I'm having some difficulty with the following formula in Google Scripts. What I would like to achieve, is:
1- get Number from A1
2- from Number, have multiple returns
3- set those returns in the same row (A) as original Number, in neighboring cells (A2, A3)
What it looks like now:
function GETALLTWO(bid) {
if (input.map) {
return input.map(GETALLTWO)
} else {
return input;
}
var api_str = "client_id=randomstringofnumbers&client_secret=anotherrandomstringofnumbers";
var url= "https://api.untappd.com/v4/beer/info/" + bid + "?" + api_str;
var response = UrlFetchApp.fetch(url);
if (response.getResponseCode() == 200) {
var respObj = JSON.parse(response.getContentText());
var beer = respObj.response.beer;
if (beer.bid == bid) {
return beer.beer_name;
return beer.rating_score;
return beer.stats.total_user_count;
return beer.rating_count;
return beer.stats.monthly_count;
return beer.created_at;
}
}
}
From Code.gs, I can get the first Return to work, but am I combining the different functions correctly? And how would I set the location to return?
Hope someone can help, would love to learn more about scripting.
// Edit for future reference:
function getAll(bid) {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Overview')
var row=sh.getActiveCell().getRow();
var bid=sh.getRange(row,3).getValue();
var api_str = "client_id=randomstring&client_secret=randomstring";
var url= "https://api.untappd.com/v4/beer/info/" + bid + "?" + api_str;
var response = UrlFetchApp.fetch(url);
if (response.getResponseCode() == 200) {
var respObj = JSON.parse(response.getContentText());
var beer = respObj.response.beer;
if (beer.bid == bid) {
var rObj= {name:beer.beer_name,rating:beer.rating_score,totalcount:beer.stats.total_user_count,ratingcount:beer.rating_count,monthlycount:beer.stats.monthly_count,createddate:beer.created_at};
values=[[rObj.name,rObj.ratingcount,rObj.rating,rObj.totalcount,rObj.monthlycount,rObj.createddate]];
return values;
}
}
}
With this function you just need to put your cursor on the row that you want to get the bid from. It will put the data back in that row starting at column D
function getAllTwo() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Your Sheet Name')
var row=sh.getActiveCell().getRow();
var bid=sh.getRange(row,3).getValue();
var api_str = "client_id=randomstringofnumbers&client_secret=anotherrandomstringofnumbers";
var url= "https://api.untappd.com/v4/beer/info/" + bid + "?" + api_str;
var response = UrlFetchApp.fetch(url);
if (response.getResponseCode() == 200) {
var respObj = JSON.parse(response.getContentText());
var beer = respObj.response.beer;
if (beer.bid == bid) {
var rObj= {name:beer.beer_name,rating:beer.rating_score,totalcount:beer.stats.total_user_count,ratingcount:beer.rating_count,monthlycount:beer.stats.monthly_count,createdate:beer.created_at};
values=[[rObj.name,rObj.ratingcount,rObj.rating,rObj.totalcount,rObj.monthlycount,rObj.createddate]];
sh.getRange(row,4,values.length,values[0].length).setValues(values);
}
}
}
EDIT: I need help combining functions into 1 and adding a trigger.
In my spreadsheet I have rows 4-100 for customer service calls that are filtered from a "ServiceData" worksheet by either choosing a "Service Month" or "Service Day" (ie. "7/11" shows only 5 rows where "July" would show 65 rows) . Each row item has corresponding Place IDs for origin/destination in column K and L with an order # (as in 1st, 2nd, 3rd... service call of the day) in column J .
TravelTime spreadsheet
I'm using the following custom function travelTime() in cells M4:M100 to calculate driving duration and distance between 2 place IDs:
function travelTime(origin,destination) {
var API_KEY = PropertiesService.getScriptProperties().getProperty('keyMaps');
var baseUrl = "https://maps.googleapis.com/maps/api/distancematrix/json? units=imperial&origins=";
var queryUrl = baseUrl + "place_id:" + origin + "&destinations=" +
"place_id:" + destination + "&mode=driving" + "&key=" + API_KEY;
var response = UrlFetchApp.fetch(queryUrl);
var json = response.getContentText();
var time = JSON.parse(json);
return [[ time.rows[0].elements[0].duration.text,
time.rows[0].elements[0].distance.text ]] ;
A major issue is that many unnecessary service calls are being made to the API when I'm making edits to the "ServiceData" spreadsheet (ie. service date changes when a particular day is over-scheduled) and not needing the travel time updated until I'm done working through a schedule .
After researching quite a bit there seems to be several options I could be using; caching, looping, arrays, and putting everything into a script then attach to a button to only run when ready. Considering I'm a newbie, putting all these options together are definitely beyond my skill level and could really use some help.
EDIT with new functions:
So after more researching I have been able to put together the following functions that when each are run independently work great. Now the problem I'm having is putting these all together in particular adjusting the original travelTime()into newTravelTime(). I have made an attempt towards the right direction below but can't figure out how to get the API call in there .
function newTravelTime() {//<--**having issues how to write this function
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheet = ss.getSheetByName("MonthlySA");
var sourceR = sourceSheet.getRange(4, 11, sourceSheet.getLastRow()-3, 4);
var sourceV = sourceR.getValues();
var array = [];
for (var i = 0; i < sourceV.length; i++) {
if (sourceV[i][2] == "") {
var origin = sourceV[i][0];//ori place IDs for API query
var destination = sourceV[i][1];//des place IDs API api query
}
array.push([sourceV[i][2]]);
}
sourceSheet.getRange(4, 13, array.length, 1).setValues(array);
I'd like to create a final getTravelTime() with all the functions and add an OnEdit trigger when either "Service Month" or "Service Day" changes in cells B1 or B2 to run them. If there is any advice with my functions themselves I would really appreciate some help, I am very new with this and trying.
///checks if origin/destination are already in the cacheSheet then return travel time to sourceSheet
function getCachedTravelTime() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheet = ss.getSheetByName("MonthlySA");
var sourceR = sourceSheet.getRange(4, 11, sourceSheet.getLastRow()-3, 4);
var sourceV = sourceR.getValues();
var cacheSheet = ss.getSheetByName("TravelTimeCache");
var cacheR = cacheSheet.getRange(2, 1, cacheSheet.getLastRow()-1, 4);
var cacheV = cacheR.getValues();
var array = [];
for (var i = 0; i < sourceV.length; i++) {
for (var j = 0; j < cacheV.length; j++) {
//if origin/destination columns from sourceSheet match columns on cacheSheet
if (sourceV[i][0]+sourceV[i][1] == cacheV[j][0]+cacheV[j][1]) {
sourceV[i][2] = cacheV[j][2]; //column with travel duration
sourceV[i][3] = cacheV[j][3]; //column with travel distance
}
}
array.push([sourceV[i][2], sourceV[i][3]]);
}
sourceSheet.getRange(4, 13, array.length, 2).setValues(array);
}
///if origin or destination are blank, label as 'missing value'
function missingOD() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheet = ss.getSheetByName("MonthlySA");
var sourceID = sourceSheet.getRange(4, 3, sourceSheet.getLastRow()-3, 12);
var sourceV = sourceID.getValues();
var array = [];
for (var i = 0; i < sourceV.length; i++) {
// if ID has a value
if (sourceV[i][0] != "") {
// if origin or destination is blank
if (sourceV[i][8] == "" || sourceV[i][9] == "") {
sourceV[i][10] = 'missing value';
}
}
array.push([sourceV[i][10]]);
}
sourceSheet.getRange(4, 13, array.length, 1).setValues(array);
}
///if cache not found - get the new travelTime for that origin/destination on sourceSheet...
function newTravelTime() {//<--
}
///...and store the new travelTime() in cacheSheet
function storeTravelTime() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheet = ss.getSheetByName("MonthlySA");
var sourceR = sourceSheet.getRange(4, 11, sourceSheet.getLastRow()-3, 4);
var sourceV = sourceR.getValues();
var cacheSheet = ss.getSheetByName("TravelTimeCache");
var cacheR = cacheSheet.getRange(2, 1, cacheSheet.getLastRow()-1, 4);
var cacheV = cacheR.getValues();
var array = [];
for (var i = 0; i < sourceV.length; i++) {
var duplicate = false;
for (var j = 0; j < cacheV.length; j++) {
if (sourceV[i][0]+sourceV[i][1] == cacheV[j][0]+cacheV[j][1]) {
duplicate = true;
}
}
if(!duplicate){ //if origin/destination columns from sourceSheet are NOT matched on cacheSheet
array.push([sourceV[i][0], sourceV[i][1], sourceV[i][2], sourceV[i][3]]);//columns with new data
}
}
//add new data to last row of cacheSheet
cacheSheet.getRange(cacheSheet.getLastRow()+1, 1, array.length, 4).setValues(array);
}
One of the easiest solution thats coming to mind is Caching. Instead of making API calls everytime check if we have already made that call previously.
Something like this
function getTravelTime(origin, destination) {
var travelTime = getTravelTimeFromPreviousCall(origin, destination);
if (travelTime != null) {
return travelTime;
} else {
var travelTime = fetchTravelTime(origin, destination);
storeTravelTime(origin, destination, travelTime);
return travelTime;
}
}
function fetchTravelTime(origin, destination) {
var API_KEY = PropertiesService.getScriptProperties().getProperty('keyMaps');
var baseUrl = "https://maps.googleapis.com/maps/api/distancematrix/json? units=imperial&origins=";
var queryUrl = baseUrl + "place_id:" + origin + "&destinations=" + "place_id:" + destination + "&mode=driving" + "&key=" + API_KEY;
var response = UrlFetchApp.fetch(queryUrl);
var json = response.getContentText();
var time = JSON.parse(json);
return time.rows[0].elements[0].duration.text;
}
For this we can define our cache something like :
A sheet with column -
origin
destination
travel time
And we need to define following functions:
getTravelTimeFromPreviousCall(origin, destination) : In this we need to check cache and return travel time for that origin & destination, if not found then return null
storeTravelTime(origin, destination, time) : This will only store travel time for future use in cache sheet
You can try something like this :
function getTravelTimeFromPreviousCall(origin, destination) {
var cacheSheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(CACHE_SHEET_NAME);
var cacheData = sheet.getDataRange().getValues();
for (var i=0; i<cacheData.length; i++) {
if (cacheData[i][ORIGIN_COLUMN_INDEX]==origin && cacheData[i][DESTINATION_COLUMN_INDEX]==destination) {
return cacheData[i][TRAVEL_TIME_COLUMN_INDEX];
}
}
return null;
}
function storeTravelTime(origin, destination, travelTime) {
var cacheSheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(CACHE_SHEET_NAME);
sheet.appendRow([origin, destination, travelTime]);
}
Please fix loop variable, array indexes & constants, as per your sheet.
NEEDLES TO SAY, I am very new to this, but trying my hardest to figure all this out. I have a script right now which actively removes all empty rows from an entire workbook. But I'm hoping someone can assist is narrowing this down to a single sheet within that workbook.
function removeEmptyRows() {
SpreadsheetApp.getActive()
.getSheets()
.forEach(function (s) {
c = 0;
s.getRange(1, 1, s.getMaxRows(), s.getMaxColumns())
.getValues()
.forEach(function (r, j) {
if (r.toString()
.replace(/,/g, "")
.length == 0) {
s.deleteRow((j += 1) - c)
c += 1;
}
})
})
}
Ideally I would like for this to remove only blank rows on one sheet within my workbook called 'Racing Results'. The reason I'm need this, is due to how the spreadsheet is setup and having multiple rows merged together. So when I copy these results over to a different sheet, there are gaps between them and I'd like them removed. Here is the script I'm using to copy the data to another sheet.
function Copy() {
var sss = SpreadsheetApp.openById('18cl69Id4saI455wk__-PhvfxXZa7iWlQpoiRKqBz6bU');
var ss = sss.getSheetByName('Score Card');
var range = ss.getRange('A32:E36');
var data = range.getValues();
var tss = SpreadsheetApp.openById('18cl69Id4saI455wk__-PhvfxXZa7iWlQpoiRKqBz6bU');
var ts = tss.getSheetByName('Race Results');
ts.getRange(ts.getLastRow()+1, 1, data.length, data[0].length).setValues(data);
}
If not to throw one final monkey wrench into this colossal mess, I have been attempting to copy two different cell ranges within the same script and I feel like this isn't possible because only the latter one gets copied and the initial one is discarded. Here is the other copy script I am using which runs before the one above this.
function Copy() {
var sss = SpreadsheetApp.openById('18cl69Id4saI455wk__-PhvfxXZa7iWlQpoiRKqBz6bU');
var ss = sss.getSheetByName('Score Card');
var range = ss.getRange('A1:A1');
var data = range.getValues();
var tss = SpreadsheetApp.openById('18cl69Id4saI455wk__-PhvfxXZa7iWlQpoiRKqBz6bU');
var ts = tss.getSheetByName('Race Results');
ts.getRange(ts.getLastRow()+1, 1, data.length, data[0].length).setValues(data);
}
Score Card Screenshot
In a perfect world, what I'm trying to get setup is the following. Above is a screenshot of the scorecard we are using. I am wanting to copy the Current Date (A1) to the 'Racing Results' sheet, then I want to copy the final score with the team names (A32:E36) and move them to the 'Racing Results' sheet right under it. Once that has been done, I want to remove the empty rows between the results because as of right now this is how it looks when copying over. (see image below)
Race Results Screenshot
Thanks in advance to anyone who is able to assist with any of this in any way shape or form.
Edit:
Removing Empty Rows from a spreadsheet is functioning as intended. Still having issues with Copying multiple times in the same action even when giving them different names. Here is my updated script.
function CopyDate() {
var sss = SpreadsheetApp.openById('18cl69Id4saI455wk__-PhvfxXZa7iWlQpoiRKqBz6bU');
var ss = sss.getSheetByName('Score Card');
var range = ss.getRange('A1:A1');//This range is only one cell
var data = range.getValues();
var tss = SpreadsheetApp.openById('18cl69Id4saI455wk__-PhvfxXZa7iWlQpoiRKqBz6bU');
var ts = tss.getSheetByName('Race Results');
ts.getRange(ts.getLastRow()+1, 1, data.length, data[0].length).setValues(data);
}
function CopyScore() {
var sss = SpreadsheetApp.openById('18cl69Id4saI455wk__-PhvfxXZa7iWlQpoiRKqBz6bU');
var ss = sss.getSheetByName('Score Card');
var range = ss.getRange('A32:E36');
var data = range.getValues();
var tss = SpreadsheetApp.openById('18cl69Id4saI455wk__-PhvfxXZa7iWlQpoiRKqBz6bU');
var ts = tss.getSheetByName('Race Results');
ts.getRange(ts.getLastRow()+1, 1, data.length, data[0].length).setValues(data);
}
function delBlankRows(shtname){
var shtname=shtname || 'Race Results';
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName(shtname);
var rg=sh.getRange(1,1,sh.getMaxRows(),sh.getLastColumn());
var vA=rg.getValues();
var n=0;
for(var i=0;i<vA.length;i++){
if(!vA[i].join("")){
sh.deleteRow(i-n+1);
n++;
}
}
}
function Sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
function SaveRaceResults() {
CopyDate();
Sleep(5000);
CopyScore();
Sleep(5000);
delBlankRows();
}
Deleting All Blank Rows on a Sheet
function delBlankRows(shtname){
var shtname=shtname || 'Sheet1';
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName(shtname);
var rg=sh.getRange(1,1,sh.getMaxRows(),sh.getLastColumn());
var vA=rg.getValues();
var n=0;
for(var i=0;i<vA.length;i++){
if(!vA[i].join("")){
sh.deleteRow(i-n+1);
n++;
}
}
}
Copy function:
function Copy() {
var sss = SpreadsheetApp.getActive();
var ss1 = sss.getSheetByName('Score Card');
var range1 = ss1.getRange('A1');//This range is only one cell
var data1 = range1.getValues();
var ts1 = sss.getSheetByName('Race Results');
ts1.getRange(ts1.getLastRow()+1, 1, data1.length, data1[0].length).setValues(data1);
var ss2 = sss.getSheetByName('Score Card');
var range2 = ss2.getRange('A32:E36');
var data2 = range2.getValues();
var ts2 = sss.getSheetByName('Race Results');
ts2.getRange(ts2.getLastRow()+1, 1, data2.length, data2[0].length).setValues(data2);
}
I'm learning Google Apps Scripts for use with Google Spreadsheets.
I have a list of URLs in one column and I want to write a script to get the title element from each URL and write it in the adjacent cell. I have accomplished this for one specific cell as per the following script:
function getTitles() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("url_list");
var range = sheet.getRange("G3");
var url = range.getValue();
var response = UrlFetchApp.fetch(url);
var doc = Xml.parse(response.getContentText(),true);
var title = doc.html.head.title.getText();
var output = sheet.getRange("H3").setValue(title);
Logger.log(title);
return title;
}
This gets the URL in G3, parses it, pulls the element and writes the output in H3.
Now that I have this basic building block I want to loop the entire G column and write the output to the adjacent cell but I'm stuck. Can anyone point me in the right direction?
May look something like this:
function getTitles() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("url_list");
var urls = sheet.getRange("G3:G").getValues();
var titleList = [], newValues = [],
response, doc, title;
for (var row = 0, var len = urls.length; row < len; row++) {
if (urls[row] != '') {
response = UrlFetchApp.fetch(urls[row]);
doc = Xml.parse(response.getContentText(),true);
title = doc.html.head.title.getText();
newValues.push([title]);
titleList.push(title);
Logger.log(title);
} else newValues.push([]);
}
Logger.log('newValues ' + newValues);
Logger.log('titleList ' + titleList);
// SET NEW COLUMN VALUES ALL AT ONCE!
sheet.getRange("H3").offset(0, 0, newValues.length).setValues(newValues);
return titleList;
}