简体   繁体   中英

Lazy-loading facebook customer chat plugin - can I force the chat dialogue to open?

I'm trying to lazy-load the facebook customer chat plugin, to avoid the performance hit on every pageload.

My idea is that instead of including the FB sdk on every page on the offchance that a customer might want to interact with the chat, I can just have a chat icon that the user clicks, and THEN load the sdk.

Seems to make perfect sense to me.

There's a slight delay when loading the javascript, but that's ok, I've put a little pulsing animation on the chat icon to give the user the idea that something's happening.

The catch is if they've already closed a chat dialogue at some point, it won't reopen:

From https://developers.facebook.com/docs/messenger-platform/discovery/customer-chat-plugin :

By default, the greeting dialog will be shown on desktop and minimized on mobile. Users can also click to show or minimize the dialog. This state is cached on the browser for the duration of the page session (including page reloads).

The first part of that is fine - I can set greeting_dialog_display to 'show' very easily. But if they've already closed a chat window on a previous page, then the caching of that state becomes a problem; they click my fake-chat icon, the SDK loads... and nothing happens - they have to click the icon a second time to open the chat window. Not good UX at all.

Is there something I can do to get around this? I've had a look with devtools at the code behind the scenes, but frankly couldn't make head nor tail of it, and I'm not sure I could interact with it even if I could, since the main body of the chat widget seems to be in an iframe?

Here's my code, not that most of it is very relevant to the question:

HTML/JS:

<img id="fake-chat" onclick="loadRealChat();" src="/img/facebook-chat.svg">

<div class="fb-customerchat" page_id="293008574697" greeting_dialog_display="show"></div>

<script>
    function loadRealChat() {
    _('fake-chat').style.animation='pulse 0.5s linear 6';

    _('fake-chat').insertAdjacentHTML('afterend', '<div class="fb-customerchat" page_id="PAGE_ID" greeting_dialog_display="hide"></div>');

    window.fbAsyncInit = function() {
        FB.init({
            appId            : 'APP_ID',
            autoLogAppEvents : true,
            xfbml            : true,
            version          : 'v3.0'
        });
    };

    (function(d, s, id){
        var js, fjs = d.getElementsByTagName(s)[0];
        if (d.getElementById(id)) {return;}
        js = d.createElement(s); js.id = id;
        js.src = "https://connect.facebook.net/en_US/sdk.js";
        fjs.parentNode.insertBefore(js, fjs);
        }(document, 'script', 'facebook-jssdk'));
}
</script>

CSS:

#fake-chat{cursor:        pointer;
           box-shadow:    rgba(0, 0, 0, 0.15) 0px 3px 12px;
           border-radius: 50%;
           position:      fixed;
           bottom:        24px;
           right:         24px}

@keyframes pulse {
      0% { transform: scale(1); }
     25% { transform: scale(1.1); }
     50% { transform: scale(1); }
     75% { transform: scale(0.9); }
    100% { transform: scale(1); }
}

As a bonus it'd be nice if I could accurately stop the animation at the moment that the facebook chat finishes loading and appears - any ideas?

Thank you!

You can disable xfbml (set xfbml: false) at the beginning. Then you can trigger messenger chat to load using:

FB.CustomerChat.show(shouldShowDialog: boolean);

My solution was like this I set a cookie for 30 min and if cookie is active chat is loaded for every page after first button click here is the code.

HTML/CSS

      <div class="fake-button"><img src="messenger-icon.svg"></div>
      .animate > img {
       animation: pulse 1s linear 4;
      }
      @keyframes pulse {
      0% { transform: scale(1); }
      25% { transform: scale(1.1); }
      50% { transform: scale(1); }
      75% { transform: scale(0.9); }
      100% { transform: scale(1); }
      }

And JS code

 $(window).load(function () {
            if (getCookie('fb-chat')) {
                FB.XFBML.parse();
            }
        });
$('.fake-button').on('click', function () {
            $(this).addClass('animate');
            FB.XFBML.parse();
            setCookie('fb-chat', true, 0.0216);
        }) .on("animationend", function(){
            FB.CustomerChat.showDialog();
            $(this).removeClass('animate');
        });
        window.fbAsyncInit = function() {
            FB.init({
                xfbml            : false,
                version          : 'v3.2'
            });
        };
        (function(d, s, id) {
            var js, fjs = d.getElementsByTagName(s)[0];
            if (d.getElementById(id)) return;
            js = d.createElement(s); js.id = id;
            js.src = 'https://connect.facebook.net/en_US/sdk/xfbml.customerchat.js';
            fjs.parentNode.insertBefore(js, fjs);
        }(document, 'script', 'facebook-jssdk'));

        function getCookie(name) {
            var v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
            return v ? v[2] : null;
        }

        function setCookie(name, value, days) {
            var d = new Date;
            d.setTime(d.getTime() + 24*60*60*1000*days);
            document.cookie = name + "=" + value + ";path=/;expires=" + 
        d.toGMTString();
        }
        function deleteCookie(name) {
            setCookie(name, '', -1);
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM