1
votes

The new version of the standard webchat channel ("gemini") stripped out all of the formatting. I was able to replicate most of the old interface via tweaks in the botframework-webchat implementation, but I cannot get the adaptive card formatting to match. With the general formatting I was able to get it close, and the adaptiveCardHostConfig tweaks shown here on Github got a bit closer, but I still can't figure out how to replicate it. Specifically, the chat bubble (which is gray in my implementation) no longer appears behind the adaptive card. This is especially noticeable for carousels, where it used to be one "bubble" with multiple cards and is now discrete cards. Furthermore, the buttons are no longer interactive (blue border used to appear on mouseover), and the bublle "nub" is absent. Please see below for examples. Note that I DO know how to make the background for the card itself gray to match the bubbles, but that is not the look that I want or that displayed previously.

In summary, I'm asking

  1. How can I format the gray background like was present in the previous version.
  2. How can I add the bubble nub to the card (or perhaps more accurately, make the card appear inside a bubble).
  3. How can I make the buttons on the adaptive card interactive

Single Card (new on left, old on right) single-card

Carousel (new on left, old on right) enter image description here

And here is the website code

<!DOCTYPE html>
<html>
    <head>
        <title>Support Bot</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />

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

        <style>
        html,
        body {
            height: 100%;
        }

        body {
            margin: 0;
        }

        html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, table, caption, tbody, tfoot, thead, tr, th, td {
            margin: 0;
            padding: 0;
            border: 0;
        }

        #chatbotTitle {
            display: flex;
            align-items: center;
            height: 40px;
            width: 100%;
            background-color: #0067CC;
            color: #FFFFFF;
            font-family: Calibri, Helvetica Neue, Arial, sans-serif;
            justify-content: space-between;
        }

        #webchat {
            height: calc(100% - 40px);
            width: 100%;
        }

        .btn {
            display: flex;
            background-color: white;
            border: 1px solid #767676;
            color: #0067CC;
            text-align: center;
            margin: 15px;
        }

        .btn:hover {
            border-color: #444444;
        }

        .btn:active {
            background-color: #CCCCCC;
        }

        </style>
    </head>
    <body>
        <div id="chatbotTitle"><h3 style="padding-left:10px;">Support Bot</h3><button class="btn" id="transcriptButton">Email Transcript</button></div>
        <div id="webchat" role="main"></div>
        <script>
            let interval;

            var PageTitleNotification = {
                Vars:{
                    OriginalTitle: document.title,
                    Interval: null
                },    
                On: function(notification, intervalSpeed){
                    var _this = this;
                    _this.Vars.Interval = setInterval(function(){
                        document.title = (_this.Vars.OriginalTitle == document.title)
                                 ? notification
                                 : _this.Vars.OriginalTitle;
                    }, (intervalSpeed) ? intervalSpeed : 1000);
                },
                Off: function(){
                    clearInterval(this.Vars.Interval);
                    document.title = this.Vars.OriginalTitle;   
                }
            }

            // We are using a customized store to add hooks to connect event
            const store = window.WebChat.createStore({}, ({ dispatch }) => next => action => {

                if (action.type === 'WEB_CHAT/SEND_MESSAGE') {
                    // Message sent by the user
                    PageTitleNotification.Off();
                    clearTimeout(interval);
                } else if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY' && action.payload.activity.name !== "inactive") {
                    // Message sent by the bot
                    clearInterval(interval);
                    interval = setTimeout(() => {
                        // Change title to flash the page
                        PageTitleNotification.On('Are you still there?');

                        // Notify bot the user has been inactive
                        dispatch({
                            type: 'WEB_CHAT/SEND_EVENT',
                            payload: {
                                name: 'inactive',
                                value: ''
                            }
                        });
                    }, 300000)
                }

                return next(action);
            });

            const adaptiveCardHostConfig = {
                "spacing": {
                    "small": 3,
                    "default": 8,
                    "medium": 20,
                    "large": 30,
                    "extraLarge": 40,
                    "padding": 10
                },
                "separator": {
                    "lineThickness": 1,
                    "lineColor": "#EEEEEE"
                },
                "supportsInteractivity": true,
                "fontTypes": {
                    "default": {
                    "fontFamily": "Calibri, sans-serif",
                    "fontSizes": {
                        "small": 12,
                        "default": 14,
                        "medium": 17,
                        "large": 21,
                        "extraLarge": 26
                    },
                    "fontWeights": {
                        "lighter": 200,
                        "default": 400,
                        "bolder": 600
                    }
                    },
                    "monospace": {
                    "fontFamily": "'Courier New', Courier, monospace",
                    "fontSizes": {
                        "small": 12,
                        "default": 14,
                        "medium": 17,
                        "large": 21,
                        "extraLarge": 26
                    },
                    "fontWeights": {
                        "lighter": 200,
                        "default": 400,
                        "bolder": 600
                    }
                    }
                },
                "containerStyles": {
                    "default": {
                    "backgroundColor": "#FFFFFF",
                    "foregroundColors": {
                        "default": {
                        "default": "#000000",
                        "subtle": "#767676"
                        },
                        "accent": {
                        "default": "#0063B1",
                        "subtle": "#0063B1"
                        },
                        "attention": {
                        "default": "#FF0000",
                        "subtle": "#DDFF0000"
                        },
                        "good": {
                        "default": "#54a254",
                        "subtle": "#DD54a254"
                        },
                        "warning": {
                        "default": "#c3ab23",
                        "subtle": "#DDc3ab23"
                        }
                    }
                    },
                    "emphasis": {
                    "backgroundColor": "#F0F0F0",
                    "foregroundColors": {
                        "default": {
                        "default": "#000000",
                        "subtle": "#767676"
                        },
                        "accent": {
                        "default": "#2E89FC",
                        "subtle": "#882E89FC"
                        },
                        "attention": {
                        "default": "#FF0000",
                        "subtle": "#DDFF0000"
                        },
                        "good": {
                        "default": "#54a254",
                        "subtle": "#DD54a254"
                        },
                        "warning": {
                        "default": "#c3ab23",
                        "subtle": "#DDc3ab23"
                        }
                    }
                    },
                    "accent": {
                    "backgroundColor": "#C7DEF9",
                    "foregroundColors": {
                        "default": {
                        "default": "#333333",
                        "subtle": "#EE333333"
                        },
                        "dark": {
                        "default": "#000000",
                        "subtle": "#66000000"
                        },
                        "light": {
                        "default": "#FFFFFF",
                        "subtle": "#33000000"
                        },
                        "accent": {
                        "default": "#2E89FC",
                        "subtle": "#882E89FC"
                        },
                        "attention": {
                        "default": "#cc3300",
                        "subtle": "#DDcc3300"
                        },
                        "good": {
                        "default": "#54a254",
                        "subtle": "#DD54a254"
                        },
                        "warning": {
                        "default": "#e69500",
                        "subtle": "#DDe69500"
                        }
                    }
                    },
                    "good": {
                    "backgroundColor": "#CCFFCC",
                    "foregroundColors": {
                        "default": {
                        "default": "#333333",
                        "subtle": "#EE333333"
                        },
                        "dark": {
                        "default": "#000000",
                        "subtle": "#66000000"
                        },
                        "light": {
                        "default": "#FFFFFF",
                        "subtle": "#33000000"
                        },
                        "accent": {
                        "default": "#2E89FC",
                        "subtle": "#882E89FC"
                        },
                        "attention": {
                        "default": "#cc3300",
                        "subtle": "#DDcc3300"
                        },
                        "good": {
                        "default": "#54a254",
                        "subtle": "#DD54a254"
                        },
                        "warning": {
                        "default": "#e69500",
                        "subtle": "#DDe69500"
                        }
                    }
                    },
                    "attention": {
                    "backgroundColor": "#FFC5B2",
                    "foregroundColors": {
                        "default": {
                        "default": "#333333",
                        "subtle": "#EE333333"
                        },
                        "dark": {
                        "default": "#000000",
                        "subtle": "#66000000"
                        },
                        "light": {
                        "default": "#FFFFFF",
                        "subtle": "#33000000"
                        },
                        "accent": {
                        "default": "#2E89FC",
                        "subtle": "#882E89FC"
                        },
                        "attention": {
                        "default": "#cc3300",
                        "subtle": "#DDcc3300"
                        },
                        "good": {
                        "default": "#54a254",
                        "subtle": "#DD54a254"
                        },
                        "warning": {
                        "default": "#e69500",
                        "subtle": "#DDe69500"
                        }
                    }
                    },
                    "warning": {
                    "backgroundColor": "#FFE2B2",
                    "foregroundColors": {
                        "default": {
                        "default": "#333333",
                        "subtle": "#EE333333"
                        },
                        "dark": {
                        "default": "#000000",
                        "subtle": "#66000000"
                        },
                        "light": {
                        "default": "#FFFFFF",
                        "subtle": "#33000000"
                        },
                        "accent": {
                        "default": "#2E89FC",
                        "subtle": "#882E89FC"
                        },
                        "attention": {
                        "default": "#cc3300",
                        "subtle": "#DDcc3300"
                        },
                        "good": {
                        "default": "#54a254",
                        "subtle": "#DD54a254"
                        },
                        "warning": {
                        "default": "#e69500",
                        "subtle": "#DDe69500"
                        }
                    }
                    }
                },
                "imageSizes": {
                    "small": 40,
                    "medium": 80,
                    "large": 160
                },
                "actions": {
                    "maxActions": 100,
                    "spacing": "default",
                    "buttonSpacing": 8,
                    "showCard": {
                    "actionMode": "inline",
                    "inlineTopMargin": 8
                    },
                    "actionsOrientation": "vertical",
                    "actionAlignment": "stretch"
                },
                "adaptiveCard": {
                    "allowCustomStyle": false
                },
                "imageSet": {
                    "imageSize": "medium",
                    "maxImageHeight": 100
                },
                "factSet": {
                    "title": {
                    "color": "default",
                    "size": "default",
                    "isSubtle": false,
                    "weight": "bolder",
                    "wrap": true,
                    "maxWidth": 150
                    },
                    "value": {
                    "color": "default",
                    "size": "default",
                    "isSubtle": false,
                    "weight": "default",
                    "wrap": true
                    },
                    "spacing": 8
                }
            };

            window.WebChat.renderWebChat(
                {
                    adaptiveCardHostConfig,
                    directLine: window.WebChat.createDirectLine({
                        token: 'MYTOKENHERE'
                    }),
                    store: store,
                    userID: 'userID',
                    username: 'userName',
                    locale: 'en-US',
                    styleOptions: {
                        botAvatarInitials: 'BOT',
                        userAvatarInitials: 'USR',
                        accent: '#0067CC',
                        backgroundColor: 'White',
                        cardEmphasisBackgroundColor: '#F0F0F0',
                        paddingRegular: 10,
                        paddingWide: 10 * 2,
                        messageActivityWordBreak: 'break-word',
                        fontSizeSmall: '80%',
                        avatarSize: 40,
                        botAvatarBackgroundColor: '#0067CC',
                        botAvatarImage: '',
                        botAvatarInitials: '',
                        userAvatarBackgroundColor: '#ECEFF1',
                        userAvatarImage: '',
                        userAvatarInitials: '',
                        bubbleBackground: '#ECEFF1',
                        bubbleBorderColor: '#E6E6E6',
                        bubbleBorderRadius: 8,
                        bubbleBorderStyle: 'solid',
                        bubbleBorderWidth: 1,
                        bubbleFromUserBackground: '#0067CC',
                        bubbleFromUserBorderColor: '#E6E6E6',
                        bubbleFromUserBorderRadius: 8,
                        bubbleFromUserBorderStyle: 'solid',
                        bubbleFromUserBorderWidth: 1,
                        bubbleFromUserNubOffset: 'bottom',
                        bubbleFromUserNubSize: 10,
                        bubbleFromUserTextColor: 'White',
                        bubbleImageHeight: 240,
                        bubbleMaxWidth: 480,
                        bubbleMinHeight: 30,
                        bubbleMinWidth: 250,
                        bubbleNubOffset: 'bottom',
                        bubbleNubSize: 10,
                        bubbleTextColor: 'Black',
                        markdownRespectCRLF: true,
                        richCardWrapTitle: false,
                        rootHeight: '100%',
                        rootWidth: '100%',
                        hideScrollToEndButton: false,
                        hideSendBox: false,
                        hideUploadButton: true,
                        microphoneButtonColorOnDictate: '#F33',
                        sendBoxBackground: 'White',
                        sendBoxButtonColor: '#767676',
                        sendBoxButtonColorOnDisabled: '#CCC',
                        sendBoxButtonColorOnFocus: '#0067CC',
                        sendBoxButtonColorOnHover: '#0067CC',
                        sendBoxDisabledTextColor: '#767676', // defaults to subtle
                        sendBoxHeight: 40,
                        sendBoxMaxHeight: 200,
                        sendBoxTextColor: 'Black',
                        sendBoxBorderBottom: 'solid 5px #DBDEE1',
                        sendBoxBorderLeft: 'solid 5px #DBDEE1',
                        sendBoxBorderRight: 'solid 5px #DBDEE1',
                        sendBoxBorderTop: 'solid 5px #DBDEE1',
                        sendBoxPlaceholderColor: undefined, // defaults to subtle
                        sendBoxTextWrap: false,
                        showSpokenText: false,
                        suggestedActionBackground: 'White',
                        suggestedActionBorder: undefined,
                        suggestedActionBorderColor: '#CCCCCC',
                        suggestedActionBorderRadius: 0,
                        suggestedActionBorderStyle: 'solid',
                        suggestedActionBorderWidth: 1,
                        suggestedActionDisabledBackground: '#F9F9F9',
                        suggestedActionDisabledBorder: null,
                        suggestedActionDisabledBorderColor: '#E6E6E6',
                        suggestedActionDisabledBorderStyle: 'solid',
                        suggestedActionDisabledBorderWidth: 1,
                        suggestedActionDisabledTextColor: '#767676',
                        suggestedActionHeight: 30,
                        suggestedActionImageHeight: 20,
                        suggestedActionLayout: 'carousel',
                        suggestedActionTextColor: null,
                        groupTimestamp: false,
                        sendTimeout: 20000,
                        sendTimeoutForAttachments: 120000,
                        timestampColor: '#767676',
                        timestampFormat: 'relative',
                        transcriptOverlayButtonBackground: 'rgba(0, 0, 0, .6)',
                        transcriptOverlayButtonBackgroundOnFocus: 'rgba(0, 0, 0, .8)',
                        transcriptOverlayButtonBackgroundOnHover: 'rgba(0, 0, 0, .8)',
                        transcriptOverlayButtonColor: 'White',
                        transcriptOverlayButtonColorOnFocus: 'White',
                        transcriptOverlayButtonColorOnHover: 'White',
                        typingAnimationBackgroundImage: null,
                        typingAnimationDuration: 5000,
                        typingAnimationHeight: 20,
                        typingAnimationWidth: 64,
                        subtle: '#767676'
                    }
                },
                document.getElementById('webchat')
            );

            document.querySelector('#transcriptButton').addEventListener('click', () => {
                store.dispatch({
                    type: 'WEB_CHAT/SEND_MESSAGE',
                    payload: { text: 'Email me a transcript' }
                });
            });

        </script>
    </body>
