Crear un Sitio de Google con Apps Script

Crear un Sitio de Google con Apps Script

El objetivo de este tutorial es crear un sitio con header, footer y contenido que lea y escriba datos a una hoja de cálculo de Google. Como extra se agregará JQuery y Boostrap. Puedes descargar antes el código. El resultado se muestra en la siguiente imagen GIF.

Crear un Sitio de Google con Apps Script

Google Apps Script

Google Apps Script en resumen es usar Javascript en el lado del cliente y del servidor desde la nube. Proporciona formas fáciles de automatizar tareas entre diferentes productos de Google y servicios de terceros.

Sitios de Google

Un Sitio de Google permite a las personas que puedan trabajar juntos para añadir archivos adjuntos, información de otras aplicaciones de Google (como Google Docs, Google Calendar, YouTube y Picasa), y nuevo contenido de forma libre. Su principal ventaja es que te olvidas de compilar.

JQuery

jQuery es una biblioteca de JavaScript que permite simplificar la manera de interactuar con los documentos HTML, manipular el árbol DOM, manejar eventos, desarrollar animaciones y agregar interacción con la técnica AJAX a páginas web. En nuestro ejemplo y de manera usual, las funciones pertenecientes a JQuery se respresentan al inicio con “$” .

Bootstrap

En resumen es un conjunto de herramientas que permiten un diseño responsivo en una página Web mediante bibliotecas de CSS y Javascript.

Empecemos

Entramos a https://sites.google.com  y seleccionamos la opción CREATE:

site1

Escogemos Blank Template y nombramos a nuestro nuevo sitio.

site2

Seleccionamos el tema Blank Slate ya que con este más adelante podremos hacer nuestros propios menús con plugins de Boostrap como Jasny.

site3

Seleccionamos la opción de CREATE. Con esto ya hemos creado un sitio de manera sencilla y rápida.

site4

Vamos a https://drive.google.com y creamos una carpeta como ejemplo llamada “mysite” seleccionando NUEVO.

site5

Dentro de la carpeta “mysite” creamos un Google Apps Script seleccionando NUEVO ->Más -> Google Apps Script.

Nombramos al proyecto, en este caso como ejemplo sería Laishidua Site.

site6

 

Siguiendo pasos similares a lo anterior creamos una nueva hoja de cálculo, la llamaremos LaishiduaUserPass y renombramos a la primera Hoja: Sheet1.

site8

Al abrir el Apps Script de Laishidua Site creamos seis archivos aparte del archivo .GS que se creó por defecto (en este caso fue Code.gs): index.html, contentInit.html, contentForm.html, StyleSheet.html, JS_ContentInit.html, JS_ContentForm.html y JS_Libs_Ext.html.

site7

En Code.gs ponemos:

function doGet() { 
 return HtmlService.createTemplateFromFile('index')
 .evaluate()
 .setSandboxMode(HtmlService.SandboxMode.IFRAME); 
}

function include(filename) {
 return HtmlService.createHtmlOutputFromFile(filename)
 .setSandboxMode(HtmlService.SandboxMode.IFRAME)
 .getContent();
}

function searchContent(template, callbackname){ 
 var res = new Array();
 res[0] = HtmlService.createTemplateFromFile(template).getRawContent();
 if (callbackname != null) {
 res[1] = callbackname; 
 }
 return res; 
}

function saveToSheet(usr, pwd){
 var lock = LockService.getPublicLock();
 lock.waitLock(30000); // wait 30 seconds before conceding defeat.
 try {
 var sheet = SpreadsheetApp.
 openByUrl('https://docs.google.com/spreadsheets/d/1i4naI0PKSVUWWlKkGPQ8I9-6TpMWPOb0BnQNRc6nfjI/edit')
 .getSheetByName("Sheet1");
 var lastRow = sheet.getLastRow(); 
 sheet.appendRow([usr, pwd]);
 var lastRowRes = sheet.getLastRow();
 var res = "Error!";
 if (lastRowRes > lastRow) {
 res = "Success!";
 }
 return res;
 } catch(e) {
 // if error return this
 return "Error!";
 } finally { //release lock
 lock.releaseLock();
 } 
}

function sesion_GSUserEmail(){
 return Session.getActiveUser().getEmail();
}

Code.gs es el único script que va a estar del lado del servidor. A continuación explico cada función.

  • doGet() es la función que en primer lugar carga una plantilla que nosotros definimos como index.html. Definimos el SandboxMode como IFRAME que en resúmen nos va a permitir usar las bibliotecas de JQuery y Bootstrap en nuestro sitio sin problemas.
  • include(<nombre del archivo a incluir>) función que nos ayuda a incluir mas scripts en el index principal.
  • searchContent(<plantilla>, <función a ejecutar del lado del cliente al cargar la plantilla>) como separamos cada contenido entre el de inicio de bienvenida y el del formulario en dos plantillas diferentes, esta función nos ayuda a cargarlos y ejecutar el segundo parametro que es el nombre de la función que se encuentra del lado del cliente.
  • saveToSheet(<usuario>, <contraseña>) salva los dos parámetros en la hoja de cálculo que hemos creado cuya ruta en este caso como ejemplo sería https://docs.google.com/spreadsheets/d/1i4naI0PKSVUWWlKkGPQ8I9-6TpMWPOb0BnQNRc6nfjI/. El código previene acceso concurrente al código.
  • sesion_GSUserEmail() obtiene el correo electrónico del usuario que se encuentra conectado actualmente al sitio.

