Sei sulla pagina 1di 131

2014

Jos Julin Ariza Valderrama


+10y Aplications Developer
Madrid - Spain
josejariza@gmail.com
http://jjdrone.blogspot.com.es

@JJArizaV
@impactotecno
https://www.youtube.com/user/jjdroneariza

I'm a Senior software developer with 10-years background in the technology


industry.
My strong experience is working with java in different levels like front-end,
back-end, mobile (Android), social network interaction and database
connections.
I like to work with high-end technology this the why I was working with NoSQL
dbs, raspberry pi devices and other nice technologies... like drones! I can fly it!

https://www.youtube.com/watch?v=15zSL5infoc

Google Apps es un paquete de productividad basado en la


nube
Aplicaciones

Gmail
Calendario
Drive
Gtalk
Sites

Google Apps Script te permite extender la experiencia de


uso de Google Apps
Lenguaje de scripting basado en la nube que ofrece
maneras fciles de automatizar las tareas a travs de
productos de Google y servicios de terceros
Liberado desde 2009
Basado en JavaScript, sintaxis muy similar y fcil de
aprender
Google Apps Script utiliza el Google Web Toolkit (GWT) para
crear y mostrar los elementos de la interfaz de usuario.
Google Web Toolkit es fcil de aprender, y completamente
abstrae la complejidad de AJAX / HTML.

Una manera fcil de automatizar tareas en los productos


de Google
Javascript pero no en el navegador
Editor en browser, almacenadas y compartidas
Runtime de Javascript en la nube
Conjunto de APIs y puntos de entrada a mltiples
productos de google.

Es compatible con 11 Google Apps como inicio, pero


adems ofrece comunicarnos con servicios avanzados como
Analytics, BigQuery, Youtube, Prediction API, AdSense u
otros servicios externos ajenos a Google como JDBC, SOAP,
XML y URL Fecth.
Basado en la nube, tenemos las herramientas de desarrollo
como el debbuguer en el propio navegador web, todo de
manera online.
Puede ser utilizado para crear herramientas sencillas para el
consumo interno de una organizacin, realizar tareas
simples de administracin del sistema, as como tareas mas
complejas, pero de forma muy sencilla

Dashboard

https://script.google.com/dashboard

Automatizar tareas repetitivas y flujos de trabajo


Automatizar aprobaciones de gastos, gestin de la compra
de entradas de pedidos
Enlace productos de Google con los servicios de terceros
Crear funciones personalizadas de hoja de clculo
Construir ricas interfaces grficas de usuario y los mens
Casi todo", es de uso libre y gratuito

Tener una cuenta google


Acceso a internet
Usar un navegador que soporte Javascript, de preferencia
Google Chrome

Google desarroll este navegador teniendo por objetivos


ser seguro, rpido, sencillo y estable. Google Chrome se
diferencia de sus competidores por su interfaz de usuario
sencilla, minimalista. En cuanto a velocidad Google Chrome
goza de la fama de ser el ms rpido procesando cdigo
de JavaScript, que es frecuentemente usado en pginas
web.

El inspector de elementos es una herramienta genial


para resolver problemas de diseo. Hay varios
exploradores que la tienen, este tutorial utilizar el
inspector de elementos de Google Chrome. Para usar el
inspector de elementos hay 2 formas:
F12
O hacer click segundario encima de cualquier elemento de una
pagina web

El inspector de elementos se abrir por defecto abajo de la


pantalla. En el lado izquierdo est el HTML de la pgina. Si
pasan el cursor por el HTML se va a destacar en la pgina
web visualizada en el navegador el elemento que
corresponde. Esto sirve para que puedan reconocer cual
elemento van a editar.
El inspector de elementos sirve para muchsimas cosas

Descubrir errores
Reutilizar atributos CSS
Modificar la apariencia de elementos
Reutilizar selectores CSS

Los cambios que se hacen en el Inspector de Elementos no


se guardan, por lo que al recargar la pagina, toda la
apariencia volver a como estaba
Imaginemos un problema:
hay un problema en mi cdigo css: tiene una imagen de fondo que
no se est cargando.

Para solucionar este problema abrimos el Inspector de


Elementos, apretando F12 o haciendo click con el botn
secundario. Cuando se abra el Inspector de Elementos
vamos a seleccionar la consola (Console).

En la consola podemos ver que el error es que el archivo no


est encontrado. Entonces hay que revisar la ruta del
archivo

Ejemplo prctico:
Vamos a cambiar el logo de Google en www.google.es al logo de
nuestra empresa

JavaScript dispone de fuertes capacidades de programacin


orientada a objetos
La programacin orientada a objetos es un paradigma de
programacin que utiliza la abstraccin para crear modelos
basados en el mundo real
La programacin orientada a objetos puede considerarse
como el diseo de software a travs de una conjunto de
objetos que cooperan, a diferencia de un punto de vista
tradicional en el que un programa puede considerarse
como un conjunto de funciones, o simplemente como una
lista de instrucciones

En la programacin orientada a objetos, cada objeto es


capaz de recibir mensajes, procesar datos y enviar mensajes
a otros objetos
Cada objeto puede verse como una pequea mquina
independiente con un papel o responsabilidad definida
El cdigo orientado al objetos est concebido para ser ms
fcil de desarrollar y ms fcil de entender posteriormente,
prestndose a un anlisis ms directo, a una mayor
codificacin y comprensin de situaciones y procedimientos
complejos que otros mtodos de programacin menos
modulares

Terminologa

Clase: Define las caractersticas del Objeto


Objeto: Una instancia de una Clase
Constructor: Un mtodo llamado en el momento de la instanciacin
Propiedad: Una caracterstica del Objeto, como el color
Mtodo o funcin: Una capacidad del Objeto, como caminar
Herencia: Una Clase puede heredar caractersticas de otra Clase
Encapsulamiento: Una Clase slo define las caractersticas del
Objeto, un Mtodo slo define cmo se ejecuta el Mtodo

Funciones

Una funcin con nombre es aquella a la que se hace referencia


en el script antes o despus de definirla, mientras que
una funcin annima es una funcin sin nombre que hace
referencia a ella misma; se hace referencia a la funcin annima
al crearla.
Las funciones annimas se utilizan habitualmente al manipular
controladores de eventos. Para escribir una funcin annima,
puede almacenarse un literal de funcin dentro de una variable.
Por consiguiente, posteriormente podr hacer referencia a la
funcin en el cdigo.

Funciones anonimas

var myWidth = function () {


trace(my_mc._width);
};
//posteriormente en el cdigo:

myWidth();

Estndares de codificacin

Sangra
La unidad de sangra es de cuatro espacios. El uso de
pestaas debe ser evitada porque todava no hay un
estndar para el tamao de los tabuladores. El uso de
espacios puede producir un tamao de archivo ms grande,
pero el tamao no es significativo sobre las redes locales, y
la diferencia se elimina por minificacin.

Estndares de codificacin

Longitud de la lnea
Evite lneas de ms de 80 caracteres. Cuando una
instruccin no cabe en una sola lnea, puede ser necesario
para separarla.
Coloque el espacio en blanco despus de un operador,
idealmente despus de una coma. Un espacio en blanco
despus de un operador disminuye la probabilidad de que
un error al reutilizar el script.

Estndares de codificacin

Comentarios
Sea generoso con sus comentarios. Es conveniente dejar la
informacin que ser leda posteriormente por personas
(posiblemente usted) que se necesitan para comprender lo que ha
hecho. Los comentarios deben estar bien escritos y ser claros, al igual
que el cdigo que estn anotando. Una punto de humor ocasional
puede ser apreciado. Las frustraciones y resentimientos no.
Es importante que los comentarios se mantegan al da. Comentarios
errneos pueden hacer que los programas an ms difcil de leer y
entender.
Haga comentarios significativos. Concntrese en lo que no es
inmediatamente visible.

Estndares de codificacin

Declaraciones de variables
Todas las variables deben ser declaradas antes de utilizar.
JavaScript no requiere esto, pero esto hace que el programa
sea ms fcil de leer y hace que sea ms fcil detectar las
variables no declaradas que pueden convertirse en
variables globales implcitas.
Se prefiere que cada variable se le dar su propia lnea y
comentario. Ellos deben ser listadas en orden alfabtico.

Estndares de codificacin

Declaraciones de funcin
Todas las funciones deben ser declaradas antes de ser utilizado.
Funciones internas deben seguir la declaracin var. Esto ayuda a
aclarar qu variables se incluyen en su mbito de aplicacin.
No debe haber ningn espacio entre el nombre de una funcin y
el parntesis izquierdo de su lista de parmetros. Debe haber un
espacio entre el parntesis derecho y la llave izquierda que
empieza de que el cuerpo de la instruccin. El propio cuerpo
debe separarse con cuatro espacios. La llave de cierre est
alineada con la lnea que contiene el principio de la declaracin
de la funcin.

Estndares de codificacin

Nombres
Los nombres deben formarse a partir maysculas y minsculas
(A .. Z, a .. z), los 10 dgitos (0 .. 9) y _ (guin bajo). Evite el uso
de caracteres internacionales, ya que no pueden leer bien o
entender en todas partes. No utilice $ (signo de dlar) o \ (barra
invertida) en los nombres.
No utilice _ (subrayado) como el primer carcter de un nombre.
A veces se usa para indicar la privacidad, pero en realidad no
ofrecen privacidad..
La mayora de las variables y funciones deben empezar con una
letra minscula, se recomienda usar camelCase

JavaScript tiene varios objetos incluidos en su ncleo, como


Math, Object, Array y String
Ejemplo 1:

<html>
<body>
<h3> Hola mundo JS </h3>
<script language=javascript>
alert (Math.random ());
</script>
</body>
</html>

Clase con propiedad y constructor

function Person(gender) {
this.gender = gender;
alert('Person instantiated');
}
var person1 = new Person('Hombre');
var person2 = new Person('Mujer');
alert ('person1 is a' + person1.gender);

Acrnimo de JavaScript Object Notation, es un formato


ligero para el intercambio de datos

{
"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [ {"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}
}

JSON Object a partir de String:

var the_object = eval("(" + myJson + ")");


alert (the_object.menu.id);

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<section id="tests">
<h1>Tutorial JSON (JavaScript Object Notation)</h1>
<div id="content" >
</div>
</section>
<script type="text/javascript">
var objetos = {"Personas":[
{"nombre":Jose","edad":23},
{"nombre":Julian","edad":17}
]};

document.getElementById('content').innerHTML =
objetos.Personas[1].nombre ;
/*Declarar un objeto JSON con una funcion en un atributo
notese el uso de "this" que hace referencia a el objeto en s, es decir a
persona*/
var persona = {"name":Otra persona","edad":23,
"avisar":function(){alert("Hola soy
"+this.name);}
};

persona.avisar();
</script>
</body>
</html>

El inters de los scripts JavaScript reside en gestionar


localmente los eventos detectados. Los eventos son el
resultado de una accin del usuario. Por ejemplo, hacer clic
sobre un botn o seleccionar un campo de un formulario
son eventos.
La importancia de los eventos radica en que nos posibilita
modificar el contenido de un documento HTML sin
intercambio de datos a travs de la red

La gestin de eventos se efecta mediante scripts


ejecutados automticamente cuando se produce un evento
dado.
Tiene 3 elementos principales
Listener
Handlers
Callbacks

MailApp:
https://developers.google.com/apps-script/reference/mail/mailapp
Los mails se envan a nombre de quien hizo el script
Hay un lmite diario de envos de mails impuesto por Google
Mtodos:

getRemainingDailyQuota()
sendEmail(message)
sendEmail(recipient, subject, body)
sendEmail(recipient, subject, body, options)
sendEmail(to, replyTo, subject, body)

UiApp
Crea interfaces de usuario para su uso dentro de Google
Apps o como servicios independientes.
Mtodos
createApplication()
getActiveApplication()
getUserAgent()

Widgets: componentes de una interfaz de usuario:

Textbox
Label
Buttons
Check box
Radio buttons
Text Area

Panels: Permiten organizar los widgets en una ventana


Logger nos permite aadir losgs a nuestros scripts
Logger.log('A test of the Log');

Cuadro de dialogo simple

Texto

Button

Para generar nuestro primer Script nos dirigimos a Google Drive,


de ah elegimos la opcin de Script (Si no aparece, ve a la parte
de abajo que dice Connect more Apps y busca Script)
De inmediato, se mostrar una pantalla con algunas opciones
para crear un Script, unos siendo plantillas, otros tutoriales, en
todos los ejemplos nosotros crearemos un proyecto desde cero
En la vista general del editor, tendremos las opciones
suficientes para trabajar con nuestros scripts, como debugger y
autocompletado (Los mtodos estan descritos en la
documentacin oficial: developers.google.com/appsscript/reference/spreadsheet/)

El siguiente cdigo, nos permite crear un documento


que se llame Hola mundo de AppScript con un
cuerpo de mensaje Este Documento fue creado a
partir de AppScript, adems que la URL del
documento la mandamos a un correo electrnico, en
este ejemplo en particular lo manda al email del
usuario que edita el Script

function createAndSendDocument() {
//Crear un nuevo Documento de Nombre Hola Mundo de AppScript
var doc = DocumentApp.create('Hola Mundo de AppScript');
//Obtenemos el Body del Documento y agregamos un Parrafo
doc.getBody().appendParagraph('Este Documento fue creado a Partir de AppScript');
//URL del Documento Generado
var url = doc.getUrl();
//Obtenemos nuestro Correo Electronico
var email = Session.getActiveUser().getEmail();
//El asunto es el nombre del Documento
var subject = doc.getName();
//El cuerpo del correo max 20kb indica la URL de nuestro documento
var body = 'Link con tu Documento: ' + url;
//Enviamos el correo (:
GmailApp.sendEmail(email, subject, body);
}

Para correr el script nos dirigimos a la barra superior del


editor. El botn en forma de Play ser el encargado de
correr el script, seguido tambin tenemos la opcin de
correr en modo Debugger (los breakpoints se agregan
dando click en donde aparece el nmero de lnea) y el
selector de la parte derecha, que en este caso solo contiene
createAndSendDocument, servir para correr la funcin
que queramos (en este caso solo tenemos una, pero
pueden ser n).

La primera vez que lo corremos, por seguridad, se pide


autorizacin a la cuenta que cre el script, esto para que
solo el dueo de la cuenta sea el encargado de manejar el
script.

Vamos a ver como actualizar dinmicamente elementos de


nuestra propia aplicacin google script

Crearemos una sencilla calculadora de sumas para ver como


se actualiza dinamicamente el campo de resultados

function doGet() {
var app = UiApp.createApplication().setTitle('Change Box');
var horizontalPanel = app.createHorizontalPanel().setId('horizontalPanel');
app.add(horizontalPanel);
horizontalPanel.add(app.createTextBox().setId('textBox1')
.setName('textBox1').setWidth('25px')

.addKeyUpHandler(app.createServerKeyHandler('changeBox')
.addCallbackElement(horizontalPanel)));
horizontalPanel.add(app.createLabel(' + '));

horizontalPanel.add(app.createTextBox().setId('textBox2')
.setName('textBox2').setWidth('25px')
.addKeyUpHandler(app.createServerKeyHandler('changeBox')
.addCallbackElement(horizontalPanel)));
horizontalPanel.add(app.createLabel(' = '));
horizontalPanel.add(app.createTextBox().setId('textBox3')

.setName('textBox3').setWidth('25px'));
return app;
}

function changeBox(e){
var app = UiApp.createApplication();
if(e.parameter.textBox1 !='' && e.parameter.textBox2 !=''){
// && e.parameter.keyCode == 13
var tb3 = parseInt(e.parameter.textBox1) + parseInt(e.parameter.textBox2);
app.getElementById('textBox3').setValue(tb3.toString());
}

return app;
}

Google Script puede usarse desde las propias aplicaciones


Google, por ejemplo Spreadsheet o Documents
GAS nos permite crear aplicaciones basandonos en un
archivo html que creamos a nuestro gusto y luego podemos
publicar en las aplicaciones Google
La clase HtmlService nos permite levantar el archivo html
para presentarlo como una web
Veamos el ejemplo

Primero creamos un nuevo Document


Estando en l vamos al men Herramientas -> Scripts
Creamos un nuevo proyecto
Aadimos un nuevo Html file desde el men File y
personalizamos el contenido a nuestro gusto
Vamos al script Code.gs y le aadimos contenido:

function htmlServiceTest() {
// obtenemos la instancia de la app Documents
var ui = DocumentApp.getUi();
// cargamos el template de nombre 'sideBar' y
aadimos detalles
var html =
HtmlService.createTemplateFromFile('sideBar').eva
luate()
.setTitle('Sidebar Example').setWidth(300)
.setSandboxMode(HtmlService.SandboxMode.NATIVE);
// presentamos el archivo
ui.showSidebar(html);
}

Spreadsheet Veamos un primer ejemplo:

Crear una nueva spreadsheet

Poner nombre a nuestra hoja


Crear un nuevo script: men tools -> Script Editor
Seleccionar: Black Project
Crear una nueva funcin: mostrarDialogo()
Obtener objeto principal de la aplicacin:
var app = UiApp.createApplication();

Crear un panel:
var panel = app.createVerticalPanel();

Aadir widgets:
var textBox = app.createTextBox();
textBox.setName('myTextBox').setId('myTextBox');
var button = app.createButton('Submit');

Aadir al panel:
panel.add(textBox);
panel.add(button);

Aadir gestin de eventos.

Aadir gestin de eventos.


var clickHandler =
app.createServerClickHandler("respondToSubmit");
button.addClickHandler(clickHandler);
clickHandler.addCallbackElement(panel);

Ensamblar
app.add(panel);
var doc = SpreadsheetApp.getActive();
doc.show(app); // mostrar la app

Crear funcin de click handler: function respondToSubmit(e)


Obtener la aplicacin activa
var app = UiApp.getActiveApplication();

Obtener el valor del campo de texto:


var textBoxValue = e.parameter.myTextBox;

Obtener la hoja activa


var sheet = SpreadsheetApp.getActiveSheet();

Aadir los datos obtenidos en la ltima fila:


var lastRow = sheet.getLastRow()+1;
var lastCell = sheet.getRange("A"+lastRow);
lastCell.setValue(textBoxValue);

Cerrar la aplicacin
return app.close();

A probar!!!

Ejecutar aplicaciones hechas en Google Script solicita


autorizacin de ejecucin
La autorizacin se vincula a la cuenta del usuario en
ejecucin

Hagamos un segundo ejemplo creando un grfico de


manera dinmica leyendo datos de un spreadsheet
Demos crear un spreadsheet con los datos a usar
Finalmente publicaremos el script como una web

function doGet(){
// Leer la data de un spreadsheet
var SS = SpreadsheetApp.openById('SpreadsheetID');
var sheet = SS.getSheets()[0];
var data = sheet.getRange('A1:G7').getValues();
// construir tabla
var dataTable = Charts.newDataTable();
//Aadir tipos de dolumnas
dataTable.addColumn(Charts.ColumnType.STRING,
data[0][0]);
for(var i=1; i<data[0].length-1; i++){
dataTable.addColumn(Charts.ColumnType.NUMBER,
data[0][i]);
}

// Aadir filas
for(var j=1; j<data.length; j++){
dataTable.addRow(data[j]);
}
// Crear y construir grfico
var chart = Charts.newPieChart()
.setDataTable(dataTable)
.setTitle("Sales by store")
.build();
//Crear aplicacin y aadir el grfico
var app =
UiApp.createApplication().setTitle("Grfico");
app.add(chart)
return app;
}

Vamos a interactuar con directamente con Google Drive


subiendo un archivo a nuestra DocList

function doGet(e) {
var app = UiApp.createApplication().setTitle("Upload archivo");
var form =
app.createFormPanel().setId('frm').setEncoding('multipart/form-data');
var formContent = app.createVerticalPanel();
form.add(formContent);
formContent.add(app.createFileUpload().setName('thefile'));
formContent.add(app.createSubmitButton('Submit'));
app.add(form);
return app;
}
function doPost(e) {
// Objeto blob del input file
var fileBlob = e.parameter.thefile;
var doc = DocsList.createFile(fileBlob);
var app = UiApp.getActiveApplication();
var label = app.createLabel('Archivo cargado');
app.add(label);
return app;
}

Vamos a crear un script que dada una direccin nos


devuelva la latitud y longitud
Paso 1: crear un spreadsheet con una direccin lo ms
precisa posible
Paso 2: crear el siguiente script

function geocode_Addresses() {
var sheet =
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet4");
var locationInfo = sheet.getRange("A2").getValues();
var geoResults, lat, lng;
for (var i = 0; i < locationInfo.length; i++) {
geoResults = Maps.newGeocoder().geocode(locationInfo[i]);
// obtener latitud and longitud
lat = geoResults.results[0].geometry.location.lat;
lng = geoResults.results[0].geometry.location.lng;
sheet.getRange(i+1, 2, 1, 1).setValue(lat + "," + lng);
Utilities.sleep(1000);
// aade un delay para prevenir
restriccin de google: Service Invoked Too Many Times
}
}

A partir de una Google Form formaremos una base de


usuarios (Nombre, Apellido, Departamento, Correo), una
vez que dichos usuarios estn en la spreadsheet se les
notificar mediante correo electrnico su registro exitoso,
pero dicha confirmacin ser a partir de una plantilla hecha
en Document que sustituir los datos de acuerdo a cada
usuario.
Ser requerido el nombre, apellido y correo. Adems el
correo debe tener formato vlido

Paso 1

Lo primero que tenemos que hacer es un Form desde


GDrive, que contendr los campos definidos previamente
aadiendo sus validaciones

Paso 2

Para asegurarnos que todo va bien, en la opcin de View


live Form, tendremos la vista del formulario.

Paso 3

Almacenar las respuestas: debemos crear un enlace de las


respuesta a un SpreadSheet, para ello, nos dirigimos al
men Responses de ah buscamos la opcin Choose
response destination que por defecto nos muestra una
ventana para crear un nuevo SpreadSheet, le damos crear y
ya tenemos nuestro SpreadSheet.
Cada vez que un usuario haga submit a nuestro form, se
agrega al SpreadSheet

Paso 3

debemos crear un Document ya que cada vez que un


usuario nuevo llegue, se le manda correo personalizado a
partir de una plantilla con los datos del evento:

Hola %nombre% %apellido%

La reunin anual se llevar a cabo en la planta 2 del


edificio principal a las 14:30pm. Te esperamos all

Paso 4

Obtener el ID del documento para el script


El script usa el ID ya que a partir de eso, se hace una copia,
el ID de un documento est en la url

Paso 5

Para programar acciones respecto a nuestra data vamos al


Spreadsheet nos vamos a Tools y de ahi a Script editor y
creamos en un script en blanco la funcin que har el
procesamiento

Paso 6

La siguiente funcin va a recibir como parmetro cada


usuario nuevo que se agregue, cada uno de sus datos est
como parte de un arreglo, por lo que lo separamos, ahora
como esta funcin va a activarse al evento
OnFormSubmit, es importante darlo de alta en la seccin
de triggers, por lo lo agregamos con la configuracin de
From SpreadSheet seguido de On Form Submit

function onFormSubmit(e) {
var
var
var
var

tiempoRegistro = e.values[0];
nombre = e.values[1];
apellido = e.values[2];
correo = e.values[4];

var docId =
DocsList.getFileById(DOCUMENT_ID).makeCopy().getId();
var doc = DocumentApp.openById(docId);
doc.setName("Exito al Registrarte "+nombre);
var body = doc.getActiveSection();

body.replaceText("%nombre%", nombre);
body.replaceText("%apellido%", apellido);
doc.saveAndClose();
//Una pausa para el servidor, de no ser as se
satura y manda error
Utilities.sleep(3000);
GmailApp.sendEmail(correo, "Hola! "+nombre+" y
Gracias por Registrarte", "Los datos del evento
estan aqui:" +doc.getUrl());

Paso 7

Probar nuestro script

Ahora vamos a programar acciones enviando emails.

Envo de emails programados


Aadir nuevas funciones para envo de emails

var ahora;
var tolerancia= 5; // tiempo en minutos
function enviarEmail() {
ahora = new Date();
var doc = SpreadsheetApp.getActiveSpreadsheet();
var sheetParam = doc.getSheetByName("Form Responses
1");
var params = sheetParam.getRange(2, 1,
sheetParam.getLastRow()-1, 5);
var data = params.getValues();

Envo de emails programados

Aadir nuevas funciones para envo de emails

for (i in data){
var row = data[i];
if (isHoraEnvio(row[0])){
MailApp.sendEmail(row[4],"Helooo!!", row[1]+" "+row[2]+" ...wrote");
}
}
}
function isHoraEnvio(date){
var desde = new Date(ahora);
var hasta = new Date(ahora);

desde.setMinutes(ahora.getMinutes() - tolerancia);
hasta.setMinutes(ahora.getMinutes() + tolerancia);
return date>desde && date<hasta;

Envo de emails programados


Aadir funcin de validacin de intervalo

function isHoraEnvio(date){
var desde = new Date(ahora);
var hasta = new Date(ahora);
desde.setMinutes(ahora.getMinutes() - tolerancia);
hasta.setMinutes(ahora.getMinutes() + tolerancia);
}

return date>desde && date<hasta;

Vamos a hacer mejoras en la interfaz de Spreadsheet

Crear un nuevo elemento del men en una hoja


Spreadsheet y solicitar al usuario un dato de entrada al
hacer click en el:
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var searchMenuEntries = [ {name: Submenu de accin",
functionName: introduccion"}];
ss.addMenu(Nuevo menu", searchMenuEntries);
}

function introduccion() {
// solicitar informacin al usuario
var searchTerm = Browser.inputBox(Introduzca un valor:");
}

Vamos a conectarnos a un servicio externo y a crear


archivos en Gdrive a partir del response
Obtendremos las imgenes de Instagram por el hashtag
favorito y con el response crearemos las imgenes
Lo primero que necesitamos es crear una aplicacin en
Instagram para obtener el Client_id
http://instagram.com/developer/clients/manage/

function fetchInstagram() {
var TAG_NAME = 'follome';
var CLIENT_ID = 'a104222e6d2447c68c4b5ec378bfb7b6';
var url =
'https://api.instagram.com/v1/tags/'+TAG_NAME+'/media/recent?client_id='+CLIENT_ID;
var count = 0;
while(url && count < 5){
count++;
var response = UrlFetchApp.fetch(url).getContentText();
var responseObj = JSON.parse(response);
var photoData = responseObj.data;
for(var i in photoData){
var imageUrl = photoData[i].images.standard_resolution.url;
fetchImageToDrive_(imageUrl);
}
url = responseObj.pagination.next_url;
}

function fetchImageToDrive_(imageUrl){
var imageBlob = UrlFetchApp.fetch(imageUrl).getBlob();
var image = DriveApp.createFile(imageBlob);
return image.getUrl();
}

Y si queremos aadir contenido dinmicamente a un


documento?

Veamos un ejemplo

function addTableInDocument() {
// Cabeceras de la tabla Backgroud color, text bold, white
var headerStyle = {};
headerStyle[DocumentApp.Attribute.BACKGROUND_COLOR] = '#336600';
headerStyle[DocumentApp.Attribute.BOLD] = true;
headerStyle[DocumentApp.Attribute.FOREGROUND_COLOR] = '#FFFFFF';
// Estilo para filas noramles
var cellStyle = {};
cellStyle[DocumentApp.Attribute.BOLD] = false;
cellStyle[DocumentApp.Attribute.FOREGROUND_COLOR] = '#000000';
// configuracin de espaciados
var paraStyle = {};
paraStyle[DocumentApp.Attribute.SPACING_AFTER] = 0;
paraStyle[DocumentApp.Attribute.LINE_SPACING] = 1;

var doc = DocumentApp.openById('1jBLVB0wUMiQbunoqWlZpq96CqMQH_ibclauznTUFNRI');


//or var doc = DocumentApp.openByUrl('URL_OF_DOCUMENT');

var body = doc.getBody();


// Aadir una tabla al documento
var table = body.appendTable();
// Creando 5 filas y 4 columnas
for(var i=0; i<5; i++){
var tr = table.appendTableRow();
// aadiendo 4 celdas a cada fila
for(var j=0; j<4; j++){
var td = tr.appendTableCell('Cell '+i+j);
// Validacion de header para la tabla
if(i == 0) td.setAttributes(headerStyle);
else td.setAttributes(cellStyle);
var paraInCell = td.getChild(0).asParagraph();
paraInCell.setAttributes(paraStyle);

}
}
doc.saveAndClose();

La clase ContactsApp ofrece mtodos para obtener los


contactos de la cuenta google en uso.
Vamos a crear una web que presente una tabla con todos
los contactos de nuestra lista tomando solo los datos
primarios y validando si existen o no

function doGet() {
var app = UiApp.createApplication();
var panel= app.createVerticalPanel();
//Obtener contactos
var contacts = ContactsApp.getContacts();
//Creacin de grid para los datos
var grid = app.createGrid(contacts.length+1,4)
.setStyleAttribute('border', '1px solid black')
.setBorderWidth(1);
//Creacin de fila header
grid.setWidget(0, 0, app.createLabel('Nombre'))
.setWidget(0, 1, app.createLabel('Email'))
.setWidget(0, 2, app.createLabel('Tlf.'))
.setWidget(0, 3, app.createLabel('Direccion'));

//Aadir todos lo contactos al grid


for (var i=0; i<contacts.length; i++){
//aadir nombre completo o texto 'no encontrado'
if(contacts[i].getFullName()!='')grid.setWidget(i+1,
0, app.createLabel(contacts[i].getFullName()));
else
grid.setWidget(i+1, 0, app.createLabel('No
encontrado').setStyleAttribute('color', 'red'));
//

Obtener el email primario del contacto


try{
grid.setWidget(i+1, 1,
app.createLabel(contacts[i].getEmails()[0].getAddress()));
}
catch(e){
grid.setWidget(i+1, 1, app.createLabel('No
encontrado').setStyleAttribute('color', 'red'));
}

// Obtener telefono primario


try{
grid.setWidget(i+1, 2,
app.createLabel(contacts[i].getPhones()[0].getPhoneNumber()
));
}
catch(e){
grid.setWidget(i+1, 2, app.createLabel('Sin
numero').setStyleAttribute('color', 'red'));
}
// obtener direccion primaria
try{
grid.setWidget(i+1, 3,
app.createLabel(contacts[i].getAddresses()[0].getAddress())
);
}
catch(e){
grid.setWidget(i+1, 3, app.createLabel('Not
Available').setStyleAttribute('color', 'red'));
}
}

//aadir grid al panel


panel.add(grid);
//aadir panel a la aplicacion
app.add(panel);
return app;
}

Operadores de bsqueda
Operador

Definicin

Ejemplos

from:

Sirve para especificar


el remitente.

from:ana
Significado: mensajes
enviados por Ana

to:

Sirve para especificar


el destinatario.

to:david
Significado: mensajes
que t u otros
usuarios habis
enviado a David

subject:

Sirve para buscar


palabras incluidas en
la lnea del asunto.

subject:cena
Significado: mensajes
cuyo asunto incluye la
palabra "cena"

Operadores de bsqueda

OR

(guin)

label:

Sirve para buscar mensajes


que incluyan el trmino A o
el trmino B.*
*El parmetro OR debe
escribirse en maysculas.

Ejemplo: from:ana OR from:david


Significado: los mensajes que
provienen de Ana o de David

Sirve para excluir mensajes


de la bsqueda.

Ejemplo: cena -pelcula


Significado: mensajes que contienen
la palabra "cena" pero no la palabra
"pelcula"

Sirve para buscar mensajes


por etiquetas.

Ejemplo: from:ana label:amigos


Significado: mensajes de Ana que
incluyen la etiqueta "amigos"
Ejemplo: from:david label:mi familia
Significado: mensajes de David
etiquetados como "Mi familia"

has:attachment

Sirve para buscar


Ejemplo: from:david has:attachment
los mensajes que
Significado: los mensajes enviados por
tengan un
David que llevan adjunto un archivo
archivo adjunto.

list:

Sirve para buscar


mensajes
incluidos en
listas de
distribucin.

filename:

Ejemplo: filename:deberesfsica.txt
Sirve para buscar Significado: mensajes que llevan
un archivo
adjunto el archivo "deberesfsica.txt"
adjunto por su
Ejemplo: label:trabajo filename:pdf
nombre o por su Significado: mensajes con la etiqueta
tipo.
"trabajo" que llevan adjunto un archivo
en formato PDF

Ejemplo: list:info@ejemplo.com
Significado: mensajes enviados o
recibidos a travs de esta lista y que
incluyen info@ejemplo.com en sus
cabeceras

""
(comillas)

Sirven para buscar


una frase exacta*.
*No se distingue
entre maysculas y
minsculas.

Ejemplo: "voy a tener suerte"


Significado: mensajes que
contienen la frase "voy a tener
suerte" o "Voy a tener suerte"
Ejemplo: subject:"cena y peli"
Significado: mensajes cuyo asunto
contiene la frase "cena y peli"

()

Sirven para agrupar


palabras.
Sirven para
especificar los
trminos que no
deben excluirse.

Ejemplo: from:ana (cena OR peli)


Significado: mensajes de Ana que
contienen la palabra "cena" o la
palabra "peli"
Ejemplo: subject:(cena peli)
Significado: mensajes cuyo asunto
incluye las palabras "cena" y "peli"

in:anywhere

Sirve para buscar


mensajes en cualquier
sitio de Gmail*.
*De forma
predeterminada, no se
busca ni en la carpeta
Spam ni en la carpeta
Papelera.

Ejemplo: in:anywhere peli


Significado: los mensajes de las
carpetas Todos, Spam y
Papelera que contienen la
palabra "peli"

in:inbox
in:trash
in:spam

Sirven para buscar


mensajes en las carpetas
Recibidos, Papelera o
Spam. Nota: hay que
escribir sus nombres en
ingls ("inbox", "trash" y
"spam", respectivamente).

Ejemplo: in:trash from:ana


Significado: los mensajes
enviados por Ana que estn en
la Papelera ("trash" en ingls)

cc:
bcc:

Sirven para buscar los mensajes


enviados con copia Cc: o copia
oculta Cco:* a determinados
destinatarios.
*No incluyas tu direccin en
"Cco:" porque las bsquedas no
pueden recuperar esos
mensajes.

after:
before:
older:
newer:

Ejemplo: after:2004/04/16
before:2004/04/18
Sirven para buscar los mensajes
Significado: mensajes enviados
enviados en un intervalo de
entre el 16 y el 18 de abril de
tiempo definido entre "older" o
2004*
"after" (despus de) y "before" o
*Ms concretamente: los
"newer" (antes de),
mensajes enviados despus de
siempre con el formato de fecha
las 12:00 a.m. (o 00:00) del 16
aaaa/mm/dd.
de abril de 2004 y antes del 18
de abril de 2004.

Ejemplo: cc:david
Significado: los mensajes que
incluyen a David en el campo
"Cc"

older_than
newer_than

Permiten buscar
mensajes con respecto
a la fecha de hoy, a
saber: enviados hace
ms de ("older") o en
los ltimos ("newer") X
d, m o y (das, meses o
aos,
respectivamente).

+ (smbolo ms)

Ejemplo: +unicornio
Significado: los
Sirve para localizar
mensajes que
nicamente las
contienen la palabra
coincidencias exactas
unicornio (pero ni
con el trmino buscado
unicornios ni
unciornio)

Ejemplo:
newer_than:2d
Significado: encuentra
los mensajes enviados
en los dos ltimos das

size:

Sirve para buscar los mensajes


de un tamao superior (en
bytes) al especificado.

Ejemplo: size:1000000
Significado: todos los
mensajes de ms de 1 MB
(1.000.000 bytes)

larger:
smaller:

Sirven para buscar los


mensajes mayores o menores
("larger" o "smaller") que el
tamao especificado. Puedes
abreviar los millares y los
millones a la manera
anglosajona, siendo "K"
equivalente a "000"y "M" a
"000.000".

Ejemplo: larger:10M
Significado: todos los
mensajes de 10.000.000
bytes o ms de tamao

Bsqueda en mails:
Crear un Spreadsheet con:
Columnas: Fecha, Remitente, Mensaje, Enlace
Columna F3: nombre de alguna etiqueta
Columna F4: criterio de bsqueda

Crear un nuevo script


Aadir funcin: Search()
Obtener hoja de busquedas:
var sheet =
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("busqueda
gmail");
var row = 2;

Bsqueda en mails:
Limpiar resultados previos
sheet.getRange(2, 1, sheet.getMaxRows() - 1, 4).clearContent();

Obtener etiqueta criterio:


var label = sheet.getRange("F3").getValue();

Obtener texto criterio:


var pattern = sheet.getRange("F4").getValue();

Obtener threads por etiqueta:


var threads = GmailApp.search("in:" + label);

Bsqueda en mails:
Recorrer listado de threads:
Browser.msgBox("threads encontrados: "+threads.length);
for (var i = 0; i < threads.length; i++) {

Obtener thread
var messages = threads[i].getMessages();

Recorrer thread y obtener cuerpo de cada mensaje:


for (var m = 0; m < messages.length; m++) {
var msg = messages[m].getBody();

Buscar el criterio
if (msg.search(pattern) !== -1) {

Bsqueda en mails:
Si hay coincidencias:

Imprimir campo fecha


sheet.getRange(row,1).setValue(
Utilities.formatDate(messages[m].getDate(),"GMT","yyyy-MM-dd"));

Imprimir campo remitente


sheet.getRange(row,2).setValue(messages[m].getFrom());

Imprimir mensaje
sheet.getRange(row,3).setValue(messages[m].getSubject());

Crear e imprimir link al mensaje


var id = "https://mail.google.com/mail/u/0/#all/"
+ messages[m].getId();
sheet.getRange(row,4).setValue(id);

Pasar al siguiente
row++;

Bsqueda en mails:
Validar cierre de llaves
Probar script!!

Un usuario puede tener calendarios propios o suscritos


Clase: CalendarApp
Permite a un script leer y actualizar Google Calendar del usuario.
Esta clase proporciona acceso directo al calendario predeterminado
del usuario, as como la capacidad de recuperar calendarios
adicionales que son propiedad del usuario o se suscribi.

Calendar
Representa un calendario perteneciente a un usuario o alguno al
que est suscrito

Crear un evento desde un formulario


Pasos:
Crear un formulario (dinmicamente) que solicite:
Ttulo
Detalles
Fecha del evento

Crear un script que:

lea los valores introducidos


Utilice un calendario del usuario
Cree un evento con los datos recibidos
Aada un registro en un spreadsheet
Publicar el formulario como una web

function doGet() {
var app = UiApp.createApplication().setTitle('Gestion de
eventos');
// panel para elementos
var panel = app.createVerticalPanel().setId('panel');
// objetos del formulario
var eventDateLabel = app.createLabel('Fecha de Evento:');
var evenDate = app.createDateBox().setId('eventDate');
var eventTitleLabel = app.createLabel('Titulo:');
var eventTitle =
app.createTextBox().setName('eventTitle').setId('eventTitle
');
var eventDeatilLabel = app.createLabel('Detalles:');
var eventDetail = app.createTextArea()
.setSize('200',
'100').setId('eventDetail').setName('eventDetail');
var btn = app.createButton('createEvents');

//Handler que ejecutar 'createEvents(e)' en evento click


var handler =
app.createServerClickHandler('createEvents');
handler.addCallbackElement(panel);
// aadir handler al evento
btn.addClickHandler(handler);
// aadiendo eventos al panel
panel.add(eventDateLabel)
.add(evenDate)
.add(eventTitleLabel)
.add(eventTitle)
.add(eventDeatilLabel)
.add(eventDetail)
.add(btn);
// aadiendo panel a la aplicacin
app.add(panel);

return app;
}

//Registro de entradas en Spreadsheet


var ss =
SpreadsheetApp.openById('1uImRKgMzAdjl_1_Pki1Dc06_3OJz7tbQd3cWBc_kLY');
var sheet = ss.getSheetByName("eventos");
sheet.getRange(sheet.getLastRow()+1, 1, 1, 5).setValues([[new
Date(), eventDate,eventTitle, eventDetails, 'Evento Creado']]);
//Show the confirmation message
app.add(app.createLabel('Evento creado correctamente'));
//make the form panel invisible
app.getElementById('panel').setVisible(false);
return app;
}
// captura de eventos
catch(e){
app.add(app.createLabel('Error occured: '+e));
return app;
}
}

function createEvents(e){
var app = UiApp.getActiveApplication();
try{
// obtener entradas del evento
var eventDate = e.parameter.eventDate;
var eventTitle = e.parameter.eventTitle;
var eventDetails = e.parameter.eventDetail;
// obtener el calendario
var cal = CalendarApp.getCalendarsByName('Jose Julian
Ariza')[0];
var eventStartTime = eventDate;
//la fecha fin se aade sumando una hora
var eventEndTime = new
Date(eventDate.valueOf()+60*60*1000);
//Create the events
cal.createEvent(eventTitle, eventStartTime,eventEndTime
,{description:eventDetails});

Vamos a crear un html sencillo que muestre de manera


dinmica cierto texto usando jquery cuando el usuario haga
submit del formulario
Necesitamos crear:
Html de contenido
Script con mtodo doGet para presentar el contenido
Publicar como una webapp

<div>
<form id="email_subscribe">
<input type="email" name="email" id="email" placeholder="Enter your
email">
<input type="submit" value="Subscribe">
</form>
<span id="thank_you" hidden="true">Thank you!</span>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
</script>
<script>
$( document ).ready(function() {
$( "#email_subscribe" ).submit(function() {
$( "#thank_you" ).show();
});
});
</script>

function geocode_Addresses() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var locationInfo = sheet.getRange(1, 1, sheet.getLastRow(), 1).getValues();
var geoResults, lat, lng;

for (var i = 0; i < locationInfo.length; i++) {


geoResults = Maps.newGeocoder().geocode(locationInfo[i]);
// obtener latitud and longitud
lat = geoResults.results[0].geometry.location.lat;
lng = geoResults.results[0].geometry.location.lng;
sheet.getRange(i+1, 2, 1, 1).setValue(lat + "," + lng);
Utilities.sleep(1000); // aade un delay para prevenir restriccin de google:
Service Invoked Too Many Times
}
}

Google I/O 2013


http://www.youtube.com/watch?v=38H7WpsTD0M
http://www.youtube.com/watch?v=KIiCSdRCqXc
http://www.youtube.com/watch?v=0HVJMIeb3aE