Search code examples
c#botframeworkdirect-line-botframework

How send event from botframework v3 c# and listen at client side javascript using Direct Line?


How to disable user input by using disabled at wc-shellinput only when some event fires from MessagesController or from any dialog and enable it when desired action accomplished by user. What if I want to navigate web app during conversation with chatbot? How this type of event handling possible?


Solution

  • Here’s how you can get it running, based off of this WebChat sample:

    Add custom ChannelData to your outgoing activity (in bot code)

    See this sample for more info.

    var message = context.MakeMessage();
    

    To Disable Input

    message.ChannelData = new { chatBox = "disable" }
    

    To Enable Input

    message.ChannelData = new { chatBox = "enable" }
    

    Send the message

    await context.PostAsync(message);
    

    Create the event for channelData.chatBox (in index.html script tags)

    const store = window.WebChat.createStore(
        {},
        ({ dispatch }) => next => action => {
        if (action && action.payload && action.payload.activity && action.payload.activity.channelData && action.payload.activity.channelData.chatBox) {
            const event = new Event(`chatBox`);
            event.data = action.payload.activity.channelData.chatBox;
            window.dispatchEvent(event);
        }
    
        return next(action);
        }
    );
    

    Listen for event and enable/disable the chat box (in index.html script tags)

    window.addEventListener('chatBox', ({ data }) => {
        const chatBox = document.querySelector(`[data-id="webchat-sendbox-input"]`);
        switch(data){
            case 'enable':
                chatBox.disabled = false;
                break;
            case 'disable':
                chatBox.disabled = true;
                break;
        }
    });
    

    Enabled:

    enter image description here

    Disabled:

    enter image description here

    Just be sure you ensure you re-enable it after disabling, as needed!

    With BotChat

    It's pretty much the same thing. You're reporting that BotChat isn't detecting all messages, so I used events instead.

    Create/send events

    var disable = new Activity()
    {
        Type = ActivityTypes.Event,
        Value = new { chatBox = "disable" }
    };
    var enable = new Activity()
    {
        Type = ActivityTypes.Event,
        Value = new { chatBox = "enable" }
    };
    await turnContext.SendActivityAsync(disable);
    

    Listen for events in BotChat

    botConnection.activity$
        .subscribe(function (activity) {
            if (activity.type === 'event' && activity.value.chatBox) {
                controlInput(activity.value.chatBox);
            }
        });
    
        function controlInput(action) {
        const chatBox = document.querySelector(`[class="wc-shellinput"]`);
        switch(action) {
            case 'enable':
                chatBox.disabled = false;
                break;
            case 'disable':
                chatBox.disabled = true;
                break;
        }
    }
    

    Note: If you're using the standard BotChat css, the input color doesn't change. You'll need to add the css yourself. Something along the lines of:

    input:disabled {
              background-color: black !important;
          }