Tuesday, June 17, 2014

Get your application integrated within IBM Connections

Since I moved to TrilogGroup, I got several requests on how we achieved the ProjExec integration with the IBM collaboration platforms, as it just looks part of it. In particular, the IBM Connections one, where the users feel like they never left Connections. We keep the same user experience than any other Connections application. This includes the same navigation bar, the same look and feel (a.k.a. OneUI), the same authentication mechanism... Some of the techniques being used are documented and supported by IBM, but others are just the result of our engineer’s inventiveness.

Let me talk today how the navigation bar can be integrated into a third party application. IBM SmartCloud for Social Business provides an easy developer experience with a well document reusable component. There are multiple articles on the subject, so I won't expand on this.  But what about IBM Connections on-premises? IBM does not provide a similar, reusable component.  Nevertheless, ProjExec does this integration, as shown below. What is the magic behind it?


Let's talk about some solutions for your own applications.

Disclaimer: This is not documented by IBM, nor it had been communicated to me by IBM. Use the technique exposed bellow as your own risk!

One solution is to load in the main application page the same files and <script> tags than Connections, in the same order.  But this strategy has some issues:
  • It is fragile. What if the next version of Connections adds/renames/removes tags or files? Your application has to be modified accordingly. And it also has to adapt to the different versions of Connections. This can quickly become a maintenance nightmare.
  • What about commons files like Dojo? Should they come from your own application or from the Connections server? You can face some weird issues if you use the former.
  • The JavaScript files and the HTML+ JS tags must be loaded and executed in the right order within the page. It is very important, else the page will just break.  Moreover, the use of third party additions to Connections makes it even trickier. How can we guarantee that the right execution order is enforced?
But wait, there is an even smarter solution. The thinking is: what displays IBM Connections pages the best? Obviously, it is IBM Connections itself :-). So instead of loading Connections pieces within your application, just load your application within Connections. In short, get an existing Connections page and inject your own content in its body, replacing the existing one. That way the common page components, including the navigation bar, are properly loaded and executed.

To make it real, the first thing you have to do was to identify the simplest possible Connections page. A page that has a simple static body you can easily replace with our own content.  After browsing the different pages, it looks like the search page /search/web/jsp/toolsHomepage.jsp is a pretty good candidate. Note that this can be simplified if you deploy a specific empty page, with the headers, within the Connections WAR files. But that requires some Connections customization. If you want to use what already exists, then the search page is good enough.

Then you have the choice of doing the work on the server or the client side:

  • On the server side, a piece of code would call the Connections page, grab the HTML markup, remove the undesired pieces and inject its new content in the body. Once done, the ready-to-go page can be sent as a whole to the browser. I can truly imagine an XPages custom JSF ViewRoot renderer doing the job :-)
  • On the client side, it is a bit more complex, because you need to mash-up the Connections page within your browser, then inject the different fragment at the right place, in the right order. But, on the other hand, it does not depend on any server side technology.

Here is a pseudo implementation of the client side solution. First, you need to start with basic html page similar to this:
<html>
<head>
  <script src=’connections-integration.js’>
  <script src=’<path to jquery>/jquery.js’>
  <script>/* inline JS #1 that grabs the Connections page*/</script>
  <script>/* inline JS #2 that inserts the Connections header*/</script>
   … <!—Your own header tags -->
</head>
<body>
  <script>/* inline JS #3 that inserts the Connections body*/</script>
   … <!—Your own page body and footer -->
  <script>/* inline JS #4 that inserts the Connections footer*/</script>
</body>

1- The first statement in the <head> tag is a reference to your custom JavaScript file (connections-integration.js), containing all the necessary code. It should be included first in the page, right after the <head> tag. Optionally, you can also include JQuery as it makes easier all the DOM operations. The JavaScript inline tags (JS #1,2,3,4) will simply call functions defined in your custom JavaScript file.

2- The JS #1 code emits a request to the Connections server, grabs the page, parses the markup, splits it into 3 parts and saves the result into a global variable. The 3 parts are:
    • Head.
      It is a copy of the <head> tag from Connections, with some content removed. For example, the <title> is removed as your app will obviously come with its own title. This is also true for all the unnecessary <meta> tags. A quick JQuery request does the trick.
    • Body.
      It contains of the <body> tag coming from Connections,  with the main content (#lotusmain) and the search bar (.lotustitle2) removed.
    • Footer.
      This is a specific part of the <body> tag. But it is an important one as some components, like Connections Mail, are injecting their code at the bottom of the page, for performance reasons. So this footer should be inserted as the bottom of your the page. You can simply remove the <ul> tags if you don’t want any Connections footer content to be displayed.
3- The other inline <script> tags (#2, #3, #4) insert the different parts at the right places in the page. To respect the execution order of Connections, these parts must be inserted and executed synchronously. This cannot be achieved with DOM insertion as the script tags won't be loaded and executed synchronously. But, fortunately, the old decried document.write() capability does the trick. The markup is converted into a string and then written on the fly to the document using this function.

There are other subtleties to make it work properly. For example, the ‘login’ button in the toolbar redirects to the last page loaded by Connections. But a quick inspection of the URL shows that there is a logoutExitPage parameter pointing to the page to redirect to. This can be set by overriding the lconn.core.auth.getLogoutUrl function.

Although this technique allows a great integration of a third party application with Connections, we would all prefer IBM to come with a supported solution, as it provides for SmartCloud. Well, with some enhancements :-) I'll be happy to share my ideas with IBM. I'm sure you too, so please join your voice to mine. By the meantime, I hope this solution will help you.

25 comments:

  1. Welcome back!

    Great technique. This is very much needed. There are many missing parts in Connections that allows extensions within Connections.

    I am also looking into search integration for a while. Current search integration is just passing a search string to an external URL and launch that. We can't contribute into search in terms of content. For instance what if a Connections user uses the Connections search to find Projexec content, say a specific project? If you don't generate Connections-specific content within your application (which will be user-dependent and will be lost if user left) there seem to be no way right now.

    Take care!

    ReplyDelete
  2. Thanks Phil, great writeup!

    Actually, I have been working on a very similar integration lately, where we decided to go the server-way and indeed integrated calls to our backend-tool from within Connections-JSPs which then modified the resulting html page to include our content. We faced really all the obstacles you stated and then some, especially when it came to dynamically loading follow-up content and facing same-origin issues (solved that by using a proxy server) or authenticating the calls from within Connections against our tool.

    If you like, I'd be glad to exchange experiences with you guys on those matters - even better involving someone from IBM who could eventually help making app-like integration into on-prem Connections a little less painful.

    @Serdar: Regarding the search we faced exactly the same issues that you mention. There doesn't currently seem to be a way to inject your own seedlist to the Connections search engine. In the end we customized the search.jsp to include javascript-issued calls to our own OpenSearch-based search engine and rendered the results similar to the native Connections results. Not a perfect solution but still...

    Cheers!

    ReplyDelete
  3. Thanks for the offering Benny. Please, feel free to share your experience. I agree that we should bubble this up to IBM, and help them build a nice integration story. Go ahead!
    I would like to come with a series of articles explaining how to achieve a great application integration within the IBM social platform. Whatever we can share, let's do it.

    ReplyDelete
  4. Very interesting article. My boss sent me the link, now I have to do the same task. But my client-side attempt fails because of CORS. My application is on notes.MyCompany.de and Connections runs on connect.MyCompany.de.
    How did you solved the problem?
    Thanks in advance.

    ReplyDelete
  5. I did the integration using a servlet on the WAS server to work around the issue that Reiner states as the content we need to integrate will almost always be on separate domains and hence CORS would be an issue. The solution I did is current "just" a servlet that does all the heavy lifting to do the extraction of the "template", replaces title, handles language based on request arguments and then inserts an iframe into the generated page with a url from configuration. That's what we needed for the first solution. Subsequently I would like to extend it to load JavaScript libraries on the resulting page to have the page load in JavaScript based UI as we also need that for other applications.

    The servlet was built using the approach that Philippe outlines above.

    The code was developed together with OpusNeo (we share offices) and the code is actully on GitHubso I would love to start a collaboration around this kind of functionality so if anyone is interested I would love to hear from you or any others that are interested.

    ReplyDelete
    Replies
    1. Mikkel could you please share the github link, i am not able to find it by myself!

      Delete
  6. Mikkel thank you for publishing this: https://github.com/lekkimworld/ic-wrapper

    ReplyDelete
  7. There is another smart approach - currently in use on IBM Smartcloud, only: http://www-10.lotus.com/ldd/appdevwiki.nsf/xpDocViewer.xsp?lookupName=IBM+Social+Business+Toolkit+documentation#action=openDocument&res_title=Adding_the_IBM_SmartCloud_for_Social_Business_banner_to_partner_applications_sbt&content=pdcontent
    I ask myself why this is not available on premise? Do we have to reengineer that one?

    ReplyDelete
  8. twilio woocommerce sms plugin for your Online shopping store or SMS marketing..........

    ReplyDelete
  9. Gracious to view your site, My spouse and i seem to be ahead to be able to additional fantastic written content along with I believe most of us really like to be able to give thanks to for a lot of fantastic written content, webpage to debate with us.local marketing

    ReplyDelete
  10. The war between humans, orcs and elves continues earn to die . Lead your race through a series of epic battles, using your crossbow to fend off foes and sending out units to destroy castleshappy wheels . Researching and upgrading wisely will be crucial to your success! There are 5 ages total and each one will bring you new units to train to fight in the war for you cause.
    earn to die 2
    Whatever you do, don’t neglect your home base because you cannot repair it and once it is destroyed, you lose! Age of War is the first game of the series and really sets the tone for the Age of War games . Also try out the Age of Defense series as it is pretty similar.
    In this game, you start at the cavern men’s age, then evolvetank trouble ! There is a total of 5 ages, each with its units and turrets. Take control of 16 different units and 15 different turrets to defend your base and destroy your enemy.
    The goal of the game also differs depending on the level. In most levels the goal is to reach a finish line or to collect tokens. Many levels feature alternate or nonexistent goals for the player.

    ReplyDelete
  11. This comment has been removed by the author.

    ReplyDelete
  12. This comment has been removed by the author.

    ReplyDelete
  13. Informative post. Glad to find your blog. Thanks for sharing.

    digital marketing training in chennai

    ReplyDelete
  14. This comment has been removed by the author.

    ReplyDelete
  15. This comment has been removed by the author.

    ReplyDelete
  16. Such a great info about integrated within IBM Connections..
    Where i found best woocommerce SMS integration ? Because We have development many websites with SMS API integration notification for our Clients.

    ReplyDelete
  17. Great post. I learned lot of things. Thanks for sharing such a useful post.

    wordpress Training in Chennai

    ReplyDelete
  18. Nowadays, this kind of advertising becomes very popular. I decided to use it too.I made a choise at this https://www.intistele.com/blog/recruitment-sms/ company cuz the quality of their work is great and the prices are low.

    ReplyDelete
  19. SMS services like bulk sms, transaction sms, promotional sms, SMS API, OTP, QTP, are great strategy to work with huge number of clients. It helps in maintain a good relation with clients. you can select Top 5 Bulk SMS Service Provider in India with SMS API for your business.

    ReplyDelete