question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How to send Welcome Message in Web Chat

See original GitHub issue

Flow

ASP.NET Core MVC View [loads webchat] -> Controller gets token generated -> Bot Channels Registration -> Bot service

Though followed backchannel sample, it does not get the welcome message. The same backchannel works for simple html page, but not Razor based view page.

Any thoughts what could be missing here?

View page (token is generated on server side)

@model EchoAuthBot.ClientApp.ChatConfig;

@{
    ViewData["Title"] = "Index";
}

<!DOCTYPE html>
<html>
<body>
    <h1>Index</h1>

    <div id="webchat" role="main"></div>
    @*<script src="https://cdn.botframework.com/botframework-webchat/master/webchat-es5.js"></script>*@
    <script src="https://cdn.botframework.com/botframework-webchat/master/webchat.js"></script>
    <script>
        // Get welcome message
        // We are using a customized store to add hooks to connect event
        const store = window.WebChat.createStore({}, ({ dispatch }) => next => action => {
            //console.log(action);
            if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') {
                dispatch({
                    type: 'WEB_CHAT/SEND_EVENT',
                    payload: {
                        name: 'webchat/join',
                        value: { language: window.navigator.language }
                    }
                });
            }

            return next(action);
        });

        // Set the StyleOptions for avatar
        const styleOptions = {
            botAvatarInitials: 'WC',
            userAvatarInitials: 'WW'
        };

        // Render the webchat control
        window.WebChat.renderWebChat({
            directLine: window.WebChat.createDirectLine({ token: `@Model.Token.ToString()` }),
            store,
            userID: `@Model.UserId.ToString()`,
            username: 'Web Chat User',
            locale: 'en-US',
            styleOptions
        }, document.getElementById('webchat'));
        document.querySelector('#webchat > *').focus();
    </script>
</body>
</html>

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:22 (10 by maintainers)

github_iconTop GitHub Comments

4reactions
tdurnfordcommented, Nov 21, 2019

Here is how Welcome Messages in Web Chat should be handled with the updates to the Direct Line Connector Service.

Web Chat Welcome Messages

Channels generally send two conversation update events when the conversation is initialized - the first for the bot and another for the user. The second conversation update - the event for the user - is intended to trigger the welcome message. At the moment, Web Chat has two different welcome message scenarios that are slightly different from other channels and based on how the developer generates the Direct Line token.

Tokens with User IDs

The first scenario is dependent on the token request including a user ID. If the developer includes a user ID when generating the token, Direct Line will only send one conversation update event to the bot that includes two user IDs in the activity’s membersAdded property - one for the bot and one for the user. Following this configuration should trigger the traditional welcome message in the onMembersAdded handler before the user messages the bot.

In the example below, the user ID is added to the token request and the welcome message is sent from the onMembersAdded handler.

Web Chat

(async function () {
  // Note, for the simplicity of this example, we are generating the Direct Line token on client side;
  // however, this is not a recommended practice and you should create and manage your tokens from the server. 
  // You should never put the Direct Line secret in the browser or client app.
  // https://docs.microsoft.com/en-us/azure/bot-service/rest-api/bot-framework-rest-direct-line-3-0-authentication
  const secret = '<DIRECT_LINE_SECRET> | <WEB_CHAT_SECRET>';
  const res = await fetch('https://directline.botframework.com/v3/directline/tokens/generate', { 
    body: JSON.stringify({ user: { id: 'dl_user_id', name: 'username' }}),
    headers: {
      Authorization: `Bearer ${secret}`,
      'Content-type': 'application/json'
    },
    method: 'POST',
  });
  const { token } = await res.json();

  window.WebChat.renderWebChat({
    directLine: window.WebChat.createDirectLine({ token })
  }, document.getElementById('webchat'));

  document.querySelector('#webchat > *').focus();
})().catch(err => console.error(err));

Bot Framework SDK v4 (Node.js)

this.onMembersAdded(async (context, next) => {
  const { membersAdded } = context.activity;

  for (let member of membersAdded) {
    if (member.id !== context.activity.recipient.id) {
      await context.sendActivity("Welcome Message from `onMembersAdded` handler!");
    }
  }
  await next();
});

Tokens, User IDs, and iFrames

To achieve this in an iFrame of Web Chat, retrieve your token with user ID as described above and pass the token within the src attribute of the iFrame: <iframe src='https://webchat.botframework.com/embed/YOUR_BOT_HERE?t=YOUR_TOKEN_HERE' style='min-width: 400px; width: 100%; min-height: 500px;'></iframe>

Secrets and Tokens without User IDs

Alternatively, conversations created with tokens that do not include a user ID send two conversation update events. Direct Line sends the first conversation update - the one for the bot - when the connection with the bot is established. Direct Line sends the second conversation update for the user after they send their first message.

Generally, users anticipate the bot to send a welcome message before they send a message. To do this, you can dispatch a backchannel welcome event from Web Chat’s store middleware when the Direct Line connection is established. Then in the onEvent handler, you can send a welcome message. Note, in the onMembersAdded handler you should check which channel is sending the event before sending the welcome message. If the channel id is “webchat” or “directline” you should not send the traditional welcome message to avoid sending multiple welcome messages.

Web Chat

