Bots de conversa de Telegram amb Google Apps Script

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

Llistem el contingut (directori) d'una carpeta de Google Drive

En aquest exemple crearem un script que ens mostrarà el contingut (carpetes i fitxers) d'una carpeta de Google Drive. La primera versió només mostrarà el llistat, no serà molt útil però ens permetrà entendre les principals funcions implicades. La segona versió, molt més útil, ens mostrarà el llistat mitjançant un conjunt de botons, de manera que picant el botó d'una carpeta podrem accedir a veure'n també el contingut i picant sobre un fitxer el podrem descarregar (si tenim permisos suficients).

Aquest script ens facilita compartir fitxers amb altres persones ja que només cal posar els fitxers en una carpeta per permetre que tots els usuaris de l'script puguin veure la llista i descarregar aquells que els interessin.

Aquest script fa servir només la comanda /drive però es podria ampliar amb més comandes que li permetessin fer altres funcions. Si la comanda va sola es mostra el contingut de la carpeta principal, definida a l'script. La comanda també pot portar com a paràmetre (separat amb una @) l'identificador d'una carpeta i llavors se'ns mostrarà el contingut de la carpeta indicada.

La primera cosa que cal fer és crear el bot de conversa, després cal crear l'script per acabar assignant l'script al bot de conversa.

Script de lectura

Aquest seria l'script. Abans de fer-lo servir cal indicar-li el token, l'adreça de l'script i l'adreça de la carpeta corresponent.

La funció doPost mira quina és la comanda rebuda i si és /drive executa la funció drive. Aquesta funció mira si la carpeta sol·licitada és la carpeta arrel, si no ho és mostra la referència a la carpeta superior (..). Després es llisten les carpetes que conté la carpeta sol·licitada, posant el símbol 📁 al davant de cada una. Finalment es mostra la llista de fitxers i també se'ls posa un símbol Unicode al davant, segons el tipus de fitxer.

var token = "^^34328844:AAFIpk-e7j3UZtYQYQaTduf4hEhnDqIcNXI"; // API Token de Telegram 
var telegramUrl = "https://api.telegram.org/bot" + token;  // Url que comunica el nostre bot amb Telegram 
var webAppUrl = "https://script.google.com/macros/s/^^fycbzXSTtXkzqyM_sABbEZanVX2EuRAIUB5xct53AXp6-MbLscpLHO/exec";
var arrel = "^^zuBdQHb6g8gN63NAzBEIBTWt6VsXCt6";  // Identificador de la carpeta arrel
function doPost(e){  // Funció que rep les dades que envia Telegram 
  var acabat = false;
  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 comanda = text.split("@");  // El signe @ separa la comanda dels paràmetres 
  var cmd = comanda[0];  // Comanda
  var par = comanda[1];  // Paràmetre
  if(cmd == '/drive'){
    drive(id,par);  // Crida a la funció que mostra el contingut de la carpeta
    acabat = true;
  }
  if(!acabat){
    var resposta = "Comanda desconeguda";
    sendText(id,resposta);  
  }
}
function drive(id,carpeta){
  var resposta = "";
  // Pictogrames que farem servir per indicar el tipus de fitxer
  var pic_carpeta = '📁';
  var pic_text = '📄'; 
  var pic_pdf = '📗'; 
  var pic_imatge = '📷'; 
  var pic_audio = '🎧'; 
  var pic_video = '🎦'; 
  var pic_altres = '💾'; 
  // Si hem passat el codi d'una carpeta, vol dir que no és l'arrel
  // Llavors posem l'element .. que representa tornar amunt
  if (carpeta == undefined){
    carpeta = arrel;
  } else {
    resposta = resposta + pic_carpeta + " " + ".." + "\n"; 
  }
  var parent = DriveApp.getFolderById(carpeta); // Creem l'objecte carpeta
  var childFolders = parent.getFolders();
  // Ara llistem primer les carpetes
  while (childFolders.hasNext()) {
    var childFolder = childFolders.next();
    resposta = resposta + pic_carpeta + " " + childFolder.getName() + "\n"; 
  }
  // Despres mostrarem els fitxers de la carpeta 
  var files = parent.getFiles();  // Agafem els fitxers
  while (files.hasNext()) {  // Mentre n'hi hagi
    var pic = pic_altres;  // Per defecte, agafem aquesta icona
    var file = files.next();  // Agafem el fitxer
    var nom = file.getName();  // N'obtenim el nom
    var tipus = file.getMimeType();  // N'obtenim el tipus
    // Segons el tipus, posem la icona
    if(tipus.indexOf('text') > -1){
      pic = pic_text; 
    }
    if(tipus.indexOf('pdf') > -1){
      pic = pic_pdf; 
    }
    if(tipus.indexOf('image') > -1){
      pic = pic_imatge; 
    }
    if(tipus.indexOf('audio') > -1){
      pic = pic_audio; 
    }
    if(tipus.indexOf('video') > -1){
      pic = pic_video; 
    }
    resposta = resposta + pic + " " + nom + "\n";
  }
  sendText(id,resposta);  
  return true ; 
}
function sendText(chatId,text_env,keyBoard){  // Funció que prepara per enviar 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);
}

Script que permet moure's per l'arbre de carpetes

En aquest cas la funció doPost és més complicada. Primer es mira si s'ha enviat una comanda directament o des dels botons del teclat i s'agafen les dades necessàries. Com abans, si la comanda és /drive es passa a la funció drive. Després es mira si hi havia paràmetres. Si no n'hi havia, la carpeta serà l'arrel (definida al començament). Si hi ha un paràmetre, s'agafa com a identificador de la carpeta de treball.

