Skip navigation

Developer

5 Posts authored by: nilsheuer

As you are hopefully aware of, we’re big fans of the Jive Add-on framework. We use it for a number of projects and products on a continuous basis.

However, it is always a good idea to spend time with other development frameworks to hone your skills and find new approaches to problems.

One, somewhat unexpected, source of inspiration for a suggested improvement to the Jive Add-on framework came during a development project for … SharePoint Online (aka. Office365, though this also applies to SharePoint 2013).

 

Apps for SharePoint allow you to build applications that behave very similar to apps in Jive:

  • They have full access to the SharePoint object model, similar to the v3 JS API
  • They offer transparent single-sign on without the need to re-authenticate
  • They can be built using any development environment that supports HTML/JS
  • They offer various integration points throughout the UI
  • They run out of context of the server itself

 

One of the differences is that SharePoint offers a concept called an immersive app. An immersive app offer all of the features mentioned above, but it runs in a separate window after being launched from the Office365/SharePoint UI.

Here is an example of an immersive app

2015-03-11_2230.png

The app runs on a separate server from the SharePoint site (even the URL is different), but is passed the security context of the user launching it, giving it full access to the SharePoint API.

A minimalistic context of the SharePoint site is retained by the available chrome control at the top. It automatically makes a themed navigation bar (that mimics your site’s theme) available, and also injects a number of CSS classes so that you can brand your app similar to the customer’s site. (Something I wish we had in Jive apps).

 

Now why is this a good idea? The main benefit from a user’s perspective is performance. Despite all its power and the elegance of embedding functionality directly into Jive, the most common criticism we hear from customers is the sometimes slow response times, as a lot of html and all webservice requests are proxied through the Jive server.

From a developer perspective the main benefit for me personally is the lack of restrictions, which are imposed by the Jive apps framework. I would love to use modern technologies like AngularJS (not really, not a big fan of v1 ;-) ), Durandal or even BreezeJS in our Jive apps, but the amount of effort of rewriting these to play nice with the restrictions of the Jive framework is cost prohibitive in most cases.

 

