Bots de conversa de Telegram amb Google Apps Script

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

Mostrem una llista d'alumnes amb un inline bot

En aquest exemple visualitzarem una llista, en el nostre cas la llista dels alumnes, amb fotografies; fent servir un inline bot. Per començar, hem de crear un full de càlcul que tingui les dades dels alumnes. Cadascú ho pot personalitzar amb les dades que vulgui gestionar, en aquest exemple hem creat aquests camps:

Columna Contingut
1 DNI de l'alumne
Podria ser el número de matrícula
2 Cognoms i nom de l'alumne
3 Grup de l'alumne
4 Subgrup de pràctiques

També crearem una carpeta a Google Drive on guardarem les fotografies dels alumnes. Si volem, el full de càlcul també pot estar en aquesta carpeta. Per poder recuperar les fotografies podríem fer servir el seu identificador i tenir-lo guardat en una altra columna del full de càlcul però hem pensat que es pot fer una mica pesat anar buscant manualment aquests identificadors, per això hem decidit que recuperarem les fotografies a partir del nom del fitxer. Aquest nom ha de ser diferent per a cada alumne i no ens ha de portar problemes, per això hem decidit posar el número de DNI de l'alumne com a nom del fitxer de la fotografia. Quan afegim cada alumne a la llista podrem fer servir el DNI tant per posar-lo a la primera columna com per identificar la fotografia. La carpeta i el seu contingut els llegirem des d'un script al que accedirem amb les nostres credencials, per tant poden ser d'ús restringit. Ens caldrà disposar dels identificadors de la carpeta i del full de càlcul per poder accedir a la informació.

Ara hem de crear el nostre bot. Li podem donar el nom alumnes i posar-li alumnes_bot com a nom d'usuari. Podem editar les opcions per configurar-lo i no hem d'oblidar d'anar a Bot Settings per seleccionar Inline Mode i dir-li Turn On. Després hem de crear l'script.

Per recuperar les fotografies, busquem a la carpeta els fitxers amb l'extensió png que tingui el DNI de l'alumne com a nom de fitxer. El resultat serà un conjunt de fitxers ja que Google Drive admet que hi hagi diversos fitxers amb el mateix nom. Nosaltres suposarem que només hi ha un fitxer al conjunt i agafarem el primer que hagi trobat. Quan tinguem el fitxer, buscarem el seu identificador i generarem l'adreça URL corresponent, per poder-lo mostrar a Telegram.