</html>

1
@tdurnford separate question addedbilloverton
I presume you must have gotten the term "Gemini" from one of TJ's posts because that's not a commonly-understood term. Can you confirm that when you say Gemini you're referring to Web Chat v4 and when you say old you're referring to Web Chat v3 aka Bot Chat? Also, when you talk about making buttons "interactive" are you talking about on-hover effects? (Sorry my team forgot your post)Kyle Delaney
@KyleDelaney Sorry, gemini is in the redirect URL so I was using that to differentiate. I'm not exactly sure on the version, but it is quite possible that it is v3 vs. v4. And yes, referring to on-hover effects. I've tried using a custom adaptiveCardHostConfig object (which can effect some changes), but I cannot replicate the look or function of the old cards. I would be quite happy if I could just get the cards to render exactly like they did in the old version.billoverton
Do you mean the embed URL? It looks like you're using the CDN in your HTML and not using embedded Web Chat so there's no reference to the term Gemini there. Is that not the case?Kyle Delaney
@KyleDelaney You are correct. The screenshots on the left are via the CDN/Directline. But without my formatting tweaks in styleOptions and adaptiveCardHost it is identical to the embed URL (which I have been calling OOTB webchat). On the right is the old version of the embed URL.billoverton

1 Answers

2
votes

Web Chat and Adaptive Cards are both open source, so it's a good idea to download their source code if you want to figure out how they work. In the Web Chat repo you can switch to the v3 branch to see how v3 works. Web Chat uses the Adaptive Cards JavaScript SDK, and the code that handles parsing and rendering is in card-elements.ts.

In botchat.css, you can see the styles that create the background you want here:

.wc-message-content {
  border-radius: 2px;
  box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.2);
  padding: 8px;
  word-break: break-word; }

.wc-message-from-bot .wc-message-content {
  background-color: #eceff1;
  color: #000000; }

Those classes aren't used in Web Chat v4, but you can apply it to your attachments and carousels like this:

div.attachment.bubble,
div.content > ul.webchat__carousel__item_indented {
    background-color: #eceff1;
    color: #000000;
    border-radius: 2px;
    box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.2);
    padding: 8px;
}

I'm being pretty specific with the selector because there's another style that will try to set the padding to 0. You can just use the !important keyword if you want.

You've already seen that Web Chat doesn't allow bubble nubs on attachments in v4. The line responsible for this is here:

<Bubble className="attachment bubble" fromUser={fromUser} key={index} nub={false}>

You can modify the way activities are rendered using activity middleware according to this sample. In your case you'll want to render an SVG element alongside the activity.

To add hover styles to your buttons, you can again have a look at botchat.css:

.wc-card button:hover {
  background-color: transparent;
  border-color: #0078d7;
  color: #0078d7; }

You can use all three of those declarations or just border-color:

.ac-adaptiveCard button:hover {
    border-color: #0078d7;
}