The pros:

  • Better performance, as this is a “regular” web application, instead of running in a proxied iFrame
  • All modern web application frameworks and technologies are available without customization
  • A lot more screen real estate, as the Jive navigation and headers can take up as much as a third of the available screen, depending on the theme
  • Still able to create integrated apps that make use of the social graph and collaborative capabilities of Jive in a relevant way. (Don’t fall into the traps of the portal world! Watch my talk from JiveWorld13 here: JIVETalks: Developer - Video

 

The cons:

  • The user is taken out of context of the Jive environment. However, the same applies for a canvas based Jive apps. A chrome control can remedy some of that.
  • Not suitable for scenarios where the launch context (a place in Jive, a profile or content) is relevant.

 

Conclusion

Jive is actually very close to achieving a first version of this capability. All is needed is a “login via Jive” capability. One could build an immersive Jive app even now, but the lack of login by Jive means, that I would need to create a separate login and user management to do so. Take a look at this discussion for for an example of someone trying to achieve this (and failing): OAuth2 authorization process always ask for grant permissions

A next step would be an option to launch an app from the apps menu and have it launch in a separate window, without the need for an iFrame, and with the security context passed. This would allow us to use the v3 REST API.

A stretch goal would be to have the v3 JS API available in the app.

 

Question to Jive: When can we have this?

 

Ryan Rutan Yoav Derazon Aron Racho clara.liang Matt Tucker

Based on a lot of demand and requests for training and education around Jive's Add-On framework, we are planning a series of 2 day developer training sessions around the world.

 

(sorry had posted this as a question initially. Apologies for double posting)

 

If you are interested in attending one of these please help us in planning by filling out our survey here: Jive Add-On Developer Training Survey

 

Preliminary Agenda:

Day 1

  • Introduction to the Jive Add-On Framework and common use cases
  • Overview of available development environments (node.js, Java, .Net)
  • Add-On development best practices
  • Building your first Add-on
  • Integration points for Jive Apps

Day 2

  • Deploying your Jive Add-on for production
  • Using the Jive REST API from client applications and Jive Apps
  • Building and updating tiles
  • Using WebHooks
  • Using the Data Export API
  • Discussion, Q&A and wrap up

 

About us:

Pokeshot/SMZ is a global Jive Technology, Consulting and Professional Services Partner. We have 10 years of experience working with Jive, and have been actively involved in using and enhancing the Jive Apps and Add-On frameworks since 2011.

 

We are looking forward to your feedback.

So I've started to combine some of my code snippets into a project, and have published it on github here: pokeshot/JiveDotNetSDK · GitHub

 

This is most certainly work in progress. Currently it consists of the (partial) object model and the code for request validation for signed requests coming from Jive going to a WebAPI endpoint.

 

I would like to get some feedback from the developer community on the format of the project going forward

 

  • keep as is, as a collection of individual code pieces, with eventually better documentation
  • convert it into a regular ASP.Net web application (likely MVC and WebAPI) and implement a full sample app

 

I'd really like to get your feedback on this.

 

Upcoming things that I will add, once I clean things up:

  • OAuth dance for getting client credentials for using the REST Api
  • Webhook support
  • Add-on registration WebAPI controller (this depends on the feedback to my question above)
  • Request validation for MVC Views
  • Language/i18n support (Jive apps do not use the standard language headers)
  • Code for registering tiles and pushing data to them
  • Code for consuming data from the data export API

 

Let me know if I am missing anything.

So I recently stumbled across this video I had uploaded to Youtube a few years back. I had completely forgotten about it.

This was in the Jive 3.0 or 4.0 days, I believe.

 

So this was a document browser for Jive, I wrote using an awesome, but sadly mostly forgotten technology from Microsoft, called Pivot (Microsoft Live Labs Pivot - Wikipedia, the free encyclopedia). Pivot was based on the same technology as Photosynth, and allowed you to do some amazing things with large datasets. It allowed you to start with datasets of thousands or even ten thousands of elements and drill down into or filter them on the fly, using a positively Minority Reportesque UI.

 

While this is not really that relevant from todays point of view, I still think that maybe, just maybe, this little project of mine influenced the cards-tiles interface for browsing people, places and content in Jive 5 and beyond a tiny bit.

 

Watch the video below. It starts a little slow, but gets a lot shinier around the 3 minute mark. I've provided some technical details below.

 

 

From a technology point of view this was pretty involved, due to the lack of decent APIs on the Jive side at that point. It shows how far Jive has come when it comes to APIs.

 

The process went as follows:

  • Information about content was retrieved directly from the Jive database. This included titles, content, authors, tags, ratings and the place a content was stored in. This was pretty easy and fast. The largest dataset I've tried this with was around 3000 documents.
  • Any binary content was downloaded using the legacy XML based REST API that was available in Jive 3.0 and 4.0. Openclient, the first version of the current API came in 4.5. The reason for this was that the binary content is encoded in some weird undocumented way in the database.
  • Jive native content was converted to images using a tool that came with the Pivot SDK. Basically you defined an HTML template, pumped your Jive HTML content into it, and it would render it out as an image file that Pivot could use.
  • Binary content was converted into images using the incredibly awesome Apose libraries. They allow you to take any office format and convert it into a pixel perfect image or PDF. I wish Jive would use them instead of their OpenOffice solution. Sometimes when Jive has butchered another one of my Powerpoints, I dream of writing a replacement document rendering service using Aspose ;-) We are using their technology in our SmarterPath LMS for Jive and are very, very happy with it.
  • All of the data was mangled into a Pivot collection.

This was certainly done in a batch way. Processing a 1000 document dataset took 5 to 10 minutes on a laptop. The majority of the time converting HTML and Binaries to images.

 

Being a Silverlight based technology, Pivot isn't going anywhere. Pretty sad, in my opinion. Imaging the Jive people browser allowing you to drill down from 10.000 colleagues using faceted search in real time, without any browsing or paging. *Sigh*

 

I hope you liked this little trip down nostalgia lane. I have a few more silly examples like this, that I might post. If you don't see any value in this, let me know also.

We are using Microsoft technologies for a number of our services and products. Most recently our Windows Phone app for Jive.

 

Using the Jive REST API from a .Net/C# application is actually very straightforward, so I am going to outline a basic example in this post.

Assumptions:

  • Jive system that supports the v3 api. I am using Jive Cloud in this example
  • .Net 4.5(.1) based project. I am using Visual Studio 2013 Update 2

 

In this example we are going to retrieve a person object from Jive (Jive REST Rest API v3.7 → Person entity)

 

The data model:

The person object

    public class Person
    {
        public string displayName { get; set; }
        public int followerCount { get; set; }
        public int followingCount { get; set; }
        public int id { get; set; }
        public string location { get; set; }
        public string status { get; set; }
        public string thumbnailId { get; set; }
        public string thumbnailUrl { get; set; }
        public DateTime updated { get; set; }
        public List<ProfileEntry> emails { get; set; }
        public JivePerson jive { get; set; }
        public Name name { get; set; }
        public List<ProfileEntry> phoneNumbers { get; set; }
        public List<ProfileEntry> photos { get; set; }
        public DateTime published { get; set; }
        public List<string> tags { get; set; }
        public JiveResource resources { get; set; }

    }

The JivePerson object that holds the Jive specific information about a person

    public class JivePerson
    {
        public bool enabled { get; set; }
        public bool external { get; set; }
        public bool externalContributor { get; set; }
        public bool federated { get; set; }
        public DateTime lastProfileUpdate { get; set; }
        public Level level { get; set; }
        public string locale { get; set; }
        public List<ProfileEntry> profile { get; set; }
        public bool sendeable { get; set; }
        public bool termsAndConditionsRequired { get; set; }
        public string timeZone { get; set; }
        public string username { get; set;}
        public bool viewContent { get; set; }
        public bool visible { get; set; }
    }

 

Additional objects for statuslevel, profile entries and names

    public class Level
    {
        public string description { get; set; }
        public string imageURI { get; set; }
        public string name { get; set; }
        public int points { get; set; }
    }


    public class ProfileEntry
    {
        public string jive_label { get; set; }
        public string value { get; set; }
        public string type { get; set; }
        public bool primary { get; set; }
    }
    public class Name
    {
        public string familyName { get; set; }
        public string formatted { get; set; }
        public string givenName { get; set; }
    }

 

 

Now that we have the datamodel for our person, let's retrieve a person via the rest api. In our example we are going to use the simplest call by getting the logged in user. I've hardcoded the necessary Urls in this example.

 

string jiveServer = "https://community.jivesoftware.com";
Person person = await JiveDataSource.GetPersonAsync(jiveServer + "/api/core/v3/people/@me");

 

The asynchronous method gets the Json describing the person using the ExecuteAbsolute method in the JiveRequest class.

Afterwards the JsonConvert.DeserializeObject method from the Json.net libary is used to create a person object from the Json.

 

   public static async Task<Person> GetPersonAsync(string url)
        {
            JiveRequest myJiveRequest = new JiveRequest();


            string jiveCommunityJSON = await myJiveRequest.ExecuteAbsolute(url);
            Person myPerson = JsonConvert.DeserializeObject<Person>(jiveCommunityJSON);
            return myPerson;
        }

 

Finally here is the JiveRequest.ExecuteAbsolute method. Again values are hardcoded in this example

 

        public async Task<string> ExecuteAbsolute(string url)
        {
          
            string jiveCommunityUrl = "https://community.jivesoftware.com";
           //This example uses basic auth. OAuth based authentication is also possible

            string userName = "myuser";
            string password = "mypassword";

            System.Net.Http.HttpClientHandler jiveHandler = new System.Net.Http.HttpClientHandler();

          //Setting credentials for our request. This needs to be done for every request as there are no persistent sessions for the REST Api
            NetworkCredential myCredentials = new NetworkCredential(userName, password);
            myCredentials.Domain = jiveCommunityUrl + "/api/core/v3";
          //Getting our credentials in Base64 encoded format
            string cre = String.Format("{0}:{1}", userName, password);
              byte[] bytes = Encoding.UTF8.GetBytes(cre);
           string base64 = Convert.ToBase64String(bytes);
          //Set credentials and make sure we are pre-authenticating our request
            jiveHandler.Credentials = myCredentials;
            jiveHandler.PreAuthenticate = true;
            jiveHandler.UseDefaultCredentials = true;

           httpClient = new System.Net.Http.HttpClient(jiveHandler);
            httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", base64);


            HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, url);

            System.Net.Http.HttpResponseMessage activityResponse = await httpClient.SendAsync(requestMessage);
            String myActivityResponse = await activityResponse.Content.ReadAsStringAsync();
          //Remove the string Jive includes in every response from the REST API
            string cleanResponseActivities = myActivityResponse.Replace("throw 'allowIllegalResourceCall is false.';", "");


            return cleanResponseActivities;


        }

Filter Blog