El nostre script, que podem crear independentment o vincular-lo al full de càlcul, serà el següent:

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 
// Id del full de càlcul (l'obtenim quan el compartim)
var IdFull = "^^ThsoSjkeMSfwEKy4mn_4QEYH96sxv3VURqE3WHCTswDA";
// Id de la carpeta on hi ha les fotos
var IdCarpeta = "^^zuBdQHb6g8gN63NAzBEIBTWt6VsXCt6";
// Imatge genèrica per si no hi ha foto
var foto_alt = "https://drive.google.com/uc?export=view&id=1sPbQLDQjs4tfEiNqpbmSN8pqh5H1v9j-";
var id_usr = "^^9499826";  // El nostre Id de Telegram
function doPost(e){ // Funció que rep les dades enviades, mitjançant post, per Telegram
  var data = JSON.parse(e.postData.contents);  // Tracta les dades rebudes com a JSON i les guarda a dades
  if(data.mesage){  // En cas que no fem servir callback
    var text = data.message.text;  // Recupera el text del missatge (el que escrivim al costat del nom del bot)
    var id = data.message.chat.id;  // Recupera l'identificador de la finestra des de la que s'ha enviat
    var id_usuari = data.message.from.id; // Recupera l'identificador de l'usuari que ha escrit el missatge
    var id_missatge = data.message.message_id; // Recupera l'identificador del missatge
    var update_id = data.update_id  // Recupera l'identificador del missatge final
    var lang = data.message.from.language_code ;  // Llengua que l'usuari té configurada a Telegram 
    var nom_usuari = data.message.from.first_name ;  // Recupera el nom de l'usuari que ha enviat el missatge
    var posicio = data.message.location;  // Recupera la localizació de l'usuari, si és possible
  }
  if(data.callback_query){  // En cas que fem servir callback
    // Recupera l'identificador de l'usuari que ha escrit el missatge
    var id_usuari = data.callback_query.from.id; 
    // Recupera l'identificador de la finestra des de la que s'ha enviat
    var id = data.callback_query.message.chat.id;  
    var id_missatge = data.callback_query.message.message_id; // Recupera l'identificador del missatge
    // Recupera el text del missatge (el que escrivim al costat del nom del bot)
    var text = data.callback_query.data;  
    var usuari = data.callback_query.from.user_name ;  // Recupera el nom de l'usuari que ha enviat el missatge
    var nom = data.callback_query.from.first_name ;  // Recupera el nom de l'usuari que ha enviat el missatge
    var lang = data.callback_query.from.language_code ;  // Llengua que l'usuari té configurada a Telegram 
  }
  if(data.inline_query){  // En cas que fem servir inline
    // Recupera l'identificador de l'usuari que ha escrit el missatge
    var id_usuari = data.inline_query.from.id; 
    var id = data.inline_query.id;  // Recupera l'identificador de la finestra des de la que s'ha enviat
    var id_missatge = data.update_id; // Recupera l'identificador del missatge
    // Recupera el text del missatge (el que escrivim al costat del nom del bot)
    var text = data.inline_query.query;  
    var usuari = data.inline_query.from.user_name ;  // Recupera el nom de l'usuari que ha enviat el missatge
    var nom = data.inline_query.from.first_name ;  // Recupera el nom de l'usuari que ha enviat el missatge
    var lang = data.inline_query.from.language_code ;  // Llengua que l'usuari té configurada a Telegram 
  }
  var sh = SpreadsheetApp.openById(IdFull).getSheetByName("Llistat");  // Agafem el full
  var carpeta = DriveApp.getFolderById(IdCarpeta);  // Agafem la carpeta
  var foto_alt = "https://drive.google.com/uc?export=view&id=1sQbQLDBjs4tdEiNqpbmVN8pqh5H1v9c-";
  var dades = sh.getDataRange().getValues();  // Llegim les dades
  var llista = new Array();
  if (id_usuari == id_usr){  // Si no és l'usuari autoritzat no fa res
    for (var i in dades){  // Llegeix les dades
      if (i > 0){  // Exclou la columna de títols
        var row = dades[i];  // Agafa una filera
        var dni = row[0];
        var nomComp = row[1];
        var grup = row[2];
        var subgrup = row[3];
        var grupComp = grup + "." + subgrup;  // Combina el grup i el subgrup
        // Mirem si a grup hi ha el text que hem entrat al costat del nom del bot
        if (grupComp.indexOf(text) > -1){
          var caption = nomComp;  // Text que acompanya la foto
          // A Google Drive hi pot haver noms de fitxers repetits
          var url_foto = foto_alt;  // Per defecte, agafa la imatge genèrica
          var fotos = carpeta.getFilesByName(dni + ".png");  // Un conjunt de fotos, teòricament
          if (fotos.hasNext()){  // Hi ha alguna foto amb aquest nom
            var foto = fotos.next();  // Agafa la foto
            var id_foto = foto.getId();  // Mira l'identificador per generar la URL
            var url_foto = "https://drive.google.com/uc?export=view&id=" + id_foto;
          }
          // Això és el que surt quan es pica a un dels elements de la llista
          var fitxa = "\n\n" + 
            "Grup: " + grupComp + "\n\n" +
            nomComp + "\n\n" +
            url_foto + "\n\n";
          var item = {
            'type': 'article',
            // Això és el que es veu quan es posa el nom del bot
            'title': grupComp + "    " + caption,
            "thumb_url": url_foto,
            'id': i,
            // Mides de la foto
            'thumb_width': 100,
            'thumb_height': 100,
            // Això és el que surt quan es pica a un dels elements de la llista
            "input_message_content":{
              "message_text": fitxa,
              "parse_mode": "HTML"
            }
          };
          llista.push(item);  // Ho afegeix a la llista
        }
      }
    }
    answerInlineQuery(id, llista);
  }
}
// Funció que envia un text a Telegram
function answerInlineQuery(ident, result){  
  var options = {
    method: "post",
    payload: {
      method: "answerInlineQuery",
      inline_query_id: ident,
      cache_time: 5,
      results: JSON.stringify(result)
    }
  };
  UrlFetchApp.fetch(telegramUrl + '/', options);
} 

