JavaScript, HTML, CSS e... !
12 commenti

Mostra una Tastiera Virtuale nei Bot di Telegram

Telegram Bot con Inline Keyboard in Google Sheets

Con un Bot di Telegram è possibile mostrare all'utente una serie di bottoni cliccabili che effettuano un'azione.

In un altro mio video sull'argomento ho mostrato come creare un bot che pone una domanda all'utente, attende la sua risposta e in base al testo inserito fornisce a sua volta una risposta pertinente in modo automatico: https://www.youtube.com/watch?v=cSK-RFiVMv0

Sullo stesso principio voglio mostrarti in questo video come adattare il codice affinché l'utente possa visualizzare, insieme al messaggio del bot, una tastiera virtuale con una serie di bottoni dove gli basterà cliccare su uno di essi per scegliere la sua risposta. Questa funzionalità prende il nome di inline keyboard, appunto tastiera in linea. Se inizi ora con i Bot di Telegram ti consiglio il mio video su come crearne uno in 5 minuti che ti servirà da base per tutte le tue integrazioni di funzionalità: https://www.youtube.com/watch?v=cmQ2fxETY3A

La funzione che ho chiamato sendKeyboard effettua la stessa cosa di sendMessage, ovvero invia un messaggio all'utente, tuttavia dovendo gestire parametri più avanzati rispetto ad un semplice messaggio di testo, come appunto l’oggetto che conterrà le informazioni della nostra tastiera virtuale, sfrutta il metodo post e la sua sintassi è diversa.

Questo oggetto è definito nella funzione doPost(e), che ricordo che in Google Apps Script è la prima ad essere chiamata ogni volta che la Web app viene sollecitata.
Nella sua struttura, per ogni elemento che voglio che venga visualizzato sotto forma di bottone deve essere indicato il testo che comparirà sul bottone e il nome del riferimento che sarà passato al Bot di Telegram per fargli capire dove è avvenuto il click in modo da agire di conseguenza attivando una funzione di callback.

Dal momento che il Bot deve riuscire a capire se si tratta di un messaggio generico dell'utente oppure del click sulla tastiera virtuale che gli abbiamo proposto, diventa di centrale importanza inserire un’istruzione condizionale che verifica appunto se si tratta di un callback o di un normale inserimento di un messaggio di testo. È proprio in questo secondo caso che il bot mostrerà all'utente i bottoni cliccabili. Dopo aver recuperato il riferimento alla chat dove scrivere e le informazioni di nome e cognome dell'utente per poterlo salutare e indicargli quello che dovrà fare, passiamo il tutto alla funzione sendKeyboard che abbiamo descritto con appunto l'oggetto JSON della tastiera.

A questo punto quello che succederà nella chat di Telegram sarà mostrare il messaggio di testo appena visto e una serie di bottoni cliccabili contenenti i nomi degli aperitivi, ovvero questo risultato. Il bot rimarrà in attesa della scelte dell'utente, se questo cliccherà su uno dei bottoni verrà attivata la relativa funzione di callback.

Non resta altro che effettuare il deployment di una nuova versione dell'applicazione da 'Gestisci deployment'. Se invece è la prima volta che pubblichi l’app dovrai prima eseguire una funzione manualmente per avviare il processo di autorizzazioni e successivamente effettuare un 'Nuovo deployment'. Nel video puoi vedere il risultato dal vivo, dove inizio con un saluto che, essendo un messaggio di testo generico (e non un'azione di ritorno dal click su un bottone che non ho ancora visualizzato), ottengo in risposta il benvenuto e l'invito a scegliere il nome di un drink tra quelli selezionabili nella tastiera virtuale che appare subito dopo il messaggio. Allo stesso tempo, le mie selezioni sono state salvate in ordine cronologico nel Foglio1.

Ecco il codice mostrato nel video:

var token = getTokenId(); // ho nascosto il valore del token nel file token_id.gs per non mostrarlo a video
var telegramUrl = "https://api.telegram.org/bot" + token;
var webAppUrl = "https://script.google.com/macros/s/ID_WEB_APP/exec";

function setWebhook() {
  var url = telegramUrl + "/setWebhook?url=" + webAppUrl;
  var response = UrlFetchApp.fetch(url);
}

