Lorsque l’on commence le développement d’un projet de chatbot, un point important (parmi beaucoup d’autres !) est d’implémenter correctement la gestion de la langue. En effet, comment adhérer à l’usage d’un outil qui ne parle pas votre langue ? Il serait dommage de perdre l’utilisateur au premier message !

On va s’intéresser ici à un channel en particulier, celui du webchat, qui est un des plus utilisés mais également un de ceux où l’on possède le moins d’informations sur l’utilisateur, en montrant comment initier la conversation de manière vraiment proactive et ce dans la bonne langue.

 

Problématique du début de conversation :

En effet, on se retrouve rapidement face à deux nécessités :

  • Faire comprendre à l’utilisateur comment utiliser le chatbot via ce webchat, à l’aide d’un texte introductif
  • Pouvoir se faire comprendre de l’utilisateur.

La question du lancement de la discussion, qui plus est dans la bonne langue, est ici critique pour la suite de l’échange avec cet utilisateur.

 

Rappel technique

Pour rappel, un bot est composé de plusieurs éléments :

Schèma foncionnement Bot framework / Webchat

Comme on peut le voir sur le schéma ci-dessus, le Bot Connector (au centre) se charge de faire la liaison entre le code pur de votre projet bot (à gauche) et le channel (à droite), au travers de messages ou plus précisément d'”activités“.

Ces dernières sont de différents types, définis dans la doc Microsoft :

Bot framework / Webchat

La majorité des développeurs utilisant le framework Microsoft reconnaîtront le type contactUpdate régulièrement visible dans l’émulateur et se diront probablement qu’il suffit de récupérer la propriété “locale”. Malheureusement… non !

En effet, l’événement contactUpdate concernant l’utilisateur n’arrive qu’après le 1er message envoyé par ce dernier comme vous pouvez le voir dans l’exemple ci-dessous où j’affiche toutes les activités reçues par le bot :

Bot framework / Webchat

 

Comment faire ? Nous allons tout simplement envoyer l’information depuis le script js servant à intégrer le webchat !

 

Solution de message proactif : utilisation du “backchannel” du Webchat

Remarque : l’ensemble du code de cette démo est disponible sur mon compte Github : https://github.com/nrobert/Bot-Language-Demo

 

Étape 1 – Détermination de la langue :

Si on regarde en détails l’implémentation du webchat de Microsoft (en particulier ici, dont est extrait le bloc ci-dessous), on se rend compte qu’il gère déjà la langue de manière intéressante en :

  • utilisant le paramètre “locale” qui serait placé dans l’URL
  • ou par défaut en récupérant la langue du navigateur

On peut donc profiter du même fonctionnement ou le compléter par d’autres logiques (comme par exemple, récupérer la locale via le site dans lequel est intégré le webchat si ce dernier a l’information).

Étape 2 – Mise en place du code au niveau de l’intégration du webchat

En complément de l’intégration du webchat traditionnelle (ajout du script JS, de la CSS, du div), on ajoute simplement l’envoi d’une activité depuis le JS qui transmettra l’information :

// Get parameters from query
const params = BotChat.queryParams(location.search);

// Language definition - ici on pourrait forcer une locale si besoin
var chatLocale = params['locale'] || window.navigator.language;

// Connection settings
const botConnectionSettings = new BotChat.DirectLine({
    domain: params['domain'],
    secret: 'YOUR_SECRET',  // remplacer le secret par celui de votre bot
    webSocket: params['webSocket'] && params['webSocket'] === 'true' // defaults to true
});

// Webchat init classique
BotChat.App({
    botConnection: botConnectionSettings,
    user: { id: 'userid' },
    bot: { id: 'botid' },
    locale: chatLocale,
    resize: 'detect'
}, document.getElementById('bot'));

// BACKCHANNEL - Send message to provide language of user, and log to console
botConnectionSettings.postActivity({
    type: 'event',
    from: { id: 'userid' },
    locale: chatLocale,
    name: 'localeSelectionEvent',
    value: chatLocale
}).subscribe(function (id) { console.log('event language "' + chatLocale + '" selection sent'); });

Étape 3 – Récupération de l’événement côté bot

Côté bot, on ajoute l’implémentation au niveau du MessagesController, en ajoutant la gestion de l’ActivityTypes.Event :


[BotAuthentication]
public class MessagesController : ApiController 
{
    public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
    {
        // DEMO PURPOSE: echo all incoming activities
        Activity reply = activity.CreateReply(Newtonsoft.Json.JsonConvert.SerializeObject(activity, Newtonsoft.Json.Formatting.None));
        var connector = new ConnectorClient(new Uri(activity.ServiceUrl));
        connector.Conversations.SendToConversation(reply);
        // Process each activity
        if (activity.Type == ActivityTypes.Message)
        {
            await Conversation.SendAsync(activity, () => new Dialogs.RootDialog());
        }
        // Webchat: getting an "event" activity for our js code
        else if (activity.Type == ActivityTypes.Event && activity.ChannelId == "webchat") 
        {
            // HERE WE HAVE OUR INTERESTING VALUE
            var receivedEvent = activity.AsEventActivity();
            if ("localeSelectionEvent".Equals(receivedEvent.Name, StringComparison.InvariantCultureIgnoreCase))
            {
                await EchoLocaleAsync(activity, activity.Locale);
            }
        }
        
        var response = Request.CreateResponse(HttpStatusCode.OK);
        return response;
    }

    private async Task EchoLocaleAsync(Activity activity, string inputLocale)
    {
        Activity reply = activity.CreateReply($"User locale is {inputLocale}, you should use this language for further treatment");
        var connector = new ConnectorClient(new Uri(activity.ServiceUrl));
        await connector.Conversations.SendToConversationAsync(reply);

        // Then you should keep the user locale in UserData to ensure that you stay consistent in your reply language, if the activity.Locale field is not correct
    }
}

 

Ce qui nous fournit bien l’information en amont d’un message de l’utilisateur :

Bot framework / Webchat

Conclusion

Dans cet article, nous avons vu comment passer un paramètre depuis le webchat en utilisant le backchannel pour ensuite améliorer l’expérience de dialogue.

Avec ce mécanisme, on pourrait également passer un paramètre métier comme un identifiant d’utilisateur, un token, etc.

Livre Blanc Cell'insight 7 Cognitive Services

Documentation

Pour rappel, le webchat est open-source et disponible sur Github : https://github.com/Microsoft/BotFramework-WebChat

En particulier, ils proposent un rapide exemple sur le backchannel : https://github.com/Microsoft/BotFramework-WebChat#the-backchannel

Doc Microsoft : https://docs.microsoft.com/en-us/bot-framework/nodejs/bot-builder-nodejs-backchannel

Sources du démonstrateur de cet article : https://github.com/nrobert/Bot-Language-Demo