Un cop creat script, l'hem d'assignar al nostre bot.

Quan fem servir el bot, podem entrar el número del grup (per exemple, 5) i ens mostrarà els integrants de tots els subgrups del grup demanat. També podem posar el grup i el subgrup (per exemple, 4.2) i ens mostrarà els integrants del subgrup 2 del grup 4. De fet, atès que l'script només mira si el que hem entrat es troba en algun lloc de la composició de grup i subgrup, quan entrem 3 ens mostrarà els alumnes de tots els subgrups del grup 3 i tots els dels subgrups 3 de qualsevol grup. Si ens volem centrar només en els del grup 3 podem entrar 3. i així descartem els que tinguin el 3 en una altra posició que no sigui abans del punt (però, si n'hi ha, ens mostrarà els del grup 13). Podríem variar-ne el comportament canviant el > -1, que només mira si hi és, per un == 0 que comprova si està en la primera posició. Hem fet servir el punt per separar el grup i el subgrup però podríem fer servir qualsevol altre caràcter modificant adequadament la línia on creem la variable grupComp.

Atenció: Els inline bots es poden executar a qualsevol xat o grup. Això implica que hem de ser molt curosos si el nostre bot mostra dades personals. Per evitar que el nostre bot el puguin fer servir altres persones podem fer que l'script comprovi que som nosaltres abans d'enviar la informació. Això és el que fan les línies que hem marcat en groc.

Important: El nostre inline bot ens mostrarà la llista d'alumnes del grup seleccionat només si som nosaltres els que l'estem fent servir però si piquem sobre un dels elements de la llista, la fitxa es mostrarà en el xat des del que estem emprant el bot. Si aquest xat és un grup, tots els membres del grup podran veure aquella fitxa. Cal, doncs, anar amb compte i no fer servir inline bots que continguin dades personals en grups on hi hagi usuaris que no les hagin de veure.

Segona versió

El bot que tenim fins ara ens permet veure la llista d'alumnes però no ens permet fer accions sobre aquesta llista. Anem a fer una nova versió del bot que ens permeti marcar que aquell alumne avui no ha vingut i també veure les faltes d'un alumne concret. El primer que farem serà afegir una columna al nostre full de càlcul.

Columna Contingut
5 Faltes de l'alumne

Guardarem la data de cada falta. Per evitar que el full de càlcul interpreti la data a la seva manera, li posarem davant el signe ^ que també ens servirà per separar una data de l'altra.

Els inline bots no poden executar comandes i, per tant, ens caldrà un segon bot que sí ho pugui fer. Crearem, doncs, un altre bot i també ens caldrà un altre script que també accedirà al full de càlcul. Podrem vincular un dels dos scripts al full de càlcul (és indiferent quin sigui) però no els dos. Aquest segon script executarà les comandes que posem a la fitxa de l'alumne i també podrà respondre a altres comandes que entrem directament al bot. Si volem que les comandes de l'inline bot funcionin, serà necessari emprar-lo només dins el bot que les té definides.

En el nostre cas, posarem dues comandes:

Comanda Finalitat
/falta Posa una falta a l'alumne en la data d'avui
/faltes Llista les dates en les que l'alumne ha faltat

Ara hem de crear l'script per executar les comandes i també modificar l'script de l'inline bot per tal que ens les ofereixi quan mostri la fitxa d'un alumne. Començarem per aquest segon script perquè només són uns petits canvis. A continuació hi ha la funció doPost, que és l'única que canvia. Hem marcat en groc el que hem afegit.