La funció drive fa els mateixos passos que en el cas anterior però ara va guardant la informació, en forma de botons, en una llista que servirà per generar el teclat que s'enviarà a l'usuari. L'usuari veurà un teclat que porta per títol el nom de la carpeta llistada i porta un botó per cada element (fitxer o carpeta) que hi hagi a dins (a més del .. per pujar a un nivell superior.

Fixem-nos que l'usuari veu només uns botons que contenen els noms dels fitxers o carpetes però els identificadors de les carpetes i les adreces URL dels fitxers li queden amagats. Tampoc veu quina és la comanda que es fa servir per canviar de carpeta.

var token = "^^34328844:AAFIpk-e7j3UZtYQYQaTduf4hEhnDqIcNXI"; // API Token de Telegram 
var telegramUrl = "https://api.telegram.org/bot" + token;  // Url que comunica el nostre bot amb Telegram 
var webAppUrl = "https://script.google.com/macros/s/^^fycbzXSTtXkzqyM_sABbEZanVX2EuRAIUB5xct53AXp6-MbLscpLHO/exec";
var arrel = "^^zuBdQHb6g8gN63NAzBEIBTWt6VsXCt6";  // Identificador de la carpeta arrel
function doPost(e){  // Funció que rep les dades que envia Telegram 
  var acabat = false;
  var data = JSON.parse(e.postData.contents);  // Llegeix les dades rebudes per JSON i les guarda
  if (data.callback_query){  // Si és la resposta a un teclat
    var text = data.callback_query.data;  // Resposta del teclat
    var id = data.callback_query.from.id;  // Identificador de la finestra on s'ha escrit el missatge
  }
  if (data.message){  // Si és una comanda normal
    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) 
  }
  if(text.indexOf('@') > -1){
    var comanda = text.split("@");  // El signe @ separa la comanda dels paràmetres 
    var cmd = comanda[0];  // Comanda
    var par = comanda[1];  // Paràmetre
  } else {
    var cmd = text;
    var par = "";
  }
  if(cmd == '/drive'){
    drive(id,par);  // Crida a la funció que mostra el contingut de la carpeta
    acabat = true;
  }
  if(!acabat){
    sendText(id,"Comanda incorrecta");  
  }
}
function drive(id,carpeta){
  var llista = new Array();
  var text_tecla = "";
  var cmd_tecla = "";
  var tecla;
  // Pictogrames que farem servir per indicar el tipus de fitxer
  // Hi ha més pictogrames a: https://www.codetable.net/Group/miscellaneous-symbols-and-pictographs
  var pic_carpeta = '📁';
  var pic_text = '📄'; 
  var pic_pdf = '📗'; 
  var pic_imatge = '📷'; 
  var pic_audio = '🎧'; 
  var pic_video = '🎦'; 
  var pic_altres = '💾'; 
  // Si hem passat el codi d'una carpeta vol dir que no és l'arrel
  // Llavors posem l'element .. que representa tornar amunt
  if (carpeta == ""){
    carpeta = arrel;
    var parent = DriveApp.getFolderById(carpeta); // Creem l'objecte carpeta
  } else {
    // Mirem quina és la carpeta de nivell superior
    var parent = DriveApp.getFolderById(carpeta); // Creem l'objecte carpeta
    var superior = parent.getParents();
    var super_id = superior.next().getId(); 
    // Si no és l'arrel, mostrarem l'opció de pujar amb ..
    if(carpeta != arrel){
      text_tecla = pic_carpeta + " " + "..";
      cmd_tecla = "/drive@" + super_id;
      tecla = {"text":text_tecla,"callback_data":cmd_tecla};
      var filera = new Array(1);
      filera[0] = tecla;
      llista.push(filera);
    }
  }
  var childFolders = parent.getFolders();  // Carpetes que hi ha dintre
  // Ara llistem primer les carpetes
  while (childFolders.hasNext()) {  // Mentre en quedin
    var childFolder = childFolders.next();  // N'agafa una
    text_tecla = pic_carpeta + " " + childFolder.getName();
    cmd_tecla = "/drive@" + childFolder.getId();
    tecla = {"text":text_tecla,"callback_data":cmd_tecla};
    var filera = new Array(1);  // Contindrà una flilera d'un sol botó
    filera[0] = tecla;  // Posem el botó a la filera
    llista.push(filera);  // Afegim la filera a la llista
  }
  // Despres mostrarem els fitxers de la carpeta 
  var files = parent.getFiles();  // Agafem els fitxers
  while (files.hasNext()) {  // Mentre n'hi hagi
    var pic = pic_altres;  // Per defecte, agafem aquesta icona
    var file = files.next();  // Agafem el fitxer
    var nom = file.getName();  // N'obtenim el nom
    var tipus = file.getMimeType();  // N'obtenim el tipus
    var adre = file.getUrl();  // N'obtenim l'adreça
    // Segons el tipus, posem la icona
    if(tipus.indexOf('text') > -1){
      pic = pic_text; 
    }
    if(tipus.indexOf('pdf') > -1){
      pic = pic_pdf; 
    }
    if(tipus.indexOf('image') > -1){
      pic = pic_imatge; 
    }
    if(tipus.indexOf('audio') > -1){
      pic = pic_audio; 
    }
    if(tipus.indexOf('video') > -1){
      pic = pic_video; 
    }
    text_tecla = pic + " " + nom;
    var url_tecla = adre;
    var tecla = {"text":text_tecla,"url":url_tecla};
    var filera = new Array(1);
    filera[0] = tecla;
    llista.push(filera);
  }
  var tecles = {"inline_keyboard":llista};  // Creem el teclat
  var titol = pic_carpeta + " " + parent.getName();
  sendText(id,titol,tecles);  // Envia un mensaje a Telegram usando la función sendText()  
}
function sendText(chatId,text_env,keyBoard){  // Funció que prepara per enviar 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.