Bots de conversa de Telegram amb Google Apps Script

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

Maneres de mostrar els gràfics SVG

Un cop tinguem definides les comandes del nostre gràfic, hi ha diferents maneres de mostrar-lo a l'usuari que comentem a continuació. Cal tenir present que moltes d'elles només serveixen en alguns casos concrets.

Incloure les comandes SVG directament en una pàgina web

Això ens pot ser útil quan generem una pàgina web que s'ha de mostrar com a resposta a una comanda GET al nostre script. A continuació tenim, com a exemple, una funció doGet d'un script que ens genera una pàgina web que inclou directament un gràfic SVG. Considerem que la funció grafic retorna el dibuix complet en format SVG.

function doGet(e){
  var resp = grafic();
  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 + "<h1>Valors de la setmana passada</h1>" + "\n";
  pagina = pagina + resp + "\n";
  pagina = pagina + "</body>" + "\n";
  pagina = pagina + "</html>" + "\n";
  return HtmlService.createHtmlOutput(pagina);
}

En aquest exemple se'n pot veure un possible ús.

Generar un fitxer SVG

Podem generar un fitxer amb el nostre dibuix SVG per després utilitzar-lo on ens sembli més convenient. El següent tros de programa ho fa. Considerem que la funció grafic retorna el dibuix complet en format SVG.

  var resp = grafic();
  var nomFitxer = "grafic";
  var fitxerNou = DriveApp.getFolderById(IdCarpeta).createFile(nomFitxer + ".svg",resp);
  var idFitxer = fitxerNou.getId();
  var urlDescFitxer = fitxerNou.getDownloadUrl();  // Adreça per descarregar el fitxer del Driva
  var urlFitxer = "https://drive.google.com/uc?export=view&id=" + idFitxer;  // Adreça directa a la imatge

Aquest gràfic el podem incloure en una pàgina web que s'ha de mostrar com a resposta a una comanda GET al nostre script. A continuació tenim, com a exemple, una funció doGet d'un script que ens genera una pàgina web que inclou un gràfic SVG guardat en el fitxer. Considerem que la funció grafic retorna el dibuix complet en format SVG.

function doGet(e){
  var resp = grafic();
  var nomFitxer = "grafic";
  var fitxerNou = DriveApp.getFolderById(IdCarpeta).createFile(nomFitxer + ".svg",resp);
  var idFitxer = fitxerNou.getId();
  var urlFitxer = "https://drive.google.com/uc?export=view&id=" + idFitxer;
  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 + "<h1>Valors de la setmana passada</h1>" + "\n";
  pagina = pagina + '<img src="' + urlFitxer + '" border=0 alt="Gràfic de barres">' + "\n";
  pagina = pagina + "</body>" + "\n";
  pagina = pagina + "</html>" + "\n";
  return HtmlService.createHtmlOutput(pagina);
}

En aquest exemple se'n pot veure un possible ús.

Enviar l'enllaç a Telegram