(async function () {
  // Note, for the simplicity of this example, we are generating the Direct Line token on client side;
  // however, this is not a recommended practice and you should create and manage your tokens from the server. 
  // You should never put the Direct Line secret in the browser or client app.
  // https://docs.microsoft.com/en-us/azure/bot-service/rest-api/bot-framework-rest-direct-line-3-0-authentication
  const secret = '<DIRECT_LINE_SECRET> | <WEB_CHAT_SECRET>';
  const res = await fetch('https://directline.botframework.com/v3/directline/tokens/generate', { 
    headers: {
      Authorization: `Bearer ${secret}`,
    },
    method: 'POST'
  });
  const { token } = await res.json();

  const store = window.WebChat.createStore(
    {},
    ({ dispatch }) => next => action => {
      if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') {
        dispatch({
          type: 'WEB_CHAT/SEND_EVENT',
          payload: {
            name: 'webchat/join',
          }
        });
      }
      return next(action);
    }
  );

  window.WebChat.renderWebChat({
    directLine: window.WebChat.createDirectLine({ token }),
    store
  }, document.getElementById('webchat'));

  document.querySelector('#webchat > *').focus();
})().catch(err => console.error(err));

Bot Framework SDK v4 (Node.js)

this.onEvent(async (context, next) => {
  if (context.activity.name === 'webchat/join') {
    await context.sendActivity('Back Channel Welcome Message!');
  }
  await next();
});

this.onMembersAdded(async (context, next) => {
  const { channelId, membersAdded } = context.activity;

  if (channelId !== 'directline' && channelId !== 'webchat') {
    for (let member of membersAdded) {
      if (member.id !== context.activity.recipient.id) {
        await context.sendActivity("Welcome Message from `onMembersAdded` handler!");
      }
    }
  }
  await next();
});

For more details regarding backchannel welcome events in Web Chat, take a look at this sample.

Additional Context

1reaction
venkatx5commented, Aug 12, 2020

I’m trying to implement this to pass parameters when a chat session starts.

const store = window.WebChat.createStore( {}, function() { return function(next) { return function(action) { if (action.type === ‘DIRECT_LINE/POST_ACTIVITY’) { // tried various type such as DIRECT_LINE/CONNECT_FULFILLED action = window.simpleUpdateIn( action, [‘payload’, ‘activity’, ‘channelData’], () => ({ ‘email’: “testemail@test.com”, ‘projectId’: projectId, }) ) } return next(action); } } } );

The question is: How can I access this data from the first waterfall step of MainDialog ?

Right now, In DialogAndWelcomeBot, where OnMembersAddedAsync resides, I have managed to override OnEventAsync and I have access to the parameters but I’m unable to access them and use them from Maindialog.

protected override async Task OnEventAsync(ITurnContext turnContext, CancellationToken cancellationToken) { await base.OnEventAsync(turnContext, cancellationToken); string channelObj = string.Empty; Newtonsoft.Json.Linq.JObject channelData = null; string email = string.Empty; try { channelObj = turnContext.Activity.ChannelData.ToString(); } catch (Exception exc) { string errorMsg = string.Empty; errorMsg = "channelObj error in OnEventAsync: " + exc.Message; LogMessage(turnContext, cancellationToken, errorMsg); }

        try
        {
            channelData = Newtonsoft.Json.Linq.JObject.Parse(channelObj);
        }
        catch (Exception exc)
        {
            string errorMsg = string.Empty;
            errorMsg = "channelData error in OnEventAsync" + exc.Message;
            LogMessage(turnContext, cancellationToken, errorMsg);
        }
        try
        {
            email = channelData["email"].ToString();
        }
        catch (Exception exc)
        {
            string errorMsg = string.Empty;
            errorMsg = "email error in OnEventAsync: " + exc.Message;
            LogMessage(turnContext, cancellationToken, errorMsg);
        }

—> The following is an attempt to store in UserState but it doesn’t work IStatePropertyAccessor accessor = UserState.CreateProperty(nameof(OnboardingState)); OnboardingState state = await accessor.GetAsync(turnContext, () => new OnboardingState()); state.Ticket = new CIWTicket(); state.Ticket.SourceEmailAddress = email; await UserState.SaveChangesAsync(turnContext, false, cancellationToken); LogMessage(turnContext, cancellationToken, "email in OnEventAsync : " + email); }

    private async void LogMessage(ITurnContext sc, CancellationToken cancellationToken, string message)
    {
        var msg = MessageFactory.Text(message, message, InputHints.IgnoringInput);
        await sc.SendActivityAsync(msg, cancellationToken);
    }

Thanks a lot for the code. Saved my day!

Read more comments on GitHub >

github_iconTop Results From Across the Web

18 Best Live Chat Welcome Messages to Improve Conversion
Explore 18 live chat welcome message examples that set the right course for client interactions and improve visitor engagement right off the ...
Read more >
10 Best Welcome Messages for Customers [Examples ... - Tidio
A selection of the most effective short welcome messages for customers. Welcome texts, notes, and message templates that you can use for ...
Read more >
Live Chat Welcome Messages: Use Cases & Best Practices
Best Welcome Message Practices (With Examples) ; 1. Personalize The Experience · A warm welcome text; Clean background ; 2. Make Sure to...
Read more >
Live Chat's Welcome Message: Best Tips About Websites ...
Live Chat's Welcome Message: Best Tips About Websites' Greetings. Greetings pop up on your site, encouraging visitors to talk to you.
Read more >
How to customise the welcome message in PEGA Web Chat ...
Go to the chat-bot which is there in channels and interfaces and there you can see the welcome message. There you can customise...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found