| Bots de conversa | Exemples | Dades pràctiques | Recursos CITCEA | |
| Google Apps Script | Projectes | Interacció | Inici |
El que proposem en aquest exemple és poder crear, de manera automatitzada, l'orla de les persones que han acabat uns estudis, la llista de membres d'un quip esportiu amb fotografies, etc. El resultat obtingut tindrà un aspecte semblant al que es mostra a continuació:
Les dades estaran en un full de càlcul. A la primera columna hi haurà els cognoms de les diferents persones, a la segona els noms i en la tercera l'identificador de les fotografies que hi ha guardades a Google Drive. Amb petits canvis podríem fer que al full de càlcul hi hagués les adreces URL de les fotografies o les adreces de visualització de Google Drive.
Nota: Google Drive no admet que generem un PDF amb imatges que s'indiquen amb un enllaç, per tant en aquest exemple no generarem el document PDF ni la seva miniatura.
En el nostre cas podrem obtenir el gràfic de dues maneres. Una d'elles serà a l'executar l'script des del navegador (funció doGet) i obtindrem una pàgina web que contindrà el gràfic. L'altra serà accedint des de Telegram (funció doPost) i, en cas de fer servir la comanda /grafic obtindrem un enllaç per visualitzar el fitxer al navegador. Si fem servir Telegram des d'un dispositiu mòbil, no hem d'obrir l'enllaç des de Google Drive sinó que cal emprar el navegador.
El programa és el següent:
var token = "^^34328844:AAFIpk-e7j3UZtYQYQaTduf4hEhnDqIcNXI"; // API Token de Telegram
var telegramUrl = "https://api.telegram.org/bot" + token; // URL que comunica el bot de conversa amb Telegram
var ssId = "^^ThsoSjkeMSfwEKy4mn_4QEYH96sxv3VURqE3WHCTswDA"; // Identificador del full de càlcul
var id_carpeta = "^^Hlod5Y4qEsLF9HrIsE6oYQa32f6NHeo"; // Carpeta on guardarem el PDF
// Definim els colors que emprarem al gràfic
var negre = "#000000";
function doGet(e){
var resp = grafic(); // Crea el gràfic
var nomFitxer = "grafic"; // Nom del fitxer
// Crea el fitxer
var fitxerNou = DriveApp.getFolderById(IdCarpeta).createFile(nomFitxer + ".svg",resp);
var idFitxer = fitxerNou.getId(); // Identificador del fitxer
var urlDescFitxer = fitxerNou.getDownloadUrl(); // Adreça per descarregar el fitxer
// Adreça per veure el fitxer
var urlFitxer = "https://drive.google.com/uc?export=view&id=" + idFitxer;
// Creem una pàgina web senzilla que contindrà el gràfic
var pagina = "<!DOCTYPE HTML>" + "\n";
pagina = pagina + "<html>" + "\n";
pagina = pagina + "<head>" + "\n";
pagina = pagina + "<meta charset='UTF-8'>" + "\n";
pagina = pagina + "</head>" + "\n";
pagina = pagina + "<body>" + "\n";
pagina = pagina + resp + "\n";
pagina = pagina + "</body>" + "\n";
pagina = pagina + "</html>" + "\n";
return HtmlService.createHtmlOutput(pagina);
}
function doPost(e){
var data = JSON.parse(e.postData.contents); // Llegeix les dades rebudes per JSON i les guarda
var text = data.message.text; // Comanda enviada
var id = data.message.chat.id; // Identificador de la finestra d'on prové el missatge
var id_usuari = data.message.from.id; // Identificador de l'usuari
var id_missatge = data.message.message_id; // Identificador del missatge
var lang = data.message.from.language_code ; // Idioma de l'usuari
var nom_usr = data.message.from.first_name ; // Nom de l'usuari
var location = data.message.location; // Localització de l'usuari (si es sap)
var realitzat = false;
if(text == '/grafic'){
var resp = grafic(); // Crea el gràfic
var nomFitxer = "grafic"; // Nom del fitxer
// Crea el fitxer
var fitxerNou = DriveApp.getFolderById(IdCarpeta).createFile(nomFitxer + ".svg",resp);
var idFitxer = fitxerNou.getId(); // Identificador del fitxer
// Enllaç per veure el fitxer al navegador
var urlDescFitxer = fitxerNou.getDownloadUrl(); // Enllaç per descarregar el fitxer
// Enllaç per veure el fitxer
var urlFitxer = "https://drive.google.com/uc?export=view&id=" + idFitxer;
var resposta = "Pots veure el gràfic aquí:\n" + urlFitxer;
sendText(id,resposta); // Enviem l'enllaç
realitzat = true;
}
if (!realitzat){
var resposta = "Comanda desconeguda";
sendText(id,resposta);
}
}
function grafic(){
var maxcol = 9; // Màxim de persones per filera
var maxfil = 5; // Màxim de fileres
var sh = SpreadsheetApp.openById(ssId).getSheetByName("llista"); // Agafem el full
var dades = sh.getDataRange().getValues(); // Agafem les dades
// Vectors on guardarem les dades
var noms = new Array();
var cognoms = new Array();
var fotos = new Array();
for (var i in dades){ // Recorrem totes les dades
if (i > 0){ // Ignorem la filera de títols
var row = dades[i];
cognoms.push(row[0]);
noms.push(row[1]);
fotos.push(row[2]);
}
}
var numpers = cognoms.length; // Nombre de persones que sortiran a l'orla
if(numpers > maxcol * maxfil){
numpers = maxcol * maxfil; // Limita el nombre de persones a les que hi caben (45)
}
var numfil = Math.ceil(numpers / maxcol) - 1; // Calcula el nombre de fileres
var darrerafila = numpers - maxcol * numfil; // Persones que queden per a la darrera fila
if((darrerafila > 0) && (darrerafila < 5)){
maxcol--; // Si la darrera fila queda molt buida, suprimim una columna
}
numfil = Math.ceil(numpers / maxcol) - 1; // Nombre real de fileres
// Mides principals
var altit = 40;
var ampgr = 1200;
var altgr = 900;
// Creem la capçalera
var grafic = cap(ampgr, altgr, "Capa 1")+ '\n';
var titol = "Robòtic Futbol Club temporada 1984-1985";
grafic = grafic + text(ampgr/2, altit*1.5, titol, 40, negre, "c", 1, 0, "tit") + '\n';
// Mides de les imatges i espaiats
var ampleimg = 80;
var altimg = 1.2 * ampleimg;
var espv = ((altgr - altit) - (altimg * (numfil + 1))) / (numfil + 2);
var margeh = (ampgr - (ampleimg * maxcol)) / (maxcol + 1);
// En HTML i XML cal substituir & pel seu equivalent &
var urlbase = "https://drive.google.com/uc?export=view&id=".replace('&','&');
for(var i = 0; i < numpers; i++){ // Per a totes les persones
// Posició de la persona
var fil = Math.floor(i / maxcol);
var col = i % maxcol;
if(fil < numfil){ // Fileres normals
var numcol = maxcol;
} else { // Darrera filera
var numcol = numpers - maxcol * numfil;
}
// Posició de la foto
var esph = (ampgr - (2 * margeh) - (ampleimg * numcol)) / (numcol - 1);
var x1 = margeh + (ampleimg + esph) * col;
var y1 = altit + espv + (altimg + espv) * fil;
var idimg = "foto" + i;
var idpeu = "peu" + i;
var urlfoto = urlbase + fotos[i]; // Adreça URL de la foto
grafic = grafic + imatge(x1, y1, ampleimg, altimg, urlfoto, idimg) + '\n';
// Posició del text
x1 = x1 + ampleimg /2;
y1 = y1 + altimg + 15;
grafic = grafic + text(x1, y1, cognoms[i]+',', 12, negre, "c", 0, 0, idpeu+'a') + '\n';
grafic = grafic + text(x1, y1+13, noms[i], 12, negre, "c", 0, 0, idpeu+'b') + '\n';
}
// Posem el final del fitxer svg
grafic = grafic + peu();
return grafic;
}
function imatge(x, y, ample, alt, url, ident){
var resp = '<image id="' + ident + '" x="' + x + '" y="' + y + '" width="' + ample;
resp = resp + '" height="' + alt + '" xlink:href="' + url + '"/>';
return resp;
}
function text(x, y, txt, mida, color, alin, negreta, cursiva, ident){
if (alin == "e"){ // Esquerra
var aln = "start";
}
if (alin == "c"){ // Centre
var aln = "middle";
}
if (alin == "d"){ // Dreta
var aln = "end";
}
var resp = '<text id="' + ident + '" xml:space="preserve" text-anchor="' + aln;
resp = resp + '" font-family="serif" font-size="' + mida + '" x="' + x + '" y="' + y +'"';
if (negreta == 1){
resp = resp + ' font-weight="bold"';
}
if (cursiva == 1){
resp = resp + ' font-style="italic"';
}
resp = resp + ' stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="0" stroke="';
resp = resp + color + '" fill="' + color + '">' + txt + '</text>';
return resp;
}
function cap(ample, alt, titol){
var resp = '<svg width="' + ample + '" height="' + alt;
resp = resp + '" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"';
resp = resp + ' xmlns:xlink="http://www.w3.org/1999/xlink">' + '\n';
resp = resp + '<g>' + '\n' + '<title>' + titol + '</title>';
return resp;
}
function peu(){
var resp = '</g>' + '\n' + '</svg>';
return resp;
}
function sendText(chatId,text_env,keyBoard){ // Funció que envia un text o un teclat a Telegram
keyBoard = keyBoard || 0;
if(keyBoard.inline_keyboard || keyBoard.keyboard){
var data = {
method: "post",
payload: {
method: "sendMessage",
chat_id: String(chatId),
text: text_env,
parse_mode: "HTML",
reply_markup: JSON.stringify(keyBoard)
}
}
} else {
var data = {
method: "post",
payload: {
method: "sendMessage",
chat_id: String(chatId),
text: text_env,
parse_mode: "HTML"
}
}
}
UrlFetchApp.fetch( telegramUrl + '/', data);
}

Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.