function doPost(e){ // Funció que rep les dades enviades, mitjançant post, per Telegram
  var data = JSON.parse(e.postData.contents);  // Tracta les dades rebudes com a JSON i les guarda a dades
  if(data.mesage){  // En cas que no fem servir callback
    var text = data.message.text;  // Recupera el text del missatge (el que escrivim al costat del nom del bot)
    var id = data.message.chat.id;  // Recupera l'identificador de la finestra des de la que s'ha enviat
    var id_usuari = data.message.from.id; // Recupera l'identificador de l'usuari que ha escrit el missatge
    var id_missatge = data.message.message_id; // Recupera l'identificador del missatge
    var update_id = data.update_id  // Recupera l'identificador del missatge final
    var lang = data.message.from.language_code ;  // Llengua que l'usuari té configurada a Telegram 
    var nom_usuari = data.message.from.first_name ;  // Recupera el nom de l'usuari que ha enviat el missatge
    var posicio = data.message.location;  // Recupera la localizació de l'usuari, si és possible
  }
  if(data.callback_query){  // En cas que fem servir callback
    // Recupera l'identificador de l'usuari que ha escrit el missatge
    var id_usuari = data.callback_query.from.id; 
    // Recupera l'identificador de la finestra des de la que s'ha enviat
    var id = data.callback_query.message.chat.id;  
    var id_missatge = data.callback_query.message.message_id; // Recupera l'identificador del missatge
    // Recupera el text del missatge (el que escrivim al costat del nom del bot)
    var text = data.callback_query.data;  
    var usuari = data.callback_query.from.user_name ;  // Recupera el nom de l'usuari que ha enviat el missatge
    var nom = data.callback_query.from.first_name ;  // Recupera el nom de l'usuari que ha enviat el missatge
    var lang = data.callback_query.from.language_code ;  // Llengua que l'usuari té configurada a Telegram 
  }
  if(data.inline_query){  // En cas que fem servir inline
    // Recupera l'identificador de l'usuari que ha escrit el missatge
    var id_usuari = data.inline_query.from.id; 
    var id = data.inline_query.id;  // Recupera l'identificador de la finestra des de la que s'ha enviat
    var id_missatge = data.update_id; // Recupera l'identificador del missatge
    // Recupera el text del missatge (el que escrivim al costat del nom del bot)
    var text = data.inline_query.query;  
    var usuari = data.inline_query.from.user_name ;  // Recupera el nom de l'usuari que ha enviat el missatge
    var nom = data.inline_query.from.first_name ;  // Recupera el nom de l'usuari que ha enviat el missatge
    var lang = data.inline_query.from.language_code ;  // Llengua que l'usuari té configurada a Telegram 
  }
  var sh = SpreadsheetApp.openById(IdFull).getSheetByName("Llistat");  // Agafem el full
  var carpeta = DriveApp.getFolderById(IdCarpeta);  // Agafem la carpeta
  var foto_alt = "https://drive.google.com/uc?export=view&id=1sQbQLDBjs4tdEiNqpbmVN8pqh5H1v9c-";
  var dades = sh.getDataRange().getValues();  // Llegim les dades
  var llista = new Array();
  if (id_usuari == id_usr){  // Si no és l'usuari autoritzat no fa res
    for (var i in dades){  // Llegeix les dades
      if (i > 0){  // Exclou la columna de títols
        var row = dades[i];  // Agafa una filera
        var dni = row[0];
        var nomComp = row[1];
        var grup = row[2];
        var subgrup = row[3];
        var faltes = row[4];
        var grupComp = grup + "." + subgrup;  // Combina el grup i el subgrup
        // Mirem si a grup hi ha el text que hem entrat al costat del nom del bot
        if (grupComp.indexOf(text) > -1){
          if (faltes.length > 5){
            // El caràcter ^ fa de separador i força a que ho interpreti com a text
            // Restem 1 perquè abans del primer ^ no hi ha cap falta
            var falt = faltes.split("^");
            var num_falt = falt.length -1;
          } else {
            var num_falt = 0;
          }
          var caption = nomComp;  // Text que acompanya la foto
          // A Google Drive hi pot haver noms de fitxers repetits
          var url_foto = foto_alt;  // Per defecte, agafa la imatge genèrica
          var fotos = carpeta.getFilesByName(dni + ".png");  // Un conjunt de fotos, teòricament
          if (fotos.hasNext()){  // Hi ha alguna foto amb aquest nom
            var foto = fotos.next();  // Agafa la foto
            var id_foto = foto.getId();  // Mira l'identificador per generar la URL
            var url_foto = "https://drive.google.com/uc?export=view&id=" + id_foto;
          }
          // Això és el que surt quan es pica a un dels elements de la llista
          var fitxa = "\n\n" + 
            "Grup: " + grupComp + "\n\n" +
            nomComp + "\n\n" +
            num_falt + " faltes\n\n" +
            "Posar /falta_" + i + "\n\n" +
            "Veure /faltes_" + i + "\n\n" +
            url_foto + "\n\n";
          var item = {
            'type': 'article',
            // Això és el que es veu quan es posa el nom del bot
            'title': grupComp + "    " + caption,
            "thumb_url": url_foto,
            'id': i,
            // Mides de la foto
            'thumb_width': 100,
            'thumb_height': 100,
            // Això és el que surt quan es pica a un dels elements de la llista
            "input_message_content":{
              "message_text": fitxa,
              "parse_mode": "HTML"
            }
          };
          llista.push(item);  // Ho afegeix a la llista
        }
      }
    }
    answerInlineQuery(id, llista);
  }
}

