Bots de conversa de Telegram amb Google Apps Script

Bots de conversa Exemples Dades pràctiques   Recursos CITCEA
Google Apps Script Projectes Interacció   Inici

Generem una orla amb fotografies de les persones d'un grup

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ó:

Equip de futbol

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 &amp;
  var urlbase = "https://drive.google.com/uc?export=view&id=".replace('&','&amp;');
  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);
}

 

 

 

 

 

 

 

 

 

 

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