Ziad Akiki
Ziad Akiki

Reputation: 2680

Sending a greeting/welcome message from the bot as soon as the Webchat control is loaded

I'm developing a bot using Microsoft's Bot framework in C#. I'm trying to send a welcome message to the user as an introduction before he/she sends anything.

After researching, I somewhat achieved this using HandleSystemMessage function and sending the message in the case of a ConversationUpdate as follows:

if (activity.Type == ActivityTypes.ConversationUpdate) 
{
    IConversationUpdateActivity update = activity;
    if (update.MembersAdded.Any())
    {
        foreach (var newMember in update.MembersAdded)
        {
            if (newMember.Id != activity.Recipient.Id)
            {
                ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));

                Activity reply = activity.CreateReply();
                reply.Text("Hello, how can I help you?");
                await connector.Conversations.ReplyToActivityAsync((Activity)bubble);
            }
        }
    }
}

The problem I am facing with this method:

I assume my problem could be solved using another ActivityType perhaps or some Javascript 'hacky' way but I couldn't find a solution up until now.

Upvotes: 3

Views: 3025

Answers (2)

Nicolas R
Nicolas R

Reputation: 14619

For the webchat component, you can use the backchannel functionality to send a hidden message to your bot, in order to launch the greetings.

Heere is a sample of the implementation on the webchat side:

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

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

        // Send hidden message to do what you want
        botConnectionSettings.postActivity({
            type: 'event',
            from: { id: 'userid' },
            locale: chatLocale,
            name: 'myCustomEvent',
            value: 'test'
        }).subscribe(function (id) { console.log('event sent'); });
    </script>
</body>
</html>

On your bot side, you will get this event on your Message Controlelr:

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 ("myCustomEvent".Equals(receivedEvent.Name, StringComparison.InvariantCultureIgnoreCase))
        {
            // DO YOUR GREETINGS FROM HERE
        }
    }
    // Sample for Skype: in ContactRelationUpdate event
    else if (activity.Type == ActivityTypes.ContactRelationUpdate && activity.ChannelId == "skype")
    {
        // DO YOUR GREETINGS FROM HERE
    }
    // 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)
            {
                // DO YOUR GREETINGS FROM HERE
            }
        }
    }

    var response = Request.CreateResponse(HttpStatusCode.OK);
    return response;
}

I made a working demo using this functionality to send the user locale, it's here on Github

Upvotes: 5

Anita George
Anita George

Reputation: 1153

This is a known issue in Web chat.

Using WebChat or directline, the bot's ConversationUpdate is sent when the conversation is created and the user's ConversationUpdate is sent when they first send a message. [1]

A work around would be to send a message to the bot from the web-chat.

<!DOCTYPE html>

<script src="https://cdn.botframework.com/botframework-webchat/latest/botchat.js"></script>
<script>

    var user = {
        id: 'user-id',
        name: 'user name'
    };

    var botConnection = new BotChat.DirectLine({
        token: '[DirectLineSecretHere]',
        user: user
    });

    BotChat.App({
        user: user,
        botConnection: botConnection,
        bot: { id: 'bot-id', name: 'bot name' },
        resize: 'detect'
    }, document.getElementById("bot"));

    botConnection
        .postActivity({
            from: user,
            name: 'requestWelcomeDialog',
            type: 'event',
            value: ''
        })
        .subscribe(function (id) {
            console.log('"trigger requestWelcomeDialog" sent');
        });
</script>

[2]

I didn't change anything in my bot code to achieve this.

Upvotes: 2

Related Questions