En StyleSheet.html ponemos:

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">

En StyleSheet.html simplemente cargamos la hoja de estilo de boostrap que vamos a utilizar, también en este archivo podríamos si así lo quisiéramos nuestra propia hoja de estilo.

En JS_Libs_Ext.html ponemos:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1','packages':['corechart']}]}"></script>

En JS_Libs_Ext.html se cargan las bibliotecas de Javascript externas que vamos a utilizar tal como Jquery, Boostrap y Google Visualization.

En index.html ponemos:

<!DOCTYPE html>
<html>
 <head>
 <meta charset="utf-8">
 <title>LAISHIDUA SITE</title>
 <?!= include('StyleSheet'); ?>
 </head>
 <body>

<div id="headerContent"> 
 HERE YOU CAN PLACE A BANNER.
 </div>


<div id="indexContent" class="container-fluid"> 
 </div>


<div id="footerContent"> 
 HERE YOU CAN PLACE A FOOTER.
 </div>

 
 </body>
 <?!= include('JS_Libs_Ext'); ?>
 <?!= include('JS_ContentInit'); ?>
 <?!= include('JS_ContentForm'); ?>
</html>

index.html simplemente carga en el inicio la hoja de estilo y al final todos los javascript que hemos creado utilizando la función include.

En contentInit.html ponemos:


<h2>Welcome / Bienvenido</h2>



<h2 id="userEmail"></h2>


To go to the form, press the next button:

<button id="goToForm" type="button" class="btn btn-primary">Go</button>

En contentInit.html vamos a hacer que se cargue contentForm.html al oprimir el botón Go. Antes se debe haber cargado JS_ContentInit.html .

En JS_ContentInit.html ponemos:

<script>

 //contentIndex loading functions

 function updateDiv(content){ 
 $("#indexContent").fadeOut(500,function(){
 $('#indexContent').html(content[0]);
 $("#indexContent").fadeIn(500);
 if (content.length > 1) {
 window[content[1]].call();
 }
 })
 } 

 function getContent(content, callbackfname){
 google.script.run.withSuccessHandler(updateDiv).searchContent(content, callbackfname); 
 } 
 
 //close contentIndex loading functions
 
 // generic functions
 
 function dataTableToArray(data){
 var json = JSON.parse(data.toJSON());
 var rows = json.rows;
 var resArray = new Array();
 for(var i in rows) {
 var jsonRowC = rows[i].c;
 var arrayRow = new Array();
 for(var j in jsonRowC) {
 if (jsonRowC[j]) {
 var jsonRowV = jsonRowC[j].v;
 arrayRow[j] = jsonRowV;
 } else {
 var jsonRowV = ""; 
 arrayRow[j] = jsonRowV;
 }
 }
 resArray.push(arrayRow);
 }
 return resArray;
 } 

 //close generic functions
 
 //contentInit functions
 
 function setWelcomeToEmail(data){
 $("#userEmail").html(data); 
 } 
 
 function init() {
 google.script.run.withSuccessHandler(setWelcomeToEmail).sesion_GSUserEmail();
 $("#goToForm").on("click", function(e) {
 getContent('contentForm', "initContentForm");
 });
 } 
 
 $( document ).ready(function() {
 getContent("contentInit", "init"); 
 });
 
 //close contentInit functions
</script>



  • updateDiv(content) actualiza el “div” indexContent del index.html con algún contenido html que se lee del parámetro content.
  • getContent(content, callbackfname) utiliza la función updateDiv después de buscar el nombre del contenido html, el nombre del html se pone en el parámetro content y después se ejecuta la función cuyo nombre se pone en el parámetro callbackframe del lado del cliente.
  • dataTableToArray(data) función que convierte un objeto DataTable el cuál manda  en un arreglo, el objeto DataTable se obtiene utilizando la biblioteca google.visualization.Query.
  • setWelcomeToEmail(data) actualiza el objeto “h2” del html con el correo electrónico del usuario.
  • init() Hace que al oprimir el botón “Go” actualice el contenido del html contentForm.html en el “div” indexContent del index.html  y luego ejecute la función initContentForm que se encuentra en JS_ContentForm.html.
  • $( document ).ready … hace que se ejecute en primer lugar lo que se encuentra adentro de function() después de haber cargado la página.

En contentForm.html ponemos:

<form role="form">
 <div class="form-group">
 <label for="usr">Name:</label>
 <input type="text" class="form-control" id="usr">
 </div>
 <div class="form-group">
 <label for="pwd">Password:</label>
 <input type="password" class="form-control" id="pwd">
 </div>
 <input type="button" class="btn btn-info" value="Save" id="save">
 <input type="button" class="btn btn-info" value="Get Passwords" id="getPwds">
</form>
 
<table class="table table-striped">
 <thead>
 <tr>
 <th>Name</th>
 <th>Passwords</th>
 </tr>
 </thead>
 <tbody id="myUsrPwdsTableBody">
 </tbody>
</table>

contentForm.html es un simple formulario en html que va a insertar datos a la hoja de cálculo que hemos creado al oprimir “Save” y obtenerlos en una tabla al oprimir “getPwds”. Para esto se depende del script JS_ContentForm.html.

En JS_ContentForm.html ponemos:

<script>

 function initContentForm() {
 $("#save").on("click", function(e) {
 save();
 });
 $("#getPwds").on("click", function(e) {
 getPwds();
 });
 }

 function save() {
 var usr = $("#usr").val();
 var pwd = $("#pwd").val();
 google.script.run.withSuccessHandler(savedMessage).saveToSheet(usr, pwd);
 } 
 
 function savedMessage(data){
 alert(data);
 }
 
 function getPwds() {
 var query = 
 new google.visualization.Query(
 "https://docs.google.com/spreadsheets/d/1i4naI0PKSVUWWlKkGPQ8I9-6TpMWPOb0BnQNRc6nfjI/gviz/tq?gid=0"
 );
 query.setQuery("select A, B where A = '" + $("#usr").val() + "'");
 query.send(setPwdsInTable);
 }
 
 function setPwdsInTable(data) {
 if (data.isError()) {
 console.log('Error in query: ' + data.getMessage() + ' ' + data.getDetailedMessage());
 alert("Error to search data!");
 return;
 }
 var dataResponse = data.getDataTable();
 var dataArray = dataTableToArray(dataResponse);
 var tableBody = $("#myUsrPwdsTableBody");
 tableBody.empty();
 if ( dataArray.length > 0 ) {
 for(var i=0; i<dataArray.length; i++) {
 tableBody.append(
 "<tr><td>" + dataArray[i][0] + "</td><td>" + dataArray[i][1] + "</td></tr>");
 }
 } 
 }
 
</script>
  • initContentForm() esta función se ejecuta al haber cargado el contentForm.html, contiene dos funciones de JQuery las cuales hacen que cuando se oprima el botón “Save” se ejecute la función save() y cuando se oprima el botón “Get Passwords” se ejecute la función getPwds().
  • save() guarda los datos en la hoja de cálculo, ejecuta primero la función saveToSheet de lado del servidor y luego savedMessage() de lado del cliente.
  • savedMessage() muestra un mensaje en la página con la respuesta del servidor.
  • getPwds() obtiene los datos guardados en la hoja de cálculo fijandose en el dato ingresado en el input cuyo “id” es “usr” utilizando la biblioteca de Google Visualization la cual evita bloqueos al hacer búsquedas de lado del cliente. La respuesta de la búsqueda la devuelve al método setPwdsInTable(data).
  • setPwdsInTable(data) muestra en una tabla la respuesta de la búsqueda.

Ahora podemos empezar a integrar nuestro proyecto al sitio que hemos creado. Para esto en la vista de script vamos al menú de publicar -> implementar como aplicación web, ponemos en la versión “nuevo” y Actualizar.

site11

Al oprimir “Actualizar” va a aparecer otra ventana copiamos la ruta asignada y oprimimos Aceptar.

site12

Vamos a nuestro sitio mediante su URL, oprimimos el botón cuyo icono es un lapiz y dice “Edit Page” de la parte superior derecha.

site10

Vamos al menú insert -> Apps Script y en la ventana que aparece ponemos la URL que hemos copiado de nuestro Script, oprimimos “Select”.

site13

Aparecerá otra ventana, en esta quitamos la opción de include border … e include title, en Height ponemos de altura 3000 y oprimimos “Save”. Al volver oprimimos el “Save” de la parte superior derecha.

site14

Ahora ya tenemos integrado nuestro formulario en nuestro sitio, aunque falta ajustar ciertos detalles.

site9

Vamos al menú de configuración cuyo icono es un engrane a lado del botón share.

site10

 

Vamos a “Edit Site Layout”. Quitamos el header y sidebar.

site15

Volvemos al menú de configuración e ingresamos a “Manage Site”. Quitamos “

site16

Ahora nuestro sitio se ve mucho mas limpio. Lo podemos visualizar desde el menú de configuración en “Preview page as viewer”.

site17

<———————————————>

site18

Así de simple y rápido hemos creado un sitio con un formulario con tecnología de Google. Al abrir la hoja de cálculo creada veremos que ha guardado los datos que ingresemos al formulario.

site19

Descarga el código para crear un sitio de Google con Apps Script.

Esta entrada está también disponible en us.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *