[SalesForce] Locker Service for Communities blocks any attempts to include Salesforce Live Agent. Is this a bug

I am leaning on my friends at Salesforce Stack for a very important
question that I have spent a great deal of time on over the past few
weeks. Warning: This is a long one, please grab yourself a glass of insert drinkOfChoice and help us help every future Salesforce customer by identifying and resolving this issue.

What issue? I believe that Lightning Locker Service makes it
impossible
to implement Salesforce Live Agent into a Lightning Community
Component
.

I do not have a premiere account with Salesforce support so I have no avenue to contact the correct people at Salesforce for a true resolution to this issue, so I am reaching out to you all to see if we can collaborate together to determine:

  1. If Salesforce Live Agent (in its current state) can be implemented into a Lightning Community with Locker Service enabled?
  2. Who to contact at Salesforce to get this addressed prior to the forceful release of the Lightning Locker Service critical update in early 2017.

I should mention that prior to Lightning Locker Service being enabled,
I had an implementation of Salesforce Live Agent running without any
major issues since March of 2016. In fact, since this update hasn't
reached production yet, I still have a working implementation on our
live site right now. Details below…

Pre-Locker Service Implementation (Works W/O Locker Service):

1. I placed the hosted deployment.js file (copied straight from Setup > Live Chat Deployment) in the Header Markup in the Advanced Settings of Community Builder:

Advanced Head Markup

enter image description here


2. I created a very basic Lightning Component with 2 different anchor tags, one for if the chat is offline and the other for when it is online:

<aura:component implements="forceCommunity:availableForAllPageTypes">

<!--Initialize the Live Agent-->
<aura:handler name="init" value="{!this}" action="{!c.init}" />

<div class="container-fluid">
    <div class="row">
        <div class="col-sm-4 col-md-4 msiBoxCol">
            <a href="" id="liveagent_button_online" class="thumbnail msiBox1" style=" text-align:center;padding-bottom: 2em;display: none;" onclick="{!c.startChat}">
                <div class="msi-img1" style="padding-top:20px;"></div>
                <h3 class="msiSmall">Live Chat Online</h3>
            </a>

            <a href="" id="liveagent_button_offline" class="thumbnail msiBox1" style=" text-align:center;padding-bottom: 2em;">
                <div class="msi-img1" style="padding-top:20px;"></div>
                <h3 class="msiSmall">Live Chat Offline</h3>
            </a>
        </div>
    </div>
</div>

</aura:component>
(I had to do the <aura:component> tags weird because they don't render inside of a code block)


3. I created a Client Side Controller method to handle displaying the correct anchor tag based on online/offline and initializing the live agent (init method), and starting the chat when clicked (startChat method):

({
init : function(component, event, helper) {
    if (!window._laq) { 
        window._laq = []; 
        console.log('MM-LC++++ - !window._laq');
    }
    window._laq.push(function(){
        liveagent.showWhenOnline('CHAT ID 123', document.getElementById('liveagent_button_online'));
        liveagent.showWhenOffline('CHAT ID 123', document.getElementById('liveagent_button_offline'));
        console.log('MM-LC++++ - window._laq.push');
    });
    liveagent.init('https://d.la1w1.salesforceliveagent.com/chat', 'CHAT BUTTON ID', 'ORG ID');
},


    startChat : function(component, event, helper) {
        liveagent.startChat('CHAT ID 123');
    },
})  

The above implementation works without Locker Service, and uses a
slightly modified version of the exact implementation instructions for Salesforce Live Agent buttons, It operates the same way you would
set it up for any website embed, with the exception of using the
Lightning Component Controller for the init actions… The hosted
deployment.js is provided by and hosted by Salesforce and provides us
with the liveagent. methods, and all of the references to those
methods (liveagent.init, liveagent.start, etc) are used in the
same way as instructed for a traditional website embed.



Then we turned on Locker Service in our Dev environment…

Immediately following that, this same component which once worked flawlessly now causes the entire page to bomb, returning an "Invalid Page" message.

By commenting out each line in the Lightning Components Controller one by one, I was able to find that the liveagent.init line was the one causing the entire page to not display and throw the "Invalid Page" error:

liveagent.init('https://d.la1w1.salesforceliveagent.com/chat', 'CHAT BUTTON ID', 'ORG ID');

With that line commented out, the page loads, but the page is displaying the offline anchor tag when it should be online (agents are online and available).

Further troubleshooting on my part shows that window._laq = [] is not working the same way after enabling locker service. This results in an undefined response when typing window._laq into the console after page load.

Here are screenshots of me typing window._laq into my console window immediately upon fresh load of the page:

Production – Get a more expected return:

Expected Return

Dev with Locker Service – Get undefined:

Undefined

If I manually type window._laq = []; into the browser console, it is successfully created, and then I can manually run the window._laq.push portion of the code in the console, and then manually run liveagent.init to init the Live Agent, which results in my Online button being displayed and the liveagent.startChat working as expected… **but I can't figure out how to get this to run automatically on / after page render because all of my attempts result in window._laq still being undefined. And if window._laq is undefined, then we can't push to it, and if we can't push to it, we can't init… and so on, and so on.

I also tried using a static resource version of deployment.js via <ltng:require scripts=""> instead of referencing Salesforce's external one in my Head Markup to see if it made a difference – this resulted in even less desirable results, with the console telling me that liveagent wasn't even defined.**

SO, the ultimate questions are:

  1. Is there a way to fix this within the current design of Salesforce Live Agent and its associated methods?
  2. After enabling Locker Service, why is window._laq not being defined even though the code block is being run?
  3. If there is no way around this problem and it is indeed a more advanced problem that needs to be addressed by Salesforce, what do we
    do about it to get it fixed before Locker Service releases?

If you've made it this far, thank you, I am happy to provide as much more detail as is necessary so please make comments as needed.

Best Answer

excellent post and I am sorry to see that you had to spend so much time on this.

  1. Known issue and already tracked with bug W-3214759 Live Agent Chat is blocked in Community Templates with Locker Service. The programming mode of including a global scoped library such as deployment.js - not into the component using ltng:require - is not going to work. Actually a good thing because a component is required to be a self contained entity that declares its dependencies - all of its dependencies. The library is being included and bound to global scope not the scope of the component and its effectively invisible to the component. In other words this approach was never one that should have been used but before Locker nothing was stopping it.

  2. That looks like the difference of scope between the code that is running in the console versus the actual code you've stepped through. If you set a breakpoint inside the code (or add a debugger statement if you can alter the code) then window._laq should be defined. LS virtualizes global scope (window) along with the rest of the DOM/BOM and I suspect in one case you are working with the actual global window and in the other the virtual one in the locker context.

  3. Getting this fixed is on Salesforce and if we can't get it fixed (along with the long list of other issues in LS we're working hard to address) then the activation date will be adjusted accordingly. We're not going to activate locker if its still blocking code that is supposed to work with it enabled.

Related Topic