Ara, quan llegim les dades d'un alumne també agafem la casella de les faltes. Si no hi ha res o hi ha algun caràcter solt introduït per error deixarem el número de faltes a zero. Si, en canvi, hi ha faltes, les comptarem. A l'hora de comptar, separarem pel caràcter ^ però tenint present que no hi haurà cap data abans del primer i, per tant, la primera component del vector resultant no té interès i no s'ha de comptar. A l'hora de crear la fitxa, mostrem el nombre total de faltes de l'alumne i les dues comandes disponibles.

Quan s'executi la comanda caldrà saber a quin alumne estem fent referència, és a dir que hem de posar un paràmetre a la comanda; en el nostre cas serà el número d'ordre de l'alumne (número de línia) en el full de càlcul. Telegram interpreta com a comanda el text que hi ha des de la / fins al primer espai en blanc. Si posessim el paràmetre separat amb un espai, ens agafaria la comanda sense paràmetre. Per evitar aquest problema, separarem el paràmetre amb un caràcter (en el nostre cas fem servir _ per separar) i ho tindrem en compte a l'script.

Aquest serà l'script que processarà les comandes, que correspondrà al bot de conversa on farem servir el nostre inline bot.

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 
// Id del full de càlcul (l'obtenim quan el compartim)
var IdFull = "^^ThsoSjkeMSfwEKy4mn_4QEYH96sxv3VURqE3WHCTswDA";
// Funció que envia un text a Telegram
// Funció que s'executa quan l'script rep una ordre post
function doPost(e){ // Funció que rep les dades enviades, mitjançant post, per Telegram
  var fet = 0;
  var resposta = '';
  var dades = JSON.parse(e.postData.contents);  // Tracta les dades rebudes com a JSON i les guarda a dades
  // Extraiem les dades
  var text = dades.message.text;  // Recupera el text del missatge
  var id = dades.message.chat.id;  // Recupera l'identificador de la finestra des de la que s'ha enviat
  var id_usuari = dades.message.from.id; // Recupera l'identificador de l'usuari que ha escrit el missatge
  var id_missatge = dades.message.message_id; // Recupera l'identificador del missatge
  var lang = dades.message.from.language_code ;  // Llengua que l'usuari té configurada a Telegram 
  var nom_usuari = dades.message.from.first_name ;  // Recupera el nom de l'usuari que ha enviat el missatge
  var posicio = dades.message.location;  // Recupera la localizació de l'usuari, si és possible
  var bot = dades.message.via_bot;  // Bot que ha enviat la comanda
  // La comanda pot tenir paràmetres, separats amb _
  // Descomposem el text rebut a partir de les _
  var comanda = text.split("_");  // Separa per les _
  var cmd = comanda[0];  // Comanda
  var par = comanda[1];  // Paràmetre
  if (bot){  // Si la crida és des d'un bot, no mostrem el missatge d'error
    fet = 1;
  }
  if (cmd == '/falta'){
    falta(id,par);  // Posa una falta a l'alumne
    fet = 1;
  }
  if (cmd == '/faltes'){
    faltes(id,par);  // Mostra les faltes de l'alumne
    fet = 1;
  }
  // Si no hem entrat a cap if vol dir que la comanda no s'ha reconegut
  if (fet == 0){
    resposta = "Comanda incorrecta" + "\n";
    resposta = resposta + "id_bot = " + id_bot + "\n";
    sendText(id,resposta);
  }
}
function falta(chatId,numAl){
  var sh = SpreadsheetApp.openById(IdFull).getSheetByName("Llistat");  // Agafem el full
  var dades = sh.getDataRange().getValues();  // Agafem el contingut
  var row = dades[numAl];  // Agafa les dades de l'alumne
  var nomComp = row[1];
  var faltes = row[4];
  // Afegim la falta amb la data d'avui
  var ara = new Date();
  // Cal recordar que getMonth compta els mesos començant per 0
  var mes = ara.getMonth() + 1;
  // El caràcter ^ fa de separador i força a que ho interpreti com a text
  faltes = faltes + "^" + ara.getDate() + "-" + mes + "-" + ara.getFullYear();
  // La funció getRange ens permet seleccionar el grup de caselles sobre les que anem a escriure
  // El primer paràmetre és la filera on comença el grup (s'hi suma 1 perquè ara no comença per 0)
  // El segon paràmetre és la columna on comença el grup, en el nostre exemple la cinquena
  var rangeVal = sh.getRange(+numAl + 1, 5);  // Selecciona la casella
  rangeVal.setValue(faltes);  // Guarda el valor a la casella, substituïnt l'anterior
  var resposta = "S'ha posat falta a l'alumne " + nomComp + "\n";
  sendText(chatId,resposta);
}
function faltes(chatId,numAl){
  var sh = SpreadsheetApp.openById(IdFull).getSheetByName("Llistat");  // Agafem el full
  var dades = sh.getDataRange().getValues();  // Agafem el contingut
  var row = dades[numAl];  // Agafa les dades de l'alumne
  var nomComp = row[1];
  var faltes = row[4];
  if (faltes.length > 5){  // Si hi ha alguna falta
    var falt = faltes.split("^");
    var resposta = "Faltes de l'alumne " + nomComp + ":\n";
    // Comencem a 1 perquè abans del primer ^ no hi ha cap falta
    for (var i = 1; i < falt.length; i++){
      resposta = resposta + falt[i] + "\n";
    }
  } else {
    var resposta = "L'alumne " + nomComp + " no té faltes\n";
  }
  sendText(chatId,resposta);
}
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);
}

Si l'usuari entra manualment una comanda no vàlida s'envia un avís. Però no volem que aquest es s'enviï quan es mostra la fitxa d'un alumne; per això, no la mostrem si la comanda s'ha enviat des d'un bot. La funció falta llegeix les faltes de l'alumne i li afegeix la data d'avui al final, per indicar una nova falta. La funció faltes llegeix el nom de l'alumne i les faltes. Després descomposa la llista de faltes, separant pel símbol ^ i les llista. Si no té cap falta, mostra un text alternatiu.

Tercera versió

És poc eficient haver de buscar cada cop l'identificador de l'arxiu de la fotografia. El que podríem fer és que, un cop l'ha buscat un cop, el guardi al full de càlcul per tal que no el calgui tornar a cercar. El primer que farem serà afegir una columna al nostre full de càlcul.

Columna Contingut
6 Id foto

A continuació tenim la nova versió de la funció doPost l'script de l'inline bot, en la que hem marcat en groc les línies que s'han afegit o modificat.

function doPost(e){ // Funció que rep les dades enviades, mitjançant post, per Telegram
  var data = JSON.parse(e.postData.contents);  // Tracta les dades rebudes com a JSON i les guarda a dades
  if(data.mesage){  // En cas que no fem servir callback
    var text = data.message.text;  // Recupera el text del missatge (el que escrivim al costat del nom del bot)
    var id = data.message.chat.id;  // Recupera l'identificador de la finestra des de la que s'ha enviat
    var id_usuari = data.message.from.id; // Recupera l'identificador de l'usuari que ha escrit el missatge
    var id_missatge = data.message.message_id; // Recupera l'identificador del missatge
    var update_id = data.update_id  // Recupera l'identificador del missatge final
    var lang = data.message.from.language_code ;  // Llengua que l'usuari té configurada a Telegram 
    var nom_usuari = data.message.from.first_name ;  // Recupera el nom de l'usuari que ha enviat el missatge
    var posicio = data.message.location;  // Recupera la localizació de l'usuari, si és possible
  }
  if(data.callback_query){  // En cas que fem servir callback
    // Recupera l'identificador de l'usuari que ha escrit el missatge
    var id_usuari = data.callback_query.from.id; 
    // Recupera l'identificador de la finestra des de la que s'ha enviat
    var id = data.callback_query.message.chat.id;  
    var id_missatge = data.callback_query.message.message_id; // Recupera l'identificador del missatge
    // Recupera el text del missatge (el que escrivim al costat del nom del bot)
    var text = data.callback_query.data;  
    var usuari = data.callback_query.from.user_name ;  // Recupera el nom de l'usuari que ha enviat el missatge
    var nom = data.callback_query.from.first_name ;  // Recupera el nom de l'usuari que ha enviat el missatge
    var lang = data.callback_query.from.language_code ;  // Llengua que l'usuari té configurada a Telegram 
  }
  if(data.inline_query){  // En cas que fem servir inline
    // Recupera l'identificador de l'usuari que ha escrit el missatge
    var id_usuari = data.inline_query.from.id; 
    var id = data.inline_query.id;  // Recupera l'identificador de la finestra des de la que s'ha enviat
    var id_missatge = data.update_id; // Recupera l'identificador del missatge
    // Recupera el text del missatge (el que escrivim al costat del nom del bot)
    var text = data.inline_query.query;  
    var usuari = data.inline_query.from.user_name ;  // Recupera el nom de l'usuari que ha enviat el missatge
    var nom = data.inline_query.from.first_name ;  // Recupera el nom de l'usuari que ha enviat el missatge
    var lang = data.inline_query.from.language_code ;  // Llengua que l'usuari té configurada a Telegram 
  }
  var sh = SpreadsheetApp.openById(IdFull).getSheetByName("Llistat");  // Agafem el full
  var carpeta = DriveApp.getFolderById(IdCarpeta);  // Agafem la carpeta
  var foto_alt = "https://drive.google.com/uc?export=view&id=1sQbQLDBjs4tdEiNqpbmVN8pqh5H1v9c-";
  var dades = sh.getDataRange().getValues();  // Llegim les dades
  var llista = new Array();
  if (id_usuari == id_usr){  // Si no és l'usuari autoritzat no fa res
    for (var i in dades){  // Llegeix les dades
      if (i > 0){  // Exclou la columna de títols
        var row = dades[i];  // Agafa una filera
        var dni = row[0];
        var nomComp = row[1];
        var grup = row[2];
        var subgrup = row[3];
        var faltes = row[4];
        var id_foto = row[5];
        var grupComp = grup + "." + subgrup;  // Combina el grup i el subgrup
        // Mirem si a grup hi ha el text que hem entrat al costat del nom del bot
        if (grupComp.indexOf(text) > -1){
          if (faltes.length > 5){
            // El caràcter ^ fa de separador i força a que ho interpreti com a text
            // Restem 1 perquè abans del primer ^ no hi ha cap falta
            var falt = faltes.split("^");
            var num_falt = falt.length -1;
          } else {
            var num_falt = 0;
          }
          var caption = nomComp;  // Text que acompanya la foto
          // A Google Drive hi pot haver noms de fitxers repetits
          if (id_foto.length < 5){
            var url_foto = foto_alt;
            var fotos = carpeta.getFilesByName(dni + ".png");  // Un conjunt de fotos, teòricament
            if (fotos.hasNext()){
              var foto = fotos.next();
              id_foto = foto.getId();
              var rangeVal = sh.getRange(+i + 1, 6);  // Selecciona la casella
              rangeVal.setValue(id_foto);  // Guarda el valor a la casella, substituïnt l'anterior
              var url_foto = "https://drive.google.com/uc?export=view&id=" + id_foto;
            }
          } else {
            var url_foto = "https://drive.google.com/uc?export=view&id=" + id_foto;
          }
          // Això és el que surt quan es pica a un dels elements de la llista
          var fitxa = "\n\n" + 
            "Grup: " + grupComp + "\n\n" +
            nomComp + "\n\n" +
            num_falt + " faltes\n\n" +
            "Posar /falta_" + i + "\n\n" +
            "Veure /faltes_" + i + "\n\n" +
            url_foto + "\n\n";
          var item = {
            'type': 'article',
            // Això és el que es veu quan es posa el nom del bot
            'title': grupComp + "    " + caption,
            "thumb_url": url_foto,
            'id': i,
            // Mides de la foto
            'thumb_width': 100,
            'thumb_height': 100,
            // Això és el que surt quan es pica a un dels elements de la llista
            "input_message_content":{
              "message_text": fitxa,
              "parse_mode": "HTML"
            }
          };
          llista.push(item);  // Ho afegeix a la llista
        }
      }
    }
    answerInlineQuery(id, llista);
  }
}

 

 

 

 

 

 

 

 

 

 

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