2
votes

I would like to implement a welcome message for every members added based on their locale. The code is as following:

if (message.Type == ActivityTypes.ConversationUpdate)
{
    // some code...

    if (message.Locale == "en-us")
    {
        var reply = message.CreateReply("Hello world");
    }
    else
    {
        // some code...
    }


    // some code...
}

Strangely, the locale is null even though I've set the locale both when I test it using bot emulator and BotFramework-WebChat. The locale property is working fine when messages is received.

Is there any way I could get the locale during conversationUpdate activity?

Thank you in advance!

2
I made an article on my company's blog on this problem, but it's currently in French. I will add a reply as soon as I canNicolas R

2 Answers

4
votes

One solution to get the language of the user before his 1st input is to use the backchannel feature of the Webchat. This allows us to push information to our bot in a hidden way, to provide locale or a custom id for example.

You will found this demo on GitHub account here.

In particular, here is the sample of integration of your webchat sending the event to the bot at the end with a postActivity, created from the samples on Microsoft's Webchat GitHub description:

<!DOCTYPE html>
<html>
<head>
    <link href="https://cdn.botframework.com/botframework-webchat/latest/botchat.css" rel="stylesheet" />
</head>
<body>
    <div id="bot" />
    <script src="https://cdn.botframework.com/botframework-webchat/latest/botchat.js"></script>
    <script>
        // Get parameters from query
        const params = BotChat.queryParams(location.search);

        // Language definition
        var chatLocale = params['locale'] || window.navigator.language;

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

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

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

I added a console event to show the activity posted.

This event is then received by the bot's MessageController and treated:

[BotAuthentication]
public class MessagesController : ApiController
{
    /// <summary>
    /// POST: api/Messages
    /// Receive a message from a user and reply to it
    /// </summary>
    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")
        {
            var receivedEvent = activity.AsEventActivity();

            if ("localeSelectionEvent".Equals(receivedEvent.Name, StringComparison.InvariantCultureIgnoreCase))
            {
                await EchoLocaleAsync(activity, activity.Locale);
            }
        }
        // Sample for emulator, to debug locales
        else if (activity.Type == ActivityTypes.ConversationUpdate && activity.ChannelId == "emulator")
        {
            foreach (var userAdded in activity.MembersAdded)
            {
                if (userAdded.Id == activity.From.Id)
                {
                    await EchoLocaleAsync(activity, "fr-FR");
                }
            }
        }

        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);
    }
}

Illustration de l'arrivée des messages : Exemple messages

For French speaking users, here is a more detailed answer on my company's blog

0
votes

With DirectLineJs 0.13.0, a property has been added that allows to specify the start locale like this:

...
createDirectLine({
  token: tokenResponse.token,
  domain: `https://europe.directline.botframework.com/v3/directline`,
  pollingInterval: 500,
  conversationStartProperties: {
    locale : "fr"
  },
  watermark: "-",
})