Telegram no pot (com a mínim en el moment d'escriure això) visualitzar gràfics SVG. Podem, però, enviar a l'usuari un enllaç per tal que pugui visualitzar el gràfic al navegador. El següent tros de programa (que formaria part de la funció doPost) fa això, considerem que la funció grafic retorna el dibuix complet en format SVG.

  var realitzat = false;
  if(text == '/grafic'){
    var resp = grafic();
    var nomFitxer = "grafic";
    var fitxerNou = DriveApp.getFolderById(IdCarpeta).createFile(nomFitxer + ".svg",resp);
    var idFitxer = fitxerNou.getId();
    var urlDescFitxer = fitxerNou.getDownloadUrl();  // Enllaç per descarregar el fitxer
	// Enllaç per veure el fitxer al navegador
    var urlFitxer = "https://drive.google.com/uc?export=view&id=" + idFitxer;
    sendText(id,urlFitxer);
    realitzat = true;
  }

També podem forçar a l'usuari a descarregar el fitxer canviant l'adreça que li enviem:

    sendText(id,urlDescFitxer);

Generar un document PDF a partir del gràfic SVG

Podem generar un document PDF que contingui el nostre gràfic. Per fer-ho, definirem un codi HTML que, en realitat, serà el codi SVG del nostre gràfic. El següent tros de programa fa això, considerem que la funció grafic retorna el dibuix complet en format SVG. També obtenim els enllaços per poder obrir el fitxer i per poder descarregar-lo.

  var htmlInst = grafic();
  var html = HtmlService.createHtmlOutput(htmlInst);
  var pdf = DriveApp.createFile(html.getAs("application/pdf").setName(nomFitxer + ".pdf"));
  var idFitxer = pdf.getId();
  var urlDescFitxer = pdf.getDownloadUrl();  // Enllaç per descarregar el fitxer
  // Enllaç per veure el fitxer al navegador
  var urlFitxer = "https://drive.google.com/uc?export=view&id=" + idFitxer;  

Podem afegir més comandes HTML si volem que el nostre PDF contingui altres coses com un títol o que englobi més d'una imatge. En cas que el nostre dibuix sigui més ample que alt, podem afegir una instrucció que forci a que el PDF tingui el full apaïsat.

  var htmlInst = '<style type="text/css" media="print">@page {size: landscape;} </style>' + grafic();

En aquest exemple se'n pot veure un possible ús.

Generar un document PDF a partir de les dades binàries (BLOB) del gràfic

També podem posar el nostre dibuix dins d'una instrucció img, això ens permet canviar la mida del gràfic dins el PDF. El següent tros de programa fa això, considerem que la funció grafic retorna el dibuix complet en format SVG.

  var resp = grafic();
  var nomFitxer = "grafic";
  var fitxerNou = DriveApp.getFolderById(IdCarpeta).createFile(nomFitxer + ".svg",resp);
  var idFitxer = fitxerNou.getId();
  var urlDescFitxer = fitxerNou.getDownloadUrl();  // Enllaç per descarregar el fitxer
  // Enllaç per veure el fitxer al navegador
  var urlFitxer = "https://drive.google.com/uc?export=view&id=" + idFitxer;  
  var blob = UrlFetchApp.fetch(urlFitxer).getBlob();
  var b64 = blob.getContentType() + ';base64,'+ Utilities.base64Encode(blob.getBytes());
  var htmlEst = '<style type="text/css" media="print">@page {size: landscape;} </style>';
  var htmlInst = htmlEst + '<img src="data:' + b64 + '" width=900 alt="Histograma">';
  var html = HtmlService.createHtmlOutput(htmlInst);
  var pdf = DriveApp.createFile(html.getAs("application/pdf").setName(nomFitxer + ".pdf"));
  var idFitxer = pdf.getId();
  var urlDescFitxer = pdf.getDownloadUrl();  // Enllaç per descarregar el fitxer
  // Enllaç per veure el fitxer al navegador
  var urlFitxer = "https://drive.google.com/uc?export=view&id=" + idFitxer;  

En aquest cas hem posat l'amplada del fitxer a 900 píxels; atès que no diem res, l'alçada serà la que correspongui per mantenir la proporció.

Amb aquest mètode, la imatge no pot estar en forma d'enllaç sinó que hi ha d'haver les dades corresponents inserides a la instrucció img. Per això l'script obté les dades BLOB de la imatge, les codifica en base64 i les posa dins de la instrucció.

En aquest exemple se'n pot veure un possible ús.

Obtenir una imatge per enviar a Telegram

Ja hem dit abans que Telegram no és capaç (si més no, de moment) de visualitzar les imatges SVG. Hi ha, però, un truc que ens permet obtenir una imatge que sigui possible enviar a Telegram. El mètode es basa en que, un cop generat el document PDF que conté el gràfic, Google Drive genera una imatge miniatura (thumbnail) per poder mostrar quan es visualitza la carpeta. Aquesta imatge és la que enviarem a Telegram. Fixem-nos que per aconseguir enviar la imatge haurem de generar tres fitxers: el que conté el gràfic SVG, el document PDF i la imarge miniatura. D'aquests tres fitxers, dos estaran a la nostra carpeta com a elements separats mentre que el tercer estarà lligat al document PDF. Un cop enviada la imatge, si ho desitgem, podem esborrar els fitxers que ja no necessitem.

La generació de la imatge miniatura triga un temps i, per tant, el nostre script haurà d'esperar fins que estigui disponible. El següent tros de programa genera la imatge i l'envia a l'usuari, considerem que la funció grafic retorna el dibuix complet en format SVG.

function pdf(){
  var resp = grafic();
  var nomFitxer = "grafic";
  var fitxerNou = DriveApp.getFolderById(IdCarpeta).createFile(nomFitxer + ".svg",resp);
  var idFitxer = fitxerNou.getId();
  var urlDescFitxer = fitxerNou.getDownloadUrl();  // Enllaç per descarregar el fitxer
  // Enllaç per veure el fitxer al navegador
  var urlFitxer = "https://drive.google.com/uc?export=view&id=" + idFitxer;  
  var blob = UrlFetchApp.fetch(urlFitxer).getBlob();
  var b64 = blob.getContentType() + ';base64,'+ Utilities.base64Encode(blob.getBytes());
  var htmlEst = '<style type="text/css" media="print">@page {size: landscape;} </style>';
  var htmlInst = htmlEst + '<img src="data:' + b64 + '" width=900 alt="Histograma">';
  var html = HtmlService.createHtmlOutput(htmlInst);
  var pdf = DriveApp.createFile(html.getAs("application/pdf").setName(nomFitxer + ".pdf"));
  var pdfId = pdf.getId();
  var repetir = true;
  var cnt = 0;
  while(repetir){
    var thumb = DriveApp.getFileById(pdfId).getThumbnail();
    Utilities.sleep(100);
    cnt++;
    if((cnt > 100) || (thumb)){
      repetir = false;
    }
  }
  return thumb;
}
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();
    var nomFitxer = "grafic";
    var fitxerNou = DriveApp.getFolderById(IdCarpeta).createFile(nomFitxer + ".svg",resp);
    var idFitxer = fitxerNou.getId();
    var urlDescFitxer = fitxerNou.getDownloadUrl();  // Enllaç per descarregar el fitxer
    // Enllaç per veure el fitxer al navegador
    var urlFitxer = "https://drive.google.com/uc?export=view&id=" + idFitxer;  
    var thumb = pdf();
    sendBlobFile(id,thumb,"Valors de la setmana passada");
    realitzat = true;
  }
  if (!realitzat){
    var resposta = "Comanda desconeguda";
    sendText(id,resposta);
  }
}

En aquest exemple se'n pot veure un possible ús.

 

 

 

 

 

 

 

 

 

 

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