How to open an External Page from a Syndicated Conditional Chat Link

I'm writing a quick article in response to a question I received on another post inquiring if it was possible to open an external webpage instead of a Customer Portal page when the "Chat Now" link is clicked. Using standard functionality, this isn't possible, but using the techniques I've described in my other Syndicated Widget articles we can modify the core behavior to match our requirements.

The other articles I've written around Syndicated Widgets can be found here. It might be worth reviewing them to learn some of the background and techniques on modifying these syndicated widget's behavior.

Explanation of the Internals

When setting up a Syndicated Conditional Chat Link (SCCL), one of the attributes you define is the "chat_login_page" attribute. This attribute is the page that the user is directed to when they click on the chat link. For most implementations, this is set to /app/chat/chat_launch, or /app/chat/chat_landing. In all cases, this URL is relative to the root URL of the OSC site. The standard code takes the "chat_login_page" attribute value and appends it to the site root and performs a window.open call. The "base url" is set by the chat server when the widget definition is created and set as a property named "base_url" under the data object.

The internal logic is as follows (snippet of the chatLinkClicked method):


this.chatLinkClicked = function(context) {
    var path = this.attrs.chat_login_page + '/request_source/' + this.data.request_source;
    //...
    if (this.eo.pta) {
        if (path.match('/app/'))
            path = path.substr(4);
        path = this.data.base_url + '/ci/pta/login/redirect' + path + '/p_li/' + this.eo.pta;
    } else {
        path = this.data.base_url + path;
    }
    var callback = null ;
    if (this.attrs.open_in_new_window) {
        window.open(path, 'chatLauncher', 'width=' + this.attrs.chat_login_page_width + ',height=' + this.attrs.chat_login_page_height + ',scrollbars=1,resizable=1');
    } else {
        //...
    }
    //...
}

Redefining the Base URL

We can trick the system into allowing any absolute URL we want by redefining the value of this.data.base_url to an empty string (""). This is a property on the widget instance and is accessible inside of most of the events callbacks. I'll show how we can set the value of ths property using one of these events (we only need to do it once). Once the base_url is effectively empty, you can set any URL you wish in the "chat_login_page" attribute.

The following code registers a custom handler to the evt_conditionalChatLinkAvailabilityResponse event. The handler accesses the data.base_url property and modifies if if needed. For this demonstration, I set my "chat_login_page" attribute to an external LMGTFY page.


RightNow.Client.Controller.addComponent(
{
    chat_login_page_height: 610,
    chat_login_page_width: 460,
    chat_login_page: "https://lmgtfy.com/?q=CXDeveloper.com",
    container_element_id: "myChatLinkContainer",
    label_available_immediately_template: "Agents are available with no wait time.",
    label_unavailable_busy_template: "All agents are busy.",
    label_unavailable_hours: "We're sorry, chat is currently unavailable.",
    ignore_preroute: true,
    min_sessions_avail: 0,
    wait_threshold: 86400,
    info_element_id: "myChatLinkInfo",
    link_element_id: "myChatLink",
    instance_id: "sccl_0",
    module: "ConditionalChatLink",
    type: 7
    },
    "//cx.rightnow.com/ci/ws/get" //<-- Change to your own server
);

//Widget loaded callback
RightNow.Client.Event.evt_widgetLoaded.subscribe(function (type, args) {
        //Register event to watch for when avail is checked
        RightNow.Client.Event.evt_conditionalChatLinkAvailabilityResponse.subscribe(function(type, args, instance)
        {      
            var result = args[0].data;
            var scope = args[1].scope;
            var eventScope = args[1];
            
            //Overwrite the base_url to be blank so that we can open absolute URLs from the chat_login_page attribute
            if(scope && scope.data && scope.data.base_url)
            {
            	scope.data.base_url = "";
            }
       });   
				
});

Working Demonstration

A full working demo of this code can be found on my JSFiddle Account: https://jsfiddle.net/fishnugget77/f3pozg59/

Additional Thoughts

If you have more extreme requirements that dictate a completely custom on-click behavior, it is also possible to rewrite the entire, chatLinkClicked method. I would be very careful when doing this as there are other metric-based aspects of the OOTB method that you'd want to duplicate.

To rewrite the chatLinkClicked method on the widget instance, you'd do something like this:


//Widget loaded callback
RightNow.Client.Event.evt_widgetLoaded.subscribe(function (type, args) {
        //Register event to watch for when avail is checked
        RightNow.Client.Event.evt_conditionalChatLinkAvailabilityResponse.subscribe(function(type, args, instance)
        {      
            var result = args[0].data;
            var scope = args[1].scope;
            var eventScope = args[1];
            
            //Rewrite method
            scope.chatLinkClicked = function()
            {
            	alert('By the power of Greyskull!!');
            }
            
       });   
				
});  

Zircon - This is a contributing Drupal Theme
Design by WeebPal.