Using the Jive Application Gateway API

Version 2

    Overview

     

    One of the more useful features in Jive  Apps is the ability to have an external server, let's call it the app home server, push activity from external sources into a user's activity stream. This tutorial goes over the concepts behind this feature and  outlines the steps necessary for an app to have externally generated activity show up in a user's activity stream.

     

    AppGatewayActivity.png

     

    Background

     

    As outlined in the Using the OpenSocial API tutorial Jive apps have access to a lot of data in a Jive community.  Apps may also request information from other servers by using the open social api to make calls and receive data which they can use to display information to the user, update state, etc. Jive apps however only run when they are being displayed to the user as they do not have the  ability run as a background process. As an app developer you often want to keep the user appraised of updates that happen even when your app is not running and by having your apps' home server push activity to the Jive Application Gateway you can accomplish that goal.

     

    Be aware that to make this feature work you will need a home server for the app that can accept requests from the Jive Application Gateway (let's call it the gateway server) and which can also push activity to the gateway server. If the app home server is behind a firewall bidirectional communication between the app home server and the gateway server must be allowed or this feature will not work.

     

    We'll be modifying the app you created in the Creating a Basic "Hello World" App tutorial, so if you haven't already go through that tutorial before continuing with this tutorial.

     

    Step 1: Download and run the example home server

     

    For this example, we'll use the Tomcat application server for the home server. Please note that using Java on your app's home server is not a requirement at all. In fact you can use just about any language for which there is an OAuth library available (see http://oauth.net/code/ for a list) or for which you're willing to write one. Speaking of OAuth let's note up front that using OAuth for authentication between the app home server and the gateway server is a requirement for this feature to work. The example server has a working implementation that you can check out to see how it works.

     

    Download and install Tomcat from http://tomcat.apache.org/. Once you've done that checkout the example web application from here, do a maven buid (mvn clean package) and copy the generated activity.war into the [TOMCAT_HOME]/webapps directory. Start tomcat and hit the page http://[your_domain_here]:8080/activity to verify that the webapp was installed correctly.

     

    Alternatively, for your convenience Jive has hosted the activity.war java webapp in Google App Engine here, you may point your Jive app to it as shown in the sample app or install the sample app itself in your dashboard. To do this copy the app URL, go to app-sandbox's Apps tab, click on "Jive Apps Market" button and paste the URL. Once you have the app installed, go the app and click on the link in "If you just installed this app, go to http://jive-activity.appspot.com to post external activities.". You'll notice that your user id is sent as a paramter uid. This is the id of the user that is performing the post.

    If you are using your own Jive app , then be sure to copy the lifecycle events (described in Step 2 below) to your app, send the uid parameter and finally enter your app's consumer key and secret in the webapp's page from where you will be posting an activity. If you'd like to play with the external server, you may download the sources from here. Note that the request from the app are proxied through Jive server to the Jive Application Gateway which then forwards the request to your server.

     

    Step 2: Setup the app

     

    Create a new app

     

    $ jiveapps create activityexample

     


    Take note of the information returned as you will need to use this information further on in the tutorial.

     

    This feature requires that your app communicate to it's home server. To allow this your app must require the open social feature. Go ahead and edit the app.xml and add in the <Require ... /> as in the example below.

     

    <?xml version="1.0" encoding="UTF-8" ?>

    <Module>

       <ModulePrefs title="Gateway Tutorial App">

       <Require feature="opensocial-1.0"/>

    ...

    </ModulePrefs>

    ...

    </Module>


    When the app is installed into a jive installation (as well as uninstalled) it will send a request to the home server configured using the ModulePrefs/Link element as shown below. Go ahead edit the app.xml file to add this element as shown in the example below (be sure to change the urls to reflect where your home server is installed).


    <?xml version="1.0" encoding="UTF-8" ?>

    <Module>

        <ModulePrefs title="Gateway Tutorial App">

             <Require feature="opensocial-1.0" />

             <Link rel="event.addapp" href="http://[your_domain_here]:8080/activity/installed" />
             <Link rel="event.removeapp" href="http://[your_domain_here]:8080/activity/uninstalled" />

    ...


    For each event type a single GET request will be made to the provided url. The request will be OAuth signed and include opensocial parameters and an eventtype parameter with values "added" or "removed". For example if the href was set to "http://your_home_server.com:8080/activity/installed" then Jive will make the following request (via the gateway server). Note: the "Link" tag should be capitalized and please ensure that you do not include a trailing "/" at the end of the href.


    http://your_home_server.com:8080/activity/installed?eventtype=added

    &oauth_consumer_key=testAppKey&oauth_nonce=7sGE00xSfY4PBStICbXyPbIliNymOhu2
    &oauth_signature_method=HMAC-SHA1&oauth_timestamp=1290013827&oauth_version=1.0
    &opensocial_app_id=application_id&opensocial_app_url=
    &opensocial_owner_id=1001@jive_id&opensocial_viewer_id=1001@jive_id
    &oauth_signature=N7mODAf9OJ1DXQRPisRqGK4DNMo=

     

    The value of the 'opensocial_owner_id' parameter will be formatted 'userID@instanceUUID' which the home server will have to save and use later on when publishing activity for that user to the gateway server. The value of the 'opensocial_app_id' parameter is the unique UUID for your app which the home server will also have to save and use later when publishing activity to the gateway server.

     

    Now go ahead and use git to add, commit and push your changes to the sandbox server. Once you visit the sandbox canvas url for your app you will be presented with a dialog box to configure your app. It's only once you have accepted the permissions will the jive server make the request to the href listed in the event.addapp link.

     

    Step 3: Activity stream format

     

    Now that the app has run and sent the example home server all the information required to push activity to the gateway server let's go over the format that the gateway server requires activity to conform to.

     

    The activity stream format that the gateway server requires is based on the activitystrea.ms api spec (the 'Types' section). Being experimental this spec is incomplete and includes features which are unsupported in Jive's activity stream implementation. Given that we'll go over in detail a few examples of different types of activity that your app may push to the gateway server and outline any differences between the format required by the gateway server and the above mentioned experimental spec. As you can see from the examples below the format uses the JSON syntax.

     

    A basic activity stream with a single activity

     

    {

          "items":

          [{

              "title": "Bessie the cow was fed",

              "body" : "Fred Flintstone fed Bessie the Cow"

         }]

    }

     

    The above example has just a single activity with just a title and a body.  Activities by their nature have 'verbs' (User A created document X) and  activity streams are no different. Any activity that does not have a  verb listed will have the implied verb 'post' associated with it. Verbs are a way to specify the type of action which was done by the actor. The activitystrea.ms site define a number of verbs and it is possible to use verbs not listed there as well. Jive will accept any verb list and attempt to map  the verbs to a known type within the system. if no mapping is found Jive  internally will use the 'post' verb. Verbs are also used internally in Jive as part of the key used to determine which stream channel the  activity will be inserted into. Activities with the same verb will be  grouped into the same channel.

     

    In the above example the body of the activity is plain text which is a requirement for Jive. Any html formatting present in the body will be removed before being rendered to the end user. Jive does provide a mechanism to allow links to be generated which will be explained further on in this tutorial. The displayed body text has a practical limit of about 160 characters in the default Jive UI, and the title has a practical limit of about 120 characters. More text will just overflow the visible area of the UI and be hidden.

     

    Here's an example of an activity in an activity stream that has multiple verbs specified from most specific to least specific

     

    {

          "items":

          [{

              "verb" : ["http://activitystrea.ms/schema/1.0/favorite", "post"],

              "title" : "Bessie the cow was fed",

              "body" : "Fred Flintstone fed Bessie the Cow"

         }]

    }

     

    In the above example there are two verbs listed from most specific to least specific. The most specific verb specified "http://activitystrea.ms/schema/1.0/favorite"  will be used as part of the key to determine which channel the activity will be inserted into in Jive, whereas the "post" verb (since it is  recognized directly by Jive) will be used to map the activity to a known modification type in Jive - in this case, the 'Create' modification  type.

     

    Jive supports localization of activity content by using the Open Social format for I18n keys  ("__MSG_message.resource.key__"). Here's an example of an activity whose text has been completely internationalized

     

    {

          "items":

          [{

              "verb" : ["http://activitystrea.ms/schema/1.0/favorite", "post"],

              "title" : "__MSG_feed.title.format__",

              "body" : "__MSG_feed.body.format__"

         }]

    }


    To make this work the app has to specify the corresponding keys in the locale section of the app.xml


    <?xml version="1.0" encoding="UTF-8" ?>

    <Module>

        <ModulePrefs ...>

            ...

            <Locale lang="en">

                <msg name="feed.title.format">Fred fed Bessie the cow</msg>

                <msg name="feed.body.format">Bessie the cow was fed</msg>

                ...

            </Locale>


    The above example is interesting but not terribly useful in a lot of cases since it hardcodes 'Fred' and 'Bessie the cow'. The solution to this is to use named tokens such as ${object.title} to support dynamic replacement with values set in the activity stream. Here's an example of this


    {

         "items":

         [{

             "verb" : ["http://activitystrea.ms/schema/1.0/favorite","post"],

             "title" : "__MSG_feed.title.format__",

             "body" : "__MSG_feed.body.format__",

             "actor" : { "id" : "http://your_domain_here.com/user/123456789", "title" : "Fred"},

             "object" : { "title" : "Bessie the cow"}

        }]

       }


    And the corresponding locale section of the app.xml


    <?xml version="1.0" encoding="UTF-8" ?>

        <Module>

            <ModulePrefs ...>

                ...

                <Locale lang="en">

                    <msg name="feed.title.format">${actor.title} fed ${object.title}</msg>

                    <msg name="feed.body.format">${object.title} was fed</msg>

                    ...

                </Locale>


    Often you will want your activity to reference the user or create a link to the object in the body of the activity. To allow this Jive supports special @ tokens which Jive will use to build links. The supported tokens are ${@actor}, ${@object}, ${@target} and ${@generator}.