function sendMessage(chat_id, text) {
  var url = telegramUrl + "/sendMessage?chat_id=" + chat_id + "&text=" + text;
  var response = UrlFetchApp.fetch(url);
}

function sendKeyboard(chatId, text, keyboard) {
  var data = {
    method: "post",
    payload: {
      method: "sendMessage",
      chat_id: String(chatId),
      text: text,
      parse_mode: "HTML",
      reply_markup: JSON.stringify(keyboard)
    }
  };
  UrlFetchApp.fetch('https://api.telegram.org/bot' + token + '/', data);
}

function doPost(e) {

  var contents = JSON.parse(e.postData.contents);

  var keyboard = {
    "inline_keyboard": [
      [{
        "text": "Americano",
        "callback_data": "americano"
      }],
      [{
        "text": "Spritz",
        "callback_data": "spritz"
      }],
      [{
        "text": "Caipirinha",
        "callback_data": "caipirinha"
      }],
      [{
        "text": "Manhattan",
        "callback_data": "manhattan"
      }],
      [{
        "text": "Margarita",
        "callback_data": "margarita"
      }],
      [{
        "text": "Mojito",
        "callback_data": "mojito"
      }]
    ]
  }

  if (contents.callback_query) {

    var chat_id = contents.callback_query.from.id;
    var user = contents.callback_query.message.chat.first_name + " " + contents.callback_query.message.chat.last_name;
    var cb_data = contents.callback_query.data;

    var ssId = "SPREADSHEET_ID";
    var sh2 = SpreadsheetApp.openById(ssId).getSheetByName("Foglio2");
    var sh2range = sh2.getRange(1, 1, sh2.getLastRow(), sh2.getLastColumn());
    var sh2values = sh2range.getValues();
    var sh2values_len = sh2values.length;
    var cocktail_nome;
    for (i = 0; i < sh2values_len; i++) {
      cocktail_nome = sh2values[i][0] + '';
      if (cb_data == cocktail_nome.toLowerCase()) {
        answer = "Ingredienti: " + sh2values[i][1] + '.' + '%0A' + "Preparazione: " + sh2values[i][2];
        break;
      }
    }

    sendMessage(chat_id, answer);
    SpreadsheetApp.openById(ssId).getSheetByName("Foglio1").appendRow([new Date(), chat_id, user, cb_data]);

  } else if (contents.message) {

    var chat_id = contents.message.from.id;
    var user = contents.message.chat.first_name + " " + contents.message.chat.last_name;

    var answer = "Ciao " + user + ". Seleziona il nome di un cocktail e ti dirò come prepararlo!";
    sendKeyboard(chat_id, answer, keyboard);

  }
}

Fammi sapere nei commenti del video cosa ne pensi di questo tutorial oppure se hai un dubbio o un suggerimento che vuoi darmi.

Rinnovo l'invito a iscriverti al mio canale, se ancora non l'hai fatto, per rimanere aggiornato sui prossimi video e... a presto. Ciao! ;)

Tags

Michele Pisani

Michele Pisani

Sviluppatore Javascript ed esperto in Digital Analytics

L'esperienza nel settore Digital Analytics unita ad anni di sviluppo in Javascript ha trovato la massima espressione in Google Apps Script che mi ha permesso, con estrema facilità e poche righe di codice, di realizzare potenti applicazioni interattive e processi automatizzati integrati con i prodotti della G Suite.

Come contattarmi
scrivi un commento

12 Commenti

  1. giovedì 27 gennaio 2022 alle ore 09.37 Andre

    Buongiorno, video utilissimi. Non riesco a trovare come richiamare la funzione keyboard del bot solamente alla digitazione di una certa parola...dove andrebbe inserito il controllo?

    Rispondi a questo commento
    • giovedì 27 gennaio 2022 alle ore 11.58 Michele PisaniAutore

      Ciao Andre,
      dovresti vedere nella documentazione delle Telegram Bot API se esiste un metodo che intercetta la scrittura dell'utente anche prima dell'invio del messaggio. In questo caso quindi il problema non sta nel codice in questione ma nella fattibilità tecnica offerta da Telegram.

      Rispondi a questo commento
  2. martedì 26 aprile 2022 alle ore 21.10 SD

    Hi i tried using your contents.callback_query but it doesn't seem to get the input after i press a button. it only reads the else if(contents.message) any workaround on this?

    Rispondi a questo commento
  3. martedì 26 aprile 2022 alle ore 22.50 SD

    At the moment there are no errors on doPost function so i'm not really sure what i'm missing here.

    Here's the full code
    function doPost(e) {
    var contents = JSON.parse(e.postData.contents);
    var text = contents.message.text;
    var name = contents.message.from.first_name + " " + contents.message.from.last_name;
    var keyboard = {
    "inline_keyboard": [
    [{
    "text": "americano",
    "callback_data": "americano"
    }]
    ]
    }

    if(contents.callback_query) {
    var id = contents.callback_query.from.id;
    sendText(id,"Submit");
    }
    else if {
    sendText(id,"Here are the buttons");
    sendKeyboard(id,text,keyboard);
    }
    }

    Rispondi a questo commento
    • martedì 26 aprile 2022 alle ore 22.51 SD

      CORRECTION**

      else if (contents.message){
      var id = contents.message.from.id;
      sendText(id,"Here are the buttons");
      sendKeyboard(id,text,keyboard);
      }
      }

      Rispondi a questo commento
      • mercoledì 27 aprile 2022 alle ore 18.17 Michele PisaniAutore

        Are there any special characters in the reply message?

      • mercoledì 27 aprile 2022 alle ore 18.37 Michele PisaniAutore

        Try to use sendMessage(id,"Here are the but tons") instead of sendText(id,"Here are the buttons") , anyway you have to define id in the else statement too.

  4. giovedì 12 maggio 2022 alle ore 12.04 Isac

    Ciao Michele, vorrei richiamare con i pulsanti una pagina al posto di una casella, praticamente creare un sorta di menù.Puoi darmi dei consigli....

    ringrazio

    Rispondi a questo commento
    • martedì 17 maggio 2022 alle ore 22.09 Michele PisaniAutore

      Ciao Isac,
      cosa intendi con "richiamare una pagina" e "creare una sorta di menu"? Se ti riferisci ad un bottone che apre un URL ti lascio il link di riferimento alla documentazione ufficiale: https://core.telegram.org/bots/2-0-intro#url-buttons

      Rispondi a questo commento
      • mercoledì 18 maggio 2022 alle ore 11.54 Isac

        Ciao grazie per la risposta, sinceramente non ho idea su come usare un le API di telegram, sarebbe interessante un tutorial in merito, in generale come si usano con un esempio semplice.
        Per il menù intedo questo: Ho realizzato 3 ricette su 3 fogli differenti, ora vorrei realizzare tre bottoni, uno per la ricetta X, il secondo per la Y, la terza per la Z, premendo sul pulsante X si aprirà la ricetta X , una volta aperta la ricetta X, vorrei eseguire la ricerca delle ricette inserendo il testo, es: scrivo Spritz e in automatico mi trova gli ingredienti.
        Praticamente i tre bottoni devono soltanto spostarmi di foglio.
        Sul tuo libro è menzionato qualcosa su Telegram?
        Ringrazio

      • mercoledì 18 maggio 2022 alle ore 17.56 Michele PisaniAutore

        Ciao Isac,
        in questo caso non si tratta di una questione di Bot di Telegram ma di utilizzo di Google Apps Script con i Fogli Google. Lo script è praticamente il medesimo del mio tutorial, quello che cambia è dove indicare da quale Foglio prendere le informazioni in base al bottone cliccato, che è indipendente da come funzionano i Bot di Telegram. L'uso di Apps Script da questo punto di vista è sicuramente dettagliato nel mio primo libro "Punta in Alto con... Google Apps Script". Non tratta nello specifico di Bot di Telegram ma delle logiche e funzionamento di Apps Script che puoi applicare ai Bot.

Scrivi un commento

Il tuo indirizzo email non sarà pubblicato.I campi contrassegnati da un * sono obbligatori
Puoi utilizzare i seguenti tag nei commenti:
[bold]testo[/bold] se vuoi evidenziare un testo con il grassetto[code]function helloworld() { }[/code] se vuoi pubblicare una porzione di codice[url]https://www.appsscript.it[/url] se devi riferirti ad un indirizzo web