Fare domande, ottenere risposte (5)

Quando contattiamo un servizio clienti, per risolvere un problema, o avere informazioni commerciali o lo stato di un abbonamento o di un pagamento ad una pubblica amministrazione, vogliamo sempre la stessa cosa : qualcuno che ci comprenda nel minore tempo possibile.

Il segreto è che l’interlocutore sappia già tutto di noi, non vogliamo ripetere ogni volta la storia dall'inizio: chi sono, il mio abbonamento, i problemi che ho già avuto e risolto con voi, etc.

Se siamo fortunati la persona che raggiungiamo dopo un intricato menù vocale ha già gestito un caso simile e trova velocemente la soluzione sul sistema. Non ci fa domande banali, è simpatica e magari il servizio è anche gratuito. Ma spesso la fortuna non è dalla nostra parte.

I chat Bot hanno il vantaggio di identificarci, di guardare i nostri dati e scoprire le anomalie, di cercare nelle faq accumulate nelle aziende e forse anticipare una risposta.

Nei precedenti post abbiamo visto come usare il servizio API.AI per intercettare le richieste di un utente. In questo e nel successivo vedremo come sviluppare il servizio in Nodejs che fa da ponte tra il Facebook Messenger, i nostri dati e api.ai. Lo schema delle chiamate è quello disegnato in figura :

Schema delle chiamate tra i vari sistemi

Ho deciso di utilizzare Nodejs per sviluppare il servizio, che riceve le chiamate da Facebook, perchè ci sono già numerosi Kit che ne semplificano la realizzazione, inoltre Api.ai ha le librerie per questo linguaggio e si possono trovare su internet Cloud che offrono gratuitamente l’hosting delle applicazioni. E’ possibile creare l’applicazione senza dipendenze da altri tool ma semplificano molto librerie come BotKit e PressBot (gratuito fino a 150k chiamate mensili), in particolare PressBot consente di dare una struttura molto semplice al codice e ha un’interfaccia web di gestione dove si possono caricare i moduli tra i quali quello per api.ai.

Una volta installato e lanciato BotPress si presenta con un sito di amministrazione molto comodo :

BotPress

Sulla dashboard troviamo i moduli già installati e da configurare oltre alle news provenienti dal servizio. Tra i moduli indispensabili trovate botpress-messenger e botpress-api.ai entrambi installabili direttamente dalla dashboard. Una volta fatto vanno configurati con le key di autenticazione in modo che possono interagire con i relativi servizi.

Configurazione di API.AI

Sulla schermata Messenger è possibile indicare le informazioni per creare il menù persistente che altrimenti andrebbe fatto con delle chiamate POST direttamente a facebook.

Configurazione del menù persistente

BotPress ha un file di configurazione per i suoi parametri mentre per quelli dell’applicazione ne ho definito uno specifico che carico in base all'ambiente (dev|prod).

var env=  process.env.BOTPRESS_ENV|| "dev";

bp["config"]= readJsonSync(__dirname + '/config/configuration_'+ env + '.json');

Per l’accesso ai dati, in questo caso un database MySql, ho usato la libreria knexjs che fa anche da ORM.

bp["knex"]=  require('knex')(bp.config.knex);

Ho poi creato delle librerie separate per gestire le varie action definite su API.AI in modo da rendere più leggibile il codice:

//*** SMALLTALK
smalltalk.person(bp);

//*** APPUNTAMENTI
appuntamenti.talk(bp);

//*** APPUNTAMENTI POSTBACK
appuntamenti.postback(bp);

//*** ATTIVITA'
task.talk(bp);

//*** AGGIUNGI ATTIVITA'
task.add(bp);

//*** ATTIVITA' POSTBACK
task.postback(bp);

//*** START
start.talk(bp);

Queste librerie ricevono le chiamate da api.ai e, a seconda dei casi, generano una risposta che può essere testuale, con pulsanti o di pannelli grafici.

Per l’integrazione con api.ai va inclusa questa linea di codice :

var router = bp.getRouter('botpress-apiai', { auth: false });

I moduli hanno una struttura tra loro simile, espongono le funzioni che risponderanno a determinate action definite in api.ai

module.exports = {
person: function (bp) {}
}

In questo caso person intercetta action come “smalltalk.dialog|smalltalk.greetings|smalltalk.user|smalltalk.topics|smalltalk.person|smalltalk.appraisal|smalltalk.agent” che sono quelle dove l’utente fa domande del tipo : come ti chiami? dove vivi ? etc.

La funzione non fa altro che rispondere con quanto definito su api.ai

bp.hear({'nlp.action': /smalltalk.dialog|smalltalk.greetings|smalltalk.user|smalltalk.topics|smalltalk.person|smalltalk.appraisal|smalltalk.agent/i }, (event, next) => {
bp.messenger.sendText(
event.user.id,
event.nlp.fulfillment.speech
)
});

Il testo viene preso nella posizione event.nlp.fulfillment.speech mentre l’utente nel json lo troviamo in event.user.id

Il contenuto di event.user.id è l’identificativo facebook dell’utente che può essere usato per recuperare altre informazioni che non sono presenti nella struttura json degli eventi di BotPress.

Uno degli aspetti fondamentali di un bot è quello di intercettare frasi non comprese dal modulo nlp. In questo caso oltre alla frase “non ho capito” è importante visualizzare dei bottoni con cui intercettare le necessità dell’utente. I bottoni hanno lo scopo di informare l’utente di quali sono le azioni previste nel bot.

bp.hear({'nlp.action': 'input.unknown'}, (event, next) => {

const options = {
quick_replies: [
{
content_type: "text",
title: "Appuntamenti",
payload: "DEVELOPER_DEFINED_FOR_APPOINTMENTS_TODAY_YES"
},
{
content_type:"text",
title:"Attività",
payload: "DEVELOPER_DEFINED_GET_TASK"
},
{
content_type:"text",
title:"Messaggi",
payload: "DEVELOPER_DEFINED_GET_MESSAGE"
}
],
typing: true,
waitRead: true
}

bp.messenger.sendText(event.user.id, event.nlp.fulfillment.speech, options)
.then(() => {
// the message was read because of `waitRead` option
})
});

Nel codice si vedono tre pulsanti con le relative stringhe per i POSTBACK, queste sono delle chiamate dirette al servizio nodejs.

postback: function(bp) {

bp.hear({ platform: 'facebook', type: /postback|quick_reply/i, text: 'DEVELOPER_DEFINED_FOR_APPOINTMENTS_TOMORROW_YES' }, (event, next) => {

Domani(bp,event.nlp,event);
})




bp.hear({ platform: 'facebook', type: /postback|quick_reply/i, text: 'DEVELOPER_DEFINED_FOR_APPOINTMENTS_TODAY_YES' }, (event, next) => {

Oggi(bp,event.nlp,event);

})


},

Nel prossimo post vedremo casistiche più complesse gestite con BotPress.

Show your support

Clapping shows how much you appreciated Torlone Gianfranco’s story.