Hello! Bonjour! Hola! Since our April 2017 release, you can now create multilingual bots that understand French, English and Spanish! Here’s an overview on how to manage multilingual bots on Recast.AI. 🙂

If you’re not 100% confortable with the basis of bot building on Recast.AI, you can read this article. If you’re all set, then let’s go!

One bot to rule them all

You have two solutions when you want your bot to handle multiple languages. The first one is to duplicate your bot: one for each language. But that means duplicating the logic you have in the Builder section, making it more complicated when you want to make a small change. Doesn’t sound very attractive, does it ? But don’t worry, multilingual doesn’t mean multibot…

The second option is the one we’ve adopted here at Recast.AI: building one single bot, able to understand and reply in multiple languages at the same time! It’s easier to maintain, because everything is in one place.

Let’s see how to you can build a “polybot”!

1 – On the platform

When you create your bot on Recast.AI, you have to choose a default language. You can always change it later, but let me explain to you why a default language matters.

If you don’t pass a language parameter in the requests you make to the API , Recast.AI automatically detects which language your input is in so you can adapt your answers.

If the language detected is not part of the officially supported languages, or if your bot isn’t trained to understand it, we use the bot default language to process the input. Otherwise, the language detected will be used.

You can see for yourself by playing with the language parameter in the console, where “AUTO” corresponds to the “no language passed” part.

You can find all those information in greater details in the man.

Now that your bot is created and able to understand Shakespeare’s language, how do you make it understand Molière’s?
Well, it’s quite simple actually: just go in each of your intents and click on the top signs “+ FR” or “+ ES“. Add a few sentences  (in the right language of course) and TADA, your bot is now able to understand a new language!

Be sure to also set your bot replies in an additional language if you’re using Bot Builder.

Now is the time for a few tips and tricks. A great bot is a well trained bot. The intents should be trained with approximately the same amount of sentences per language. Otherwise, the user experience can become quite deceptive.

Another good practice is to create an intent allowing your users to change the language of the bot during the conversation. An intent triggered by sentences like:

I want to speak spanish!

Do you speak french?

We will see later in this article how to handle this situation on runtime.

2 – In the code

So, now that you have a bot trained to understand multiple languages on the platform, how do you handle it in your code? We use the Node.JS SDK in the examples below, but the content remains true no matter which language you use. You can find other SDKs in Python, PHP, Ruby, Go, and many more on our Github.

When you use the Recast.AI API to analyse an input or to interact with the conversation flow you’ve built in the Builder, you can pass an optional language parameter. We’ve already seen what it implies to specify it above, so let’s now focus on how to use it.

Note: those examples assume you have a 3.x.x version of the recastai package installed. You can find the installation steps here.

You have two options to manage the language parameter with a SDK.

The first one is to pass the language you want to use when you instantiate the Recast.AI client. It’s done once, and you don’t have to manage it in the rest of your code. It’s handy when your bot only uses one language, but not so much when you want to build a polybot, as you will want a bit more of granularity.

var recastai = require('recastai').default

// All the requests we will perform will be processed
// as if they were written in english
var client = new recastai('REQUEST_TOKEN', 'en')

// Processed as english
client.request.analyseText('What\'s the weather in Paris?')
.then(res => {
    // ...some code here...
})

// But you can still overwrite it if you need to
client.request.converseText('Ok', { language: 'fr' })
.then(res => {
    // ...some code here...
})

Note: the language parameter is expected to follow the ISO 639-1 format, so for English it would be “en”, for French “fr”,… You can find the full list here.
In our case, we want the bot to be able to understand multiple languages, so we want to manage it per calls instead of just once.

var recastai = require('recastai').default

// We don't provide the language parameter anymore
var client = new recastai('REQUEST_TOKEN')

// We use the SDK to perform a text analysis
// with the language set as English
client.request.analyseText('What\'s the weather in Paris?', { language: 'en' })
.then(res => {
    // ...some code here...
})
// Here, we interact with a conversation flow built on Recast.AI
// with the language set as french
client.request.converseText('Ok', { language: 'fr' })
.then(res => {
    // ...some code here...
})

Let’s dive a little bit deeper with an example of a bot able to speak both English and French.

