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 :
For French speaking users, here is a more detailed answer on my company's blog