A few specs for our polybot: we want to lock the language after the first interaction of the user and the user should have the ability to switch his language from french to english and vice-versa in the middle of the conversation.

To keep it simple, we will store our user language in memory, but you would probably want to store them in a database like MongoDB. Our bot will be connected to Slack using Bot Connector.

Note: if you’ve never used the Bot Connector before, this should enlighten you.
Let’s start by creating an intent called language, allowing our user to switch language during the conversation. We train it both in English and in French.

 

Now let’s create the body of our bot. We use the express module, so our bot can listen to incoming messages from the Bot Connector: 

var express = require('express')
var bodyParser = require('body-parser')
var recastai = require('recastai').default

// We don't provide a language, as we want to use
// the Recast.AI language detection ability the first
// time a user speak to our bot
var client = new recastai('REQUEST_TOKEN')

// Will serve to store our users
var users = []

var app = express()

// Server setup
app.use(bodyParser.json())
app.post('/', function(req, res) {
client.connect.handleMessage(req, res, onMessage)
})
app.listen(5000, () => console.log('Bot is listening on 5000'))

// This function will be called each time
// your bot receive a message
function onMessage(message) {
    // We extract the content of the message
    var content = message.content

    console.log('A message has been received: ', content)
}

The code is quite straightforward, as we import the various modules we need and setup express. Our function onMessage is called each time the bot receives a message from the Bot Connector. We use the users variable to store our user information, but you would probably want to store it in a database.

Now, let’s focus on our onMessage function.

We start by extracting the content of the message we’ve received, and send it to the Recast.AI API to get back the reply we want to return to Bot Connector.

function onMessage(message) {
    // We extract the content of the message
    var content = message.content

    console.log('A message has been received: ', content)
    // Send the content of the message to Recast.AI...
    client.request.converseText(content)
    .then(res => {
        // ...and send back the bot's reply to the Bot Connector
        message.addReply({ type: 'text', content: res.reply() })
    })
}

Now, store the language of the current user to continue the conversation in the same language and avoid confusion with words like “Ok” or “Cool”.

function onMessage(message) {
    var content = message.content
    // Look if the current user exists
    var currentUser = users.find(u => u.senderId === message.senderId)
    var options = {}

    // ...if he does, we pass the language as a parameter
    // to converseText
    if (currentUser) {
        options.language = currentUser.language
    }

    client.request.converseText(content, options)
    .then(res => {
        // ...if he doesn't, add the user to our users list
        if (!currentUser) {
            users.push({ senderId: message.senderId, language: res.processing_language })
        }

        message.addReply({ type: 'text', content: res.reply() })
    })
}

We’ve made quite a few changes here. Now, when a message comes along, we check in the users list if the current user has already talked to our bot. If so, we use the language associated to this user to perform the call to the Recast.AI API. If not, we make the converseText call without the language parameter, and we save the language returned by the API in our users list.

The final touch: if the action detected is the language one, switch the language of the current user from French to English and vice-versa.

function onMessage(message) {
    var content = message.content
    var currentUser = users.find(u => u.senderId === message.senderId)
    var options = {}

    if (currentUser) {
    options.language = currentUser.language
    }

    client.request.converseText(content, options)
    .then(res => {
        var action = res.action

        if (!currentUser) {
            currentUser = { senderId: message.senderId, language: res.processing_language }
            users.push(currentUser)
        }

        // If the action is the language one...
        if (action && action.slug === 'language') {
            // ...switch the language of the user
            var index = users.findIndex(u => u.senderId === currentUser.senderId)
            var newLanguage = currentUser.language === 'fr' ? 'en' : 'fr'
            users[index].language = newLanguage
        }

        message.addReply({ type: 'text', content: res.reply() })
    })
}

This bit of code is pretty simple to handle two languages.

If you want your bot to be able to understand three languages or more, you have to use entities (“language” gold entity actually) to know in which language the user is speaking to your bot. You can find more information about entities here.

3 – Conclusion

Well hey, ain’t that a multilingual bot if I’ve ever seen one! If you’re waiting for a language we haven’t rolled out yet, subscribe to our newsletter to be informed of new releases! 

If you want to use the polybot made for this article, you can fork it here. Happy coding!

Want to build your own conversational bot? Get started with Recast.AI !

Subscribe to our newsletter


There are currently no comments.