Skip navigation
1 2 3 4 5 6 Previous Next

Jive Developers

169 posts

jw16-developer-conference-logo.png

Since the JiveWorld14 Developer Conference, we've been hard at work innovating on the Jive platform that enables developers to build solutions that help company's connect, communicate and collaborate!  It's now time for JiveWorld16, and we've created an agenda that is jam-packed with sessions and activities to inspire your inner-hacker creativity, plus showcase the latest enhancements to the Jive platform and connect with fellow Jive developers. This conference is the must-attend event of the year for Jive developers!

 

WHEN

March 14th -16th, 2016

WHERE

Aria Resort & Casino
Las Vegas, Nevada

 

REGISTER NOW

 

Here are just a few of the events we have planned for conference attendees ...

 

Tech Talk: Developing and Deploying Java-based Microservices in Kubernetes

Join us for an awesome tech talk with Google's own Ray Tsang (Sr. Developer Advocate) and Amir Hermelin (Product Manager) for the Google Cloud Platform.  In this session, you’ll learn: – How to containerize different Java-based microservice workloads using Docker and different build tool plugins – Deploying and managing a fleet of Java-based microservices in Kubernetes – Service discovery 101 in Kubernetes – Perform critical DevOps steps, such as canary, rolling update, roll backs… – Tips and tricks!  view session details

 

logo_lockup_cloud_platform_icon_vertical-300x185.pngray-tsang-google-150x150.jpegamir-hermelin-headshot-150x150.jpg

 

 

JiveWorld16 Tri-Hackathon

jw16-dev-trihackathon-logo-teal-285x300.png

 

A new and improved hackathon experience that challenges multiple facets of the developer persona—from coding skills, to technology trivia to video games.   With an army of Jive developer experts available to answer questions and offer guidance, learning the Jive platform as never been so easy, effective and fun!

 

Plan on attending the JiveWorld16 Tri-Hackathon?

Please take a moment to pre-register and select your preferred T-Shirt size.

PRE-REGISTER TODAY (FREE)

Teal_T-Shirt_Render.jpg

For more details about this tri-hackathon, check out:

Announcing a Tri-Hackathon at JiveWorld16 Developer Conference w/Limited Edition T-Shirt

 

 

JiveWorld16 Developer Sessions & Hacker Lounge

Have a question about building integrations with Jive?  Dive into the details with Jive engineers on the latest Jive platform features and improvements, plus learn from fellow Jive developers how to build proven solutions with Jive Add-Ons and APIs.  This is over 24+ hours of interactive access to Jive Engineers who are ready and able to answer your questions about building your next Jive integration. Pull up a chair, break out your laptop and get your hard questions answered while hacking with knowledgable Jive developers.

 

Kurt-Collins_Built.io_-e1452288829181-150x150.jpg

On a special note, many of you may have seen a recent Jive developer blog post - Built.io Flow: Caffeinate Complex Workflows (1 of 3)

 

We are honored to welcome Kurt Collins from built.io to the JiveWorld16 Developer Conference.  He will be doing a joint session with Lev Waisberg from Jive on the future of integrations in the cloud.  Specifically, Kurt will be discussing the impact and growth of iPaaS architectures and solutions and sharing his insights into the industry.

 

For more session details:

Fast Forward: Jive Microservices & iPaaS Integrations | JiveWorld Session

builtio_flow_logo_1024.png

Introducing Built.io Flow

As we're about to enter a new year, what's a better way to start than to add a new tool to your developer arsenal and be able do more with less work? Built.io's Flow platform lets you do exactly that and so much more. Flow is an iPaaS that allows us to take processes and business rules that were very complex and time-consuming to code and simplify everything using visual tools requiring mere minutes of work. With a long list of 3rd party integrations (and getting longer), you can now tie some of the most common services into one easy to create visual workflow with no middleware to set up, monitor, and maintain.

 

As part of the list of integrations available, I'd like to announce the addition of the first set of Jive APIs that are now available in this powerful tool. You can now access Jive content, people, and places within Built.io Flow to not only get and create content from sources, but also enrich your Simple Activity Stream Integrations by combining data from multiple sources before sending your payload to Jive—an easy way to overcome the 250ms limit for processing your transform function without.

 

 


 

Using Built.io Flow for Jive Inbox Action

In this example, we'll demonstrate how to use Built.io Flow to create an Action Activity to send to any user's inbox. This is so quick and easy that it should take under 5 minutes from start to finish to repeat this process.

Screen Shot 2015-12-17 at 6.43.19 PM.png

 


 

Getting Started

After signing up for your Built.io Flow trial account and logging in, you'll be presented with a screen displaying all of your flows. We'll start by clicking +CREATE NEW FLOW in the top right corner. For the Flow Name field, we'll enter "Jive Action Inbox"; the other fields are optional.

 

Screen Shot 2015-12-17 at 4.22.59 PM.png

 


 

Adding Jive Create Action Activity

Click on ACTIVITIES on the right hand tab that's sticking out from the right edge of the browser view. Scroll down to the Jive integration and then drag the Create Action service onto the canvas.

If you're using Jive Anywhere (you should if you aren't), the ACTIVITIES tab may be hidden by the Jive Anywhere tab in your browser.

Screen Shot 2015-12-17 at 5.13.41 PM.png

 


 

Adding Custom Parameters

Click the gear icon and then the + icon to add a parameter. We'll be creating a parameter with a key of "user_id" and value of "undefined". This key will be passed in later on in a POST request with a value of our choice to the webhook subscription endpoint for our flow.

Screen Shot 2015-12-17 at 5.22.46 PM.png

 


 

Configure Jive Activity Action Service

  1. Review our REST API documentation for the Activity Action service.
  2. Connect to your Jive Instance with your Basic Auth credentials by selecting "Add New" from the Jive Connection dropdown menu.
  3. Enter a title to be displayed to the user for the notification—"Was this easy or what?"
  4. Enter content "Low cost and low commitment user feedback is great!"
  5. For the Person URLs, since we'll be only calling one user per call, we're going to enter the following:
  6. Add an action link for the user to give a response. Include a caption for the response button, HTTP verb, and URL
    • NOTE: The entry into the target URL field is not a client redirect but a server-side request. The Jive server will perform the http request with the defined method once the user clicks the button.
  7. Click Done.

Screen Shot 2015-12-17 at 6.19.25 PM.png

 


 

Finishing Touches

  1. Map the connectors from the start to the Jive Create Action service to the flow end icon.

  2. Enable the webhook from the flow start module and copy the URL.

  3. Press SAVE.
  4. Use CURL or POSTMAN to send a POST request to the subscription URL you just copied and URL encode the user_id key and your Jive user ID as the value.
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'user_id={JIVE USER ID}' 'https://flow.built.io/run/XXXXXXXXXXX'

Screen Shot 2015-12-17 at 6.26.49 PM.png

 


 

What's Next

  • In the next update, we'll tackle a very common use case where we will integrate other services to bring data into Jive and Jive initiating another workflow to add data into another service!

Want to write services for Jive in a language you love? Here's a refreshing initative to help your fellow developers in the Jive community, write something cool, or test out that language you've been wanting to learn all while having some fun and earning some extra money! What we're looking for is a minimal viable SDK in a language of your choosing and complete as many of the required items you can (listed below) to earn up to $200 per SDK! Clone the repo's below and submit a pull request with your additions for review.

 

Feeling good about your accomplishments and want to tell the world? You can blog about your contributions here in the Jive Community or mention us on Twitter @JiveDev and we'll help spread the word!

 

fries.png


 

Submissions Due

Due to the holiday season coming up, we are offering two timelines for gift card awards.

  1. Submit your pull request by November 30 and receive your gift card by December 4th! Just in time to use them for Gifts!
  2. Last submission due no later than 11:59PM PST on January 31. Gift cards will be awarded after all reviews are complete.

 


 

Prizes

GiftCards.png

Gift Cards with an amount based on the completeness and quality of your committed project, you can get a gift card for up to $200 for each submitted SDK. Choose from Amazon, Apple or even Burger King (others may be available by request)! It's possible to also earn money for clean/performance rewrites of code, improving the documentation, or other types of complementary contributions. Cards will be awarded with values ranging from $5-200. After review, we will contact you regarding where you'd like to receive the digital gift card(s).

 


 

Languages in Progress

Clone the repo's below. *Contributions to other repo's may not result in an award.

 

SDK (package manager friendly)

Example (project repo's)

For languages that apply, examples must use industry accepted frameworks (e.g., Python using Flask or Django framework).

 


 

Reference Jive SDKs / Implementations

Use these SDK's as a foundation to validate your understanding and methodologies for building in the languages listed above.

 


 

Minimum Viable SDK Requirements

  1. Validate headers — register and unregister ( Ensure Register Calls are Coming from a Genuine Jive Instance )
  2. Validate signed fetch add-on requests (How to Validate Signed Requests from an App Bundled in an Add-On )
  3. Examples Framework ( Getting Started > Building a Jive Add-On  )
    • Tile (with /jive/tile/register & /jive/tile/unregister endpoints)
    • App (with static assets — html, css, js)
      • Optional: Dynamic server-side component
    • Add-On (with configure screen)
  4. Documentation of methods for each task

 

Other ways To Contribute (and earn!)

  • Performance and legibility improvements to code.
  • Improve documentation by writing clear and succinct explanations of codebase and methods to run.
  • Automation, test cases, and other types of contributions (creativity is encouraged!).

 


 

Disclaimers

  • We reserve the right to deny contributions if they are not complementary to the nature of the project.
  • All participants must be a member of and following the Jive Developer Community.

Hello Jive Devs,

 

Today we launched a new web tool for creating an OAuth 2.0 clients for your Jive instance. Previously, your options were to use the Node.JS Jive-SDK or build the add-on from scratch, well this tool allows for greater customization in your zip in fewer steps. You simply need to enter a redirect URL in the field and give your add-on a title, description, and square icon (it will be resized automatically into 3 separate sizes). Try it out, get some tokens and build your next add-on with secure REST API calls: OAuth 2.0 Client Builder - Jive Developers

 

Screen Shot 2015-10-07 at 1.17.56 PM.png

 

We've also updated some of our old documentation to provide one resource for your Jive OAuth2 questions: OAuth 2.0—Creating a Client and Managing Access

 

Hope you find the tool useful. Post your feedback, suggestions, questions in the comments below!

 

 

//Rashed

Introduction

sfdc-report-wide-upgrade2.pngIn this example we're going to walk through how to build a tile in Jive that displays data from a Salesforce report. We'll use a custom view tile to be able to fully control the user interface, and we'll configure the tile with external data provider option to use data sent from our add-on integration service. For background info on custom view tiles, check out Creating Custom View Tiles.

 

The diagram below shows main components of this integration and screenshot on right shows the tile with data from a sample report in Salesforce developer instance.

sfdc-report-tile-arch.001.png

When using external data provider option, the add-on service can periodically query report data and send that to Jive to be available for tile rendering. This means each time a tile is displayed, it is rendered using latest data sent to Jive and no requests are made to the add-on service.

 


 

Getting started

To get us started off, you'll first need to have the following ready:

 

Download Sample on GitHub

Download the sample project at: https://github.com/jivesoftware/sfdc-report-tile

 

Installing Salesforce API Key

To get access to Salesforce API, go to your Salesforce developer account and configure the integration at Setup, Create, Apps, and use OAuth scope settings from screenshot below. The callback URL needs to point to the OAuth endpoint on your Node.JS/Jive-SDK add-on service.

 

Here's how to access the Setup menu

Screen Shot 2015-10-06 at 14.04.22.png

 

Here are the OAuth settings

sfdc-report-oauth-app.png

 

The Consumer key and secret from Salesforce app definition are set in /jiveclientconfiguration.json

"oauth2-sfdc": {

  "originServerAuthorizationUrl": "https://login.salesforce.com/services/oauth2/authorize",

  "originServerTokenRequestUrl": "https://login.salesforce.com/services/oauth2/token",

  "clientOAuth2CallbackUrl": "http://localhost:8090/oauth/oauth2Callback",

  "oauth2ConsumerKey": "3MVG9y6x0357Hlee8TDL6y5tOH95AsjUFac6us6C.8e0KncuDmapBf6UaRVA._.xKjlMw_0HA80SXGIi6Frvq",

  "oauth2ConsumerSecret": ""

}

 


 

Tile setup

The sample project has two tile definitions, one for wide tile layout slot and one for narrow. We use two definitions only to detect layout slot type for display handling and actual tile implementation is all under sfdc-report-wide tile. Here is the definition for the wide tile, see tiles/sfdc-report-wide/definition.json:

{

    "config": "/sfdc-report-wide/config?type=wide",

    "displayName": "Salesforce Report Wide",

    "name": "sfdc-report-wide",

    "style": "CUSTOM_VIEW",

    "displayWidth": "WIDE",

    "view": "/sfdc-report-wide/view?type=wide",

    "action": "/sfdc-report-wide/action?type=wide",

    "dataProviderKey": "external",

...

}

The field "style":"CUSTOM_VIEW" defines that tile is rendered with HTML from "view" endpoint, and "dataProviderKey":"external" means that data push from external add-on service is provided to the tile javascript startup function.

 

Tile Configuration

When configuring the tile, user will login to Salesforce and grant API access for this app according to standard OAuth 2.0 web server authentication flow, resulting in a token used to make Salesforce API calls. To accomplish this our add-on needs to implement an OAuth Client, which is done by including "oauth2client.js" in your configuration page and calling OAuth2ServerFlow() on page load. Note that oauth2client.js is provided by the Jive-SDK and is not included as a file in the sample project.

 

/tiles/sfdc-report-wide/public/config.html

<script src="/javascripts/oauth2client.js"></script>

...

<button type="button" id="grant-button">Grant Access</button>

 

/tiles/sfdc-report-wide/public/javascripts/config.js

$(document).ready( function() {

  var options = {

    grantDOMElementID: '#grant-button',

    authorizeUrl: '/oauth/authorizeUrl',

    ...

  };

  OAuth2ServerFlow( options ).launch();

});

 

 

OAuth Configuration

OAuth2ServerFlow function defines a callback for the button defined with grantDOMElementID option, and when clicked, initiates the authentication flow with Salesforce.

sfdc-report-config-oauth-grant.png

The authorizeUrl option points to an endpoint on your add-on service that handles communication and token storage. This is implemented by extending OAuth util class from the Jive-SDK.

 

/services/sampleOauth.js

var jive = require('jive-sdk');

var oauthUtil = jive.util.oauth;

var tokenStore = jive.service.persistence();

 

// overrides jive-sdk/routes/oauth.js to store access token

var myOauth = Object.create(jive.service.routes.oauth);

module.exports = myOauth;

 

myOauth.fetchOAuth2Conf = function() {

    return jive.service.options['oauth2-sfdc'];

};

 

myOauth.oauth2SuccessCallback = function( state, originServerAccessTokenResponse, callback ) {

    var content = originServerAccessTokenResponse['entity'];

    tokenStore.save('tokens', state['viewerID'], {

        ticket : state['viewerID'],

        accessToken: content['access_token'],

        refreshToken: content['refresh_token'],

        instanceUrl: content['instance_url']

    })

    .then( function() {

        callback({'ticket': state['viewerID'] });

    });

};

 

myOauth.getTokenStore = function() {

    return tokenStore;

};

 

When user has completed the OAuth flow, configuration page uses add-on service endpoints to get recently selected reports, and to search for reports. User interface controls were implemented with JQuery UI Dialog and Autocomplete.

Screen+Shot+2015-08-24+at+11.42.28.png

 

Selecting a report

The config page uses JQuery autocomplete to display results for searched reports. Results are retrieved with a call to osapi.http.get() which proxies the call via Jive server, and targets an endpoint on add-on service.

 

/tiles/sfdc-report-wide/public/javascripts/config.js

osapi.http.get({

  'href': SERVICE_BASE_URL + '/sfdc-report-wide/search?' +

          'ticketId=' + ticketId +

          '&term=' + encodeURIComponent(searchTerm),

  'format': 'json',

  'authz': 'signed'

}).execute(function( response ) {

  ... show search results

})

 

Implementing the search endpoint route on server

/tiles/sfdc-report-wide/backend/routes/search/get.js

exports.search_route = function (req, res) {

  var url_parts = url.parse(req.url, true);

  var queryPart = url_parts.query;

  var term = queryPart["term"];

  var ticketId = queryPart["ticketId"];

 

  sfdc.getReportsBySearchTerm(term, ticketId)

  .then(function (entity) {

    // success response

  }).catch(function (err) {

    // error

  });

};

 

See next section for details on how getReportsBySearchTerm function is implemented.

 

When user has selected a report, and clicks apply to save tile configuration, the page saves report ID, name and instance URL from Salesforce with a call to jive.tile.close(). This triggers Jive to register the tile instance with add-on service with the provided configuration.

 

/tiles/sfdc-report-wide/public/javascripts/config.js

$("#configure").click(function() {

  ...

  jive.tile.close({

    reportId: reportId,

    reportName: reportName,

    instanceUrl: sfdcInstanceUrl,

    ticketId: ticketId

  });

});

 


 

Getting report data

 

Using Salesforce API

When querying for data, the ticket id from tile instance configuration is used to find OAuth token from data storage, and then Salesforce Reporting API  is used to get report data. OAuth token is sent in Authorization header of each request and error response codes are handled to refresh the token and detect if a report has been removed from Salesforce (see the full code sample for this error handling).

 

/services/sfdc-client.js

var API_PATH = '/services/data/v33.0';

 

exports.getReport = function(reportId, ticketId) {

    return doGet("/analytics/reports/" + reportId + "?includeDetails=true", ticketId)

    .then( function(response) {

        return response.entity;

    });

};

...

function doGet(uri, ticketID) {

    var tokenData;

    return getAuthToken(ticketID)

    .then(function(found) {

        if (found) {

            tokenData = found;

            var headers = {'Authorization': 'Bearer ' + found.accessToken};

            return jive.util.buildRequest(found.instanceUrl + API_PATH + uri, 'GET', null, headers, null);

        }

    });

}

 

In a similar way, Salesforce Query API is used to search for reports based on name.

exports.getReportsBySearchTerm = function(term, ticketId) {

    var query = "select Id, Name, Format from Report where Name like '%" + term + "%' limit 50";

    return doQuery(query, ticketId)

    .then( function(entity) {

        return entity;

    })

};

...

function doQuery(query, ticketId) {

    return doGet("/query?q=" + encodeURIComponent(query), ticketId)

    .then( function(response) {

        return response.entity;

    });

}

 

Sending data to tile

The add-on service will periodically query for Salesforce report data, and send it to Jive for each registered tile. This is done by registering a task with jive.tasks.build() which will be executed by jive-sdk at specified interval. Data is set to Jive with jive.tiles.pushData() function and will then be stored by Jive and will be available when rendering tile.

 

/sfdc-report-wide/backend/services.js

exports.task = new jive.tasks.build(

    function() {

        jive.tiles.findByDefinitionName( 'sfdc-report-wide' ).then( function(instances) {

            instances.forEach( function( instance ) {

                exports.processTileInstance(instance);

            });

        });

    },

    120*60*1000 // 2hr interval

);

...

exports.processTileInstance = function(instance) {

    var reportData;

    var cfg = instance.config;

 

    sfdc.getReport(cfg.reportId, cfg.ticketId)

    .then(function(data) {

        reportData = data;

        return sfdc.getReportProperties(cfg.reportId, cfg.ticketId);

    })

    .then(function(properties) {

        var tileData = {

            title: reportData.reportMetadata.name,

            detailColumnInfo: [],

            groupingColumnInfo: [],

            groupingsDown: reportData.groupingsDown.groupings,

            aggregates: reportData.reportMetadata.aggregates,

            contents: reportData.factMap,

            ...

        };

        .... report data processing

        return jive.tiles.pushData(instance, {data: tileData});

    })

};

 

Salesforce report "fact map" data values are passed here as-is to the tile, but the data payload could be completely custom. Grouping info and aggregate data for summary reports are also sent for rendering groups in tile grid. Metadata about each column containing display label and data type is saved into detailColumnInfo field.

 

Rendering tile

When tile is rendered Jive gets the html page from "view" endpoint defined in tile's definition.json. The page javascript gets latest data push in jive.tile.onOpen() handler and renders it using jqGrid. Tabular report data rows are simply passed to jqGrid for display, but summary reports also require handling of groupings and aggregate values.

 

/tiles/sfdc-report-wide/public/javascripts/view.js

jive.tile.onOpen(function(config, options) {

    var app = new ReportView(config);

    app.init();

});

...

function ReportView(data) {

    this.data = data;

}

...

ReportView.prototype.init = function() {

  var gridOptions = {

    datatype: 'local',

  };

  ...

  if (this.data.type == "TABULAR") {

    $.each(this.data.contents['T!T'].rows, function (n, row) {

      // ...add data rows to grid

    });

  }

  else if (this.data.type == "SUMMARY") {

    gridOptions.grouping = true;

    // ...define summary groupings and aggregates for jqGrid

  }

  ...

  $("#grid").jqGrid(gridOptions);

}

 


 

What's Next?

This fall, we'd released a new update to the Jive Cloud platform (2015.3) and along with that comes a couple of great new features and updates to our REST API. We also brought a couple of new posts and tools to make your integrations richer, built easier and faster than ever before. We did a lot of tidying up with this release and squashed quite a few bugs while we're working hard on the next major release that's sure to completely WOW you—release 2016.1.

 

REST API Improvements

Jive REST API v3.13 → Moderation & Abuse - Get a count of pending moderation items (added)

Jive REST API v3.13 → Content Service - View content that's flagged as featured (added)

Jive REST API v3.13 → Person Service - Get profile field privacy of users (added)

Jive REST API v3.13 → Person Service - Endpoints for CRUD and sorting of profile fields (added)

Jive REST API v3.13 → Video Service - Cleaned up to a canonical package (updated)

Jive REST API v3.13 → Content Service - Resize capabilities to /previewImage API (updated)

 

 

New Documentation & Posts

Deploying Jive SDK Node.JS Solutions with JXcore

Creating a Twitter Widget Custom View Tile with Configuration

Ngrok: Warp Speed for Your Integration Iterations

Dev Tool: Using the Simple Stream Integration Builder with StatusPage.io (1 of 3)

Dev Tool: Build an App w/ the Simple Stream Integration Builder (2 of 3)

Dev Tool: Simple Stream App with Bi-Directional Communication (3 of 3)

 

 

Stay tuned for more news and updates on our next release and keep yourself checking the Jive Developer community often on new guides, documents, blogs, and great support!

 

 

Reminder

Want to Speak at JiveWorld16 Developer Conference?

Las Vegas - Aria Resort & Casino

March 14-16, 2016

 

 

If you've built a Custom View Tile or Simple Stream Integration that you're really proud of and want the chance to talk about it and how you did it to an audience of developers at JiveWorld16, this might be your chance! Go to this thread and see if you're eligible to speak and get a free pass!

 

Hello JiveMinds,

 

       We have come up with some solution for the ideas mentioned in the https://community.jivesoftware.com/ideas/4183 post. The solution that we have designed contains:

1. Bulk Content Move

2. Bulk Content Deletion

3. Bulk Apply Tags

4. Bulk Apply Categories

The app is called 'Content Manager'

 

        The idea came up as we were getting requests for getting some way to perform multiple operations like moving the content/s, deleting in bulk as deleting content one by one is tedious. Plus categorising content with specific categories and tags makes easy to search and manage. To facilitate the common platform for doing all these operations, we came with a solution - Content Manager.

        I will explain the features that we have developed so that it will easy to understand the functionality and use case.

 

 

All about app:

This app is being designed for groups and spaces meaning it will appear on Group's/Space's tab section.

Before doing any operation user need to select the content and for that we have designed the tabular format to ease up the selection process, it includes:

Content Types: As you can see, the table contains content of various types. But if user wants to perform specific operation on specific content, he/she can select the content type from the 'Content Types Dropdown'

Screen Shot 2015-09-29 at 10.11.19 pm.png

 

 

 

Show All/Owned Content: There can be situation where user wants to apply metadata or update the contents that are owned by him/her. In that case user can select the Show only my content else can continue with show all content otherwise.

Screen Shot 2015-09-29 at 10.15.56 pm.png

 

 

 

Filtering Criteria: The user can filter out the content based on various parameters like Last activity, Created first etc.

Screen Shot 2015-09-29 at 10.19.11 pm.png

 

 

 

 

Features:

1. Bulk Content Move:

  This feature transfers the selected content from source group to selected destination group.

Steps followed to perform the same operation:

1. Select the content to be moved from the table

2. Select the target place from the place picker that will be invoked once you click on move content icon.

3. Once the content and target place selected the conformation will be needed before proceeding :

Screen Shot 2015-09-29 at 10.23.57 pm.png

 

4. Once you confirm the move, the selected content will be moved to selected place. Following view will be displayed:

Screen Shot 2015-09-30 at 10.54.02 am.png

 

Selected content has been moved and highlighted with green. If at all for some reason, move fails the corresponding row will be highlighted in red colour with error message.

What do we do at the backend?

Screen Shot 2015-09-30 at 11.01.43 am.png

 

 

 

2. Bulk Content Deletion:

   This feature deletes the selected content.

Steps followed to perform the same operation:

1. Select the content to be deleted from the table

2. Once selected click on delete icon which would ask for deletion confirmation:

Screen Shot 2015-09-29 at 10.27.54 pm.png

 

3. Clicking on Delete button will delete the content.

What do we do at the backend?

Screen Shot 2015-09-30 at 11.03.22 am.png

 

 

 

 

3. Bulk Apply Tags:

       User can update the content by applying tags. This features suggests related tags to the entered tag once you enter 3 letters in the tag area.

Steps followed to perform the same operation:

1. Select the content to be updated with tags.

2. Click on tags icon which would show:

Screen Shot 2015-09-29 at 10.33.49 pm.png

 

3. Once the tags to be applied on the content, click on 'Add Tags' button.

What do we do at the backend?

Screen Shot 2015-09-30 at 11.04.24 am.png

 

 

 

4. Bulk Apply Categories:

     User can categorise content. This features displays categories available on the group.

Steps followed to perform the same operation:

1. Select the content to be updated with tags.

2. Click on categories icon which would show:

Screen Shot 2015-09-29 at 10.36.55 pm.png

 

3. Content will be updated with selected categories once 'Update Categories' button clicked.

What do we do at the backend?

Screen Shot 2015-09-30 at 11.05.37 am.png

 

 

 

 

 

This is the service side code snippet which does all magic (updating):

Screen Shot 2015-09-30 at 11.07.15 am.png

 

 

Access Levels:

   SuperAdmins: Super-admins have access to all the content of all the groups.

   Group Admins: Group Admins have access to all content to the group he owns.

   Normal User: Normal user will see only his content.

   Group Admins/Normal Users can move the content to the groups which they have access to.  

 

 

Logger:

  We have added logger to log all the operations which includes: operation done, group name, successIds, failureIds, User Id, Time etc

 

 

 

Code structure:

Screen Shot 2015-10-01 at 4.20.51 pm.png

 

                  As you can see in above image, the app is divided into various features. ContentManager is the parent class and other classes define the various features. We have added helper classes which take care of validation or views. JiveWrapper is the wrapper written over jive core apis, which helps to use them in customised manner.

 

This is how we have designed the app.

Please find the code under : siddharthadeshpande89/jive-content-manager · GitHub

This is an open source version licensed under AGPL.

Introduction

screenshot_1.png

Social media is an important part of our digital lives and there is hardly anyone who hasn't used Twitter; there's even smaller percentage of companies that don't leverage this platform to engage with their customers. It's a great source of 140-character news and updates and it's also a great feed to add to your Jive Cloud instance. In this blog, I'll be writing about how you can create a Jive-hosted Custom View Tile with Configuration—and that means no middleware required!

 

This post and package was created/inspired by the questions posted in Twitter feed in the Cloud.

 

The Goal

While the GitHub package is included in this post and it's configurable to display any stream you wish, this pattern is to demonstrate how to create a Jive-hosted Custom View Tile and possibly adapt it for other feeds (e.g. Facebook, Google+, WordPress, etcetera).

 

Tools Used

 

Files Modified

  • /tiles/[Tile Name]/definition.json
  • /tiles/[Tile Name]/public/view.html
  • /tiles/[Tile Name]/public/configuration.html
  • /tiles/[Tile Name]/public/javascripts/configuration.js
  • /tiles/[Tile Name]/public/javascripts/view.js
  • /jiveclientconfiguration.json (optional)
  • /tiles/[Tile Name]/public/stylesheets/main.css (optional)

 

Get the Files on GitHub

jivesoftware/twitter-widget-tile · GitHub

 


 

Build a Twitter Tile w/o Middleware using Jive's Custom View Tile

 

Create The Foundation: a Jive-SDK Example

To begin building our add-on, we're going to be requesting help from the mighty Jive-SDK to create an example for us that will take care of most of the nuances like tokens, unique ID's, and file structure. We'll be using this example project to modify and build our tile. In order to get started, first make sure you have the Jive-SDK installed on your machine by following Getting Started > Installing the Jive Node SDK. After that, create a folder for your project, open up terminal/command prompt, navigate into that folder and run the following commands:

jive-sdk create tile-app-internal --name="twitter-widget-tile"
npm update

 


 

Making a Twitter Widget

twitter widget configurator.pngTwitter offers a Widget Configurator that will allow you to customize their widget and hands you code that you can paste in to your tile. Their widget allows you to control some aspects of the view external to the configurator by adding embedded timeline attributes to the anchor tag that is provided. The options we included in our tile reflects the look of our Jive instance, yours can/will vary, but the recommended height to be set within the configurator is 300px. We will modify that later in our code and user selected configuration window, but it is a good place to start.

 


 

Configuring the Add-on

We will be modifying some of the default configuration from our sample app and adding some features and setting page types that the Tile will need in order to function correctly and be added to anywhere we'd like. We want the Tile to have access to the Jive V3 API's, JQuery 1.11, and the Tile API features—as well as allow this to be installed and view in a PLACE, USER, and NEWS feed (we are choosing to not display on mobile). Another change is that we are setting the icon images for the tile installation to be at the root of the tile directory and adding the image assets to the root of the /tiles/[Tile Name]/ directory.

 

Modified lines in /tiles/[Tile Name]/definition.json:

"displayName" : "Twitter Widget Tile",
"name" : "twitter-widget-tile",
"description" : "Configurable Twitter feed widget tile",
"pageTypes" : [ "PLACE", "USER", "NEWS" ],
"icons": {
        "16": "extension-16.png",
        "48": "extension-48.png",
        "128": "extension-128.png"
},
"config": "/twitter-widget-tile/configuration.html",
"view": "/twitter-widget-tile/view.html?features=jq-1.11,core-v3,tile"

 

You can add/change the description of the add-on to suit your needs in /jiveclientconfiguration.json (optional).

 


 

The Configuration Window

The configuration window will consist of two user configured inputs—a twitter widget ID string (the numerical ID will exceed the floating point precision of JavaScript, so it must be set to string) and a number for the height. Upon submit the data is stored in the config["data"] object, which will later be accessed by the view.

 

Editing the Configuration HTML

We provide instructions in the UI of the configuration window to help enable the end user successfully fill out the form. A required Twitter Widget ID (from the Widget Configurator) and a self-validating number input for height are the only elements needed in the form.

 

/tiles/[Tile Name]/public/configuration.html

<h2>Configuration</h2>
<p>Create and get data-widget-id from <a href="https://twitter.com/settings/widgets/" target="_blank">here</a>.
</p>
<p>
    Twitter Widget ID:
    <input class="j-text" id="twitterID" type="text" name="twitterID"  required />
</p>
<p>
    Height of Tweet tile (px):
    <input class="j-text" id="tileHeight" type="number" name="tileHeight"  max="500" min="120" value="300" step="1" />
</p>

 

Editing the Configuration JavaScript

Since we have access to the config{} object, we can store name value pairs in our config["data"] object for the view to read. We also are storing this data if a user were to go back to the configuration screen after it's first configured. The object is kept within the Jive service.

 

/tiles/[Tile Name]/public/javascripts/configuration.js

// config will initially be empty, this defaults to load the @jivedev twitter feed
// the data-widget-id must be a string since the length exceeds JS' floating point precision
var json = $.isEmptyObject(config["data"]) ? { "id": "643568438426734592", "height" : 300 } : config["data"];
console.log(json);
// populate the input dialog with config data
$("#twitterID").val( json["id"]);
$("#tileHeight").val( json["height"]);
// store the updated values into config on button click
$("#btn_submit").click( function() {
    config["data"] = { 
    "id" : $("#twitterID").val(),
    "height" : $("#tileHeight").val()
}
// send config to service
jive.tile.close(config, {} );

 


 

The View Window

Most of the work for the view is provided by the code from the Twitter Widget Configurator; along with a few modifications.

 

Editing the View HTML

We can paste the anchor tag from the tool into the <body> of our HTML file and remove the data-widget-id property from it—this will be added later using JQuery. We are also adding some customization to our widget through the data-chrome property and an ID out of personal preference.

 

/tiles/[Tile Name]/public/view.html

<a class="twitter-timeline" id="tweets" data-dnt="true" href="https://twitter.com/jivedev" data-chrome="nofooter" width="300">Tweets by @jivedev</a>

 

Editing the View JavaScript

We add the a data-widget-id and height properties that were received from the configuration window. After doing so, we call the Twitter widget script provided from the configurator (with a few personal tweaks) and use the asynchronous ready() method to bind the rendered event, which will trigger the gadgets.window.adjustHeight() method for our little tile.

 

/tiles/[Tile Name/public/javascripts/view.js

$(function(){
    $("#tweets").attr({'data-widget-id' : config["id"], 'height' : config["height"]});
        
    //Calls the twitter widget.js and creates the elements for feed list
    window.twttr = (function(d, s, id) {
        var js, fjs = d.getElementsByTagName(s)[0],
            t = window.twttr || {};
        if (d.getElementById(id)) return t;
        js = d.createElement(s);
        js.id = id;
        js.src = "https://platform.twitter.com/widgets.js";
        fjs.parentNode.insertBefore(js, fjs);
            
        t._e = [];
        t.ready = function(f) {
            t._e.push(f);
        };
    
        return t;
    }(document, "script", "twitter-wjs"));
    
    twttr.ready(function (twttr) {
        twttr.events.bind('rendered', function(){
            gadgets.window.adjustHeight();
        });
    });
});

 


 

Build Tile With Jive-SDK

Use the command below in terminal/command line to build and package the Jive hosted tile (no middleware) that you can then add to your Jive Instance.

jive-sdk build add-on --apphosting="jive"

 


 

Hot Tips

  • For testing JavaScript iterations (HTML files will be hosted by Jive), check out Ngrok: Warp Speed for Your Integration Iterations and use the jive-sdk create tile-app-external command in your command line to create a package that will let you test out the configuration and view scripts

  • The Twitter Embedded Timeline can be dynamically inserted by using the twitter.widget.createTimeline function
  • You can load multiple feeds/widgets in one tile

 


 

What's Next?

It's almost October, and you know what that means ... time for JiveWorld!  But this time, it's a little different.  Due to the fact that JiveWorld was moved to March 2016, there is now a hole in our hearts for a chance to interact, network and share amazing customer stories in 2015.

2.png?a=367223

Thanks to the efforts of the Bay Area User Group ... a team has put together an event they are calling UnJiveWorld 2015 to help fill this gap until JiveWorld16 in March in Las Vegas!

See: Save the date: Bay Area UnJiveWorld Conference October 15, 2015 in Santa Clara, CA  for more details on how to RSVP.

 

Developer Agenda

Our developer relations team is trying to help add some developer content to UnJiveWorld 2015, but before we can do that, we need to know who is interested in attending and what you would like to discuss.

  • Would you like formal presentations from Jive?
    • If so, any specific topics?
  • How about customer speakers and successes? 
  • or, we can just do an all day hack session with some Jive experts onsite?

Have a speaking idea that you'd like to submit? 
click here for more details

 

Please tell us if you are planning on attending and how we can make this time most valuable for attendees.  We will do our best to accommodate!

 

Join Us for a Day of Jive Development / Hacking

profile-image-display.jspa?imageID=20541&size=200 profile-image-display.jspa?imageID=28476&size=200

Both Ryan Rutan (Director of Developer Evangelism & Partner Innovation) & Rashed Talukder (Developer Evangelist) will be in attendance at UnJiveWorld 2015.

 

Based on your feedback/registration, we may bring more Jive engineers to answer your questions and make sure this event doesn't disappoint!

 

I'm excited for the opportunity to try out some of the new tech we'll be showcasing in the Announcing a Tri-Hackathon at JiveWorld16 Developer Conference w/Limited Edition T-Shirt, as well as a chance to meet developers face-to-face.

 

 

Introduction

There's really no other way to describe what ngrok did for my Simple Stream App Integration development cycles other than amazing. It's so good that we're writing about it twice for those of us that missed it the first time! Instead of removing an add-on, reinstalling to the Jive instance, then installing the integration to the group and creating a new activity every time I made any little code change, I can just make the edits on my local machine and host them externally. Setting everything up is incredibly easy and allows me to hit refresh on my browser while viewing the external object/app and pulls the files from my \apps\[app name]\ directory.

 

With Nitrous.io no longer having a free option, this is the perfect (and IMO better) replacement tool to develop/iterate with on your Jive instance.

 

Background

Ngrok is a small client application that punches a hole in your firewall and securely routes data to your local machine. Once the service is running, you're given a unique URL that can tunnel through HTTP and HTTPS. Ngrok also has a feature for authentication for access protection and you can inspect all the traffic going through the tunnels (http://localhost:4040). The best parts is that it's FREE and incredibly simple to have up and running. Each time you run ngrok, you'll be given a new subdomain which you'll have to change in your add-on—unless you are on a paid account—but will usually retain the endpoint if you don't close that window or close your ngrok session.

 

File Modified

  • \jiveclientconfiguration.json

 


 

Installing and Running Ngrok

Installation

Installation is relatively very simple. You need to download ngrok, unzip it to a location of your choosing, then sign up for an ngrok account. After logging in, Dashboard > Main > [Copy] "Your Tunnel Authtoken," then we're going to open terminal/command line, go into the folding containing ngrok and enter the following:

Mac/Linux:
./ngrok authtoken [paste your authtoken]

Windows:
ngrok authoken [paste your authtoken]

 


 

Starting Ngrok

Loading up an ngrok in terminal/command line is incredibly simple. You just need to set which port you'll be using for your app, which will be port 8090.

Mac/Linux:
./ngrok http 8090

Windows:
ngrok http 8090

Screen Shot 2015-09-14 at 10.47.39 AM.png

Be sure to copy your secure endpoint (https://xxxxxxxx.ngrok.io), we'll be needing that in the next steps.

 


 

Configuring Your Simple Stream App with Ngrok

Configuring your add-on to use ngrok and thus your local machine to host the app externally is incredibly simple and only requires modification to the \jiveclientconfiguration.json file.

 

Configuration

Modify the following lines in your jiveclientconfiguration.json file:

"clientUrl": "https://[your unique ngrok subdomain].ngrok.io",
"clientUrlExcludesPort": true,
"port": "8090",
"suppressAddonRegistration" : true,

 


 

Building Your Externally Hosted App with Jive SDK

Go to the root directory of your integration in terminal/command line and run jive-sdk build --apphosting="self".

After the add-on is built and zipped together, install it into your Jive instance, install it to a group and push an activity to be created. Then when you go to view the external activity, you will see the app files get pulled from your local machine and requests/status' displaced in your ngrok terminal window.  At this point, you can do all your app development iteration from your local machine without having to do additional add-on deploys to Jive.  If JS/CSS assets appear to get cached, you should be able to simply stop and start your local node service, which takes about 1-2 seconds, and you should see the assets get refreshed!

In the event your app.xml changes, you will need to uninstall/reinstall the add-on for those changes to take affect.  It is recommended, that you lock in your app.xml contributions and features prior to iterating on your app.  See:  App Action Contribution Reference

 


 

Switching Back to Jive App Hosting with Jive SDK

Once you have refined your application and are ready to bundle the resources back into your Jive add-on, all you need to do is execute the following command to instruct the Jive SDK to bundle the app resources into the /public directory in the add-on:

jive-sdk build --apphosting="jive"

 

Simply uninstall / reinstall the add-on one more time, and you should be good to go!

Note:  In most cases, it is not necessary to change the clientUrl within jiveclientconfiguration.json back to http:  or http://localhost.

 


 

What's Next?

Introduction

Screen Shot 2015-09-08 at 4.44.46 PM.png

Wrapping up the series, we are taking our Simple Stream Integration (SSI) to the next level and really pushing the bounds of what we can do with a simple activity in Jive before finding ourselves needing middleware. We are building on to our App that we created in Episode 2 and adding two-way communication between Jive and StatusPage.io. In many ways, we are walking away from the limitations of the dataset that first created the activity in Jive from the subscribed StatusPage webhook payload. Within the external object's view, we have an app that we can send POST and GET requests to StatusPage to retrieve incidents related to the component ID from when the activity was generated and also add new incidents—without needing to leave Jive. To make sure the requests and tokens are kept secure and only select Jive Groups can see this additional feature, we'll be utilizing the Jive Connects service.

 

 

The Goal

Imagine one of your clusters goes down and you get a activity in Jive from StatusPage.io that you and your team can collaborate on the activity, view the incidents generated by your team or automated services, and add/delete/update incidents as they come in—all from within Jive and without needing to spend time switching services, websites or tools. Ultimately, this saves time, money and confusion while keeping your information and credentials secure while proving a rich and easy to use UI. That's a lot to ask, but that's exactly what we'll be building here and you can do the same with your own custom simple stream integration/app within just a few hours without middleware.

 

Tools Used

 

Files Modified

  • /apps/[your app name]/public/app.xml
  • /apps/[your app name]/public/ext-object.html
  • /apps/[your app name]/public/javascripts/main.js
  • /apps/[your app name]/public/stylesheets/main.css
  • /extension_src/public/configuration.html
  • /extension_src/public/style.css
  • /extension_src/public/logo.png (added logo for activity stream configuration page)

 

Get the Files on GitHub

The source code for this project is available on GitHub.

 

You can use the Jive SDK to create your own simple stream integration that picks up after

Dev Tool: Build an App w/ the Simple Stream Integration Builder (2 of 3)

 

  • Install the Jive Node SDK
  • Then use the following command:
    • jive-sdk create simple-stream --name="my-stream"
      • You can replace my-stream with a value of your choosing.

 

Now you should be ready to follow this walk-through. =)

 


 

Creating An SSI App with 2-Way Communication For StatusPage Using Jive Connects

 

Setting Up Jive Connects

Jive Connects is a broker for proxying requests to a remote service. Since it is set up on the server side, it can add authentication headers from anonymous, basic, to OAuth 2.0 without exposing this information to anyone but the intended service. More importantly, it is needed because of browser access restrictions for network access outside of the application from which it was loaded. By using Jive Connects, we can use its HTTP verb methods (GET, POST, HEAD, PUT, DELETE) to pull and push data from other sources into our App. Permissions to the installation of the add-on containing the Jive Connects service can also be set up; however, once added to the group and authorized, all users who are members of the group in which the add-on is installed can view/use the add-on and that Jive Connects service.

 

Walk-Through Video

 

Admin-side Setup for Jive Connects

Screen Shot 2015-09-08 at 6.44.23 AM.png

  1. To get the admin set up, we start from our Admin Console (requires admin privileges) by clicking our profile picture in the top navigation banner, "Manage" > "Admin Console"
  2. We need to add the service that will use the Jive Connects API in the Jive Admin Console. Click the "Add-ons" menu > "App Services" side menu > "Add New Service"
  3. Enter a Name of the service. We included the URL of our StatusPage instance to avoid confusion for which one this service belongs to.
    • Note: This name will be visible to end-users when they first use the app, so being descriptive is recommended.  StatusPage.io - [URL] - Incidents
  4. Authentication style can vary based on the external service's API requirements. Jive Connects supports Anonymous, API Key, Basic, OAuth 2.0.
    • Note:  Due to the way StatusPage's APIs are designed we are choosing Anonymous so everyone can share the API key
  5. Description is whatever you feel is appropriate for the service for anyone who will need to reference this service internally to understand what it connects.
  6. "Tags" is the identifier that your App can use to identify this specific Jive Connects service. Tag's take the form of URIs and must be unique and begin with "jive:service://".
    • Note: For our purposes, we are using "jive:service://statuspage.io/incidents.api?version=1" where version matches the StatusPage API version
  7. The "Service URL" will be the base URL for all requests to their API. Jive Connects let's us append to this URL but not prepend or modify from within our App.
    • Note:  Since the StatusPage API contains a unique ID for each Page instance as the base for all of their API calls, we included that in our service URL
      https://api.statuspage.io/v1/pages/[Your StatusPage.io Page ID]
  8. While Jive Connects is capable of storing multiple keys per user, we felt that this use-case was best served as multiple user's sharing a single API key.  To do this, we are hard-coding the Authorization token into the Jive Connects service, such that it is never transmitted to the browser.  Per StatusPage documentation, we could do this by always passing the key as a request parameter or header.  We chose header to keep it hidden.  To keep it safe.
    • Note:  Click the "Add a new HTTP Header" and enter the header parameter per the StatusPage documentation:  Authorization:  OAuth [APIKEY]
    • Note: To get our API key from StatusPage and you can find instructions on how to get that from here.

Since this app is being installed as an add-on, the fields below such as Groups/Users with Access to this Service are no longer relevant.

When opening the app for the first time, a authorized user will be presented with a verification screen in order to enable the Jive Connects service to this App. This only needs to be done once by one user to enable it for the entire group.

 

Enable App to Access Jive Connects

Now that we have the Jive Connects service created and configured, we can use the tag created earlier and tie it to an alias to be used by our app. The alias can be any name you want it to be and your app will reference that name in order to access the Jive Connects Service. The title will be displayed at the first initialization of the service when it is first called on the Jive Connects authorization screen (this will pop up in the app load). The content between the tags is your Jive Connects service tag that you will paste in between. We need to open the /apps/[your app name]/public/app.xml file and the following anywhere before the closing </ModulePrefs>:

<!-- Begin Jive Connects feature -->
<Require feature="jive-connects-v1">
  <Param name="alias:StatusPageIncidents|title:Read StatusPage Incidents Service">jive:service://statuspage.io/incidents_api?version=1</Param>
</Require>
<!-- End Jive Connects feature -->

 


 

Customizing the App Look and Feel with HTML and CSS

Screen Shot 2015-09-08 at 5.00.58 PM.png

For purposes of this blog and personal preferences, we aren't going to go into details of how you should make your App look. But instead, I'll tell you what I did, why I chose it and you can download the source files from GitHub to see the code.

 

The Configuration Window

We are going to backtrack for a second and edit the configuration screen for our integration that we get our endpoint URL to look a little less generic and bit more StatusPage while spending very little time on it. We need to edit the /extension_src/public/configuration.html and styles.css file to get the look we want. I also went ahead and added the StatusPage.io logo to make it clearer on which integration is being installed and/or configured.

 

Customizing the App View

To start, we edit the /apps/[Your App Name]/public/ext-object.html and stylesheets/main.css files. For this example, I wanted to give the look and feel of StatusPage.io in our integration so that the end user would feel just as comfortable and transition into operating on the StatusPage incident within Jive as they would within StatusPage; the whole process should feel seamless.

 


 

Using the StatusPage.io API within the Jive External Object App

In this example, we will be taking the StatusPage.io v1 Components and Incident's API and adding it to our App to be able to get the current status of the component related to our activity, read incidents related to the component that was posted after the date the activity was created within Jive. In addition to reading it, we will add the ability to push a realtime incident update and delete an existing incident from within the App view—without ever leaving Jive. The App can be expanded even further to add the ability to update an incident with minor tweaks. As stated previously, all communication between the App and StatusPage.io is proxied through the Jive Connects service.

 

Here is a break down of the construction of a Jive Connects POST request in /apps/[your app name]/public/javascripts/main.js:

function() {
     osapi.jive.connects.post({ // This is the POST method for Jive Connects, can be swapped to GET, DELETE, PUT, or HEAD and follows same formatting 
          alias : '[The Alias You Assigned in Your app.xml File]', // Since one App can have more than one service, each request needs an alias
          href : '/[Rest of the Endpoint of the API Appended to the Service URL]' // Varies based on which part of the external service API you are calling
     }).execute(function(response) {
          if (response.error) {
               // Handle response.error content here
          }
          else {
               // Do something with response.content if there's a payload
               // or response.headers
               // or response.status
     }
}

 

Viewing the Current Component Status

We will be calling the StatusPage.io Component API using Jive Connects GET method to make the HTTP request. On a success, the payload we get back from StatusPage's Components endpoint can be viewed in response.content and we go through that array of objects to find the matching component ID to our activity, once that's done, we call the renderStatus() method with the name and current status to be displayed. We are handling any errors by displaying the response.error in the appropriate div.

loadStatus : function() {
  var appObj = this;
  osapi.jive.connects.get({
        alias : 'StatusPageIncidents',
        href : '/components.json'
    }).execute(function(response) {
  if (response.error) {
  $('#component_status').html("Received the following error: " + JSON.stringify(response.error, null, '\t'));
  gadgets.window.adjustHeight();
  }
  else {
  response.content.map(function(obj){
  if (obj.id == app.context.body.component_update.component_id){
  app.renderStatus(obj.name, obj.status);
  }
  })
  }
  })
  },

 

The process of loading and viewing the StatusPage.io Incidents API is similar to the way we received the components JSON—by using the Jive Connects get() method and pointing the request to the /incidents.json path. We are using the JavaScript map() method to go through the response.content's array of objects in order find when each incident is referring to the activity's component and then eliminating any incidents that were created BEFORE the activity was generated. Lastly, we filter out any empty objects from the array before we call our own renderIncidents() method to create the DIV's to display each of the incidents.

  var appObj = this;
  osapi.jive.connects.get({
        alias : 'StatusPageIncidents',
        href : '/incidents.json'
    }).execute(function(response) {
  if (response.error) {
  $('#incidents').html("Received the following error: " + JSON.stringify(response.error, null, '\t'));
  gadgets.window.adjustHeight();
  }
  else {
       //
  //Please see our Git repo for the full source code
     //
  app.renderIncidents(reData);
  }
    })

 

Deleting a StatusPage.io Incident through Jive Connects

We are just doing a rinse and repeat of the Jive Connects calls and switching the verb that we use to perform our task. To delete a incident, we just need to use the delete() method in Jive Connects and pass the incident ID in the request URL. After it completes, we reload the incidents by calling our custom loadIncidents() method.

  var appObj = this;
  osapi.jive.connects.delete({
  alias : 'StatusPageIncidents',
  href : '/incidents/'+incident_id+'.json'
  }).execute(function(response){
  if (response.error){
  $('#incidents').html("Received the following error: " + JSON.stringify(response.error, null, '\t'));
  gadgets.window.adjustHeight();
  }
  else {
  app.loadIncidents();
  }
  })

 

Adding a StatusPage.io Incident through Jive Connects

NewIncident.png

In order to create a new incident, we set up a form in the /apps/[your app name]/public/ext-object.html file that contains the necessary fields (incident name, incidents status, message). We are not using the twitter option in our example and the component we will be appending this incident to is going to be the same component as the activity's. Upon submitting the form, we call our addIncidents() method, which uses the Jive Connects' POST verb to add the incident to StatusPage.io. We create a string with all of the parameters that we need to send over to StatusPage.io—and include the component ID—all to the formatting required by StatusPage's API. In this POST request, we are going to include a header value { 'Content-Type' : "application/x-www-form-urlencoded" } and a body that contains the string we put together from the form and place it in encodeURI() so that StatusPage's service can read it according to their requirements. After a successful request, we call our loadIncidents() to view the newly added incident.

 

 

  // See the GIT repo for source code

  osapi.jive.connects.post({
  alias : 'StatusPageIncidents',
  href : '/incidents.json',
  headers : {'Content-Type' : "application/x-www-form-urlencoded"},
  body : encodeURI(message)
    }).execute(function(response) {
  if (response.error) {
  $('#incidents').html("Received the following error: " + JSON.stringify(response.error, null, '\t'));
  gadgets.window.adjustHeight();
  }
  else {
  app.loadIncidents();
  app.incidentForm();
  }
    })

 


 

Hot Tips

  • You may get an error when installing the add-on about an extra .DS_Store file if you've been browsing around your directory with Finder on Mac. If you go to the root of your integration folder in terminal, type in the code below to remove all the .DS_Store files from the project; build your project again with Jive-SDK
    find . -name ".DS_Store" -type f -delete
    
  • You can have multiple Jive Connects services' running in one app. This is useful in cases where you may have two different external services that you are sending requests to/from
  • If you do not want to enter a object.url in your original xform.js file, or if you do not want to see the "Go to item" link in your activity tile, you can remove it with the "hideGoToItem" property in your activity.object. Read more about this and look at examples here ›

 


 

What's Next?

jw16-dev-trihackathon-logo-teal.png

With JiveWorld16 officially announced and the call for speakers in full swing, I wanted to take a moment to share with my fellow Jive developers some of the new ideas we are implementing at the JiveWorld16 Developer Conference.  Rest assured the staples of the developer conference intact, such as the open hackathon, Midnight Hack:30, our Hacker Lounge staffed with Jive experts and amazing deep-dive developer sessions.   But we wanted to change things up a bit to make things more fun and engaging, so we decided to change the format of the hackathon.

 

We call it a Tri-Hackathon (*pause for effect)

 

This hackathon format is designed to expand developer skills, knowledge and creativity across multiple critical hacker disciplines, including: Technology Trivia, Coding Skills and Video Games!

 

 

Technology Trivia

jw16-trihackathon-tag-n3rd.png

Our team is putting together an online quiz that will test various aspects of developer and hacker trivia.   How well versed are you on technology?  Now is the chance to find out!  Topics for the quiz will include: programming logic, terminology, technology history, puzzles and much more!  The developer(s) with the highest score(s) will win this leg of the hackathon.

 

Winners will receive bragging rights in the Developer Community and additional awards yet to be determined.  Stay tuned for updates!

 

Coding Skills

jw16-trihackathon-tag-h4ck.png

Building on last year's success, we will revamp our list of Challenges from JiveWold14 to align with the direction and new features in the Jive platform. Developers will be enabled to complete relatively quick challenges throughout the course of the conference.  Each completed challenge will earn points, and the developer(s) with the most points will win this leg of the hackathon.

 

Winners will receive bragging rights in the Developer Community and additional awards yet to be determined.  Stay tuned for updates!

 

Video Games

jw16-trihackathon-tag-pwn.png

Need time to decompress?  How about taking a break to get the creative juices flowing?  This year in the JiveWorld Hacker Lounger, we will have an arcade cabinet loaded with a large assortment of FREE play vintage arcade games.  Just before the conference, we will announce an official JiveWorld16 Tri-Hackathon video game.  The leaderboard will be wiped, and from there it's arcade rulez ... the highest score(s) win this leg of the hackathon.

 

Winners will receive bragging rights in the Developer Community and additional awards yet to be determined.  Stay tuned for updates!

 

... and dont forget about the JiveWorld16 Tri-Hackathon T-Shirt!

For developers that register before December 31st, we will reserve this limited-edition JiveWorld16 Tri-Hackathon T-Shirt and distribute it at JiveWorld16.  We will also have a limited number of various sized shirts generally available at the hackathon, but registering before December 31st reserves one in your size.

jw16-dev-trihackathon-shirt.jpg

 

 

Save $300 with Early-Bird Pricing Today!  Expires: October 31st

ARIA Resort & Casino, Las Vegas, NV

March 14-16, 2016

 

Register as a Developer

 

Need help making the case for the JiveWorld16 Developer Conference? Maybe we can help ...

 

For more details about the JiveWorld16 Developer Conference, click here.

developer-conference-gradient.png

 

Call for Speakers

  • Have you built a cool Jive integration?
  • Is that integration using the Jive add-on framework?
  • Are you willing to share some developer tips/tricks and lessons learned with fellow Jive developers?
  • Are you interested in getting a FREE pass to JiveWorld16 Developer Conference (includes all JiveWorld16 amenities)?

 

If you answered, Yes, to all of these questions then we strongly recommend that you take a moment to share your speaking idea with us.

 

Recommended Topics:

  • Integrations into external systems using the REST API, Apps, Tiles, External Storage and Mobile frameworks. (30-50 minutes worth of content)
  • Quick developer hacks using the new Simple Stream Integrations, Custom View Tiles or Custom HTML Tiles capabilities in the Jive platform (15-20 minutes of content)
    • Note:  It's not too late to try out these new technologies and submit a topic for consideration.  Solutions must be functional by February 2016 (production deployment, optional) and POC capable by October 1st.
  • Building integrations with the Jive add-on framework in languages where there is currently no SDK or limited tooling, such as: Ruby, PHP, Python, Go, .NET, etc.. (20-40 minutes worth of content)
  • Development of Jive solutions using iPaaS platforms like Informatica, Boomi, Mulesoft and others. (20-40 minutes worth of content)

 

Deadline:  Monday, September 14, 2015

See the speaker submission form for more details.  

https://jiveworld.jivesoftware.com/speakers

 

Conference Details

Check out the Developers section on the JiveWorld16 website to learn more about our agenda, including:

  • JiveWorld16 Tri-Hackathon new - A new twist on the hackathon experience that is guaranteed to energize your inner hacker
  • Jive Developer Keynote - Kicking off JiveWorld16 Developer Conference off with another inspirational keynote!  See last years.
  • 12+ Jive Developer Sessions - Learn from expert Jive customers, partners and engineers on the latest capabilities in Jive and proven success stories.
  • Jive Developer Town Hallnew - Learn from product and engineering leadership about the future of the Jive platform

 

For more information, please see:

https://jiveworld.jivesoftware.com/developers/ or Register Today and save $300 with the Early Bird Discount through October 31st!

This is step-by-step tutorial on how to use the Simple Stream Integration Builder to create a simple activity stream integration with StatusPage.io. This will enable you to get a one-way webhook-style activity stream from StatusPage.io, to a Jive group, without middleware in around 10 minutes! This tool is a first in a series of episodes we’ll be releasing that will enable you to save time developing for your Jive instance.

 

Screen Shot 2015-07-17 at 7.58.29 PM.png

 

Background

StatusPage.io provides "a web page specifically dedicated to communicating which parts of your site are/aren't working and the reasons behind it." Which according to StatusPage, helps "keep your customers informed when you're having an unplanned outage." But what about your own organization and letting groups that are affected know right away? Or creating a collaborative action request and getting the right people involved? With this Simple Stream Integration, we can take the power of StatusPage.io and bring it into Jive and add even more value for you, your team, and your organization.

Note: The Simple Stream Integration Builder can only be used with Jive Cloud and Jive 9+ (Jive 7 and 8 is not supported).

 

Quick Walk-Through Video

Watch the instructional video to help create your own StatusPage.io Simple Stream Integration using the Simple Stream Integration Builder:

 

StatusPage.io Jive Activity Stream Integration Steps:

  1. First, you will need to have a StatusPage account set up and webhooks enabled on their service.
  2. Head over to the Simple Stream Integration Builder page.
  3. Examine the StatusPage JSON payload schema and the Jive Stream JSON schema for how you want the activity stream constructed.
  4. Create the JavaScript transform function within “Step 1” of the Simple Stream Integration Builder.
    Sample transform function:
//Renaming each of the component ID's with relevant names
//and adding an image for each of the relevant objects created
var component = {};
switch(body.component_update.component_id){
  case "xyk3yzfdk9kl":
  component = {
      'name': "Marketing Services",
      'img': "https://raw.githubusercontent.com/jivesoftware/jive-statuspage-addon/master/resources/images/marketing_services.png"
  }
  break;
  case "f0smn2s09lv4":
  component = {
      'name': "Cloud Data Server",
      'img': "https://raw.githubusercontent.com/jivesoftware/jive-statuspage-addon/master/resources/images/cloud_data_server.png"
  }
  break;
  default:
  component = {
      'name': "Component with ID: " + body.component_update.component_id,
      'img': "http://bit.ly/1wYwajm"
  }
}

//Just formatting the output to look better in the description
var desc = {
  'operational':  "Operational",
  'degraded_performance': "Degraded Performance",
  'partial_outage': "Partial Outage",
  'major_outage': "Major Outage!"
}

// Build activity object.
var activityInfo = { actor: {}, object:{} };

// Optional URL for this activity. Remove if n/a.
activityInfo.object.url = "https://jivesoftware3.statuspage.io";

// Required URL to the image for this activity.
activityInfo.object.image = component.img;

// Required title of the activity.
activityInfo.object.title = component.name;

// Optional HTML description of activity. Remove if n/a.
activityInfo.object.description = "New Status: " + desc[body.component_update.new_status];

callback({ "activity" : activityInfo });

 

  1. Copy and paste a sample JSON payload from StatusPage into “Step 2” of the Simple Stream Integration Builder:
{
  "meta":{
      "unsubscribe":"http://statustest.flyingkleinbrothers.com:5000/?unsubscribe=j0vqr9kl3513",
      "documentation":"http://doers.statuspage.io/customer-notifications/webhooks/"
  },
  "organization":{
      "id": "j2mfxwj97wnj",
      "status_indicator": "major",
      "status_description": "Partial System Outage"
  },
  "component_update":{
      "created_at":"2013-05-29T21:32:28Z",
      "new_status":"operational",
      "old_status":"major_outage",
      "id":"k7730b5v92bv",
      "component_id":"rb5wq1dczvbm"
  }
}

 

  1. Click the “Run Transform” button and be sure that the “Transform Function” and “Output Validation” tests are both error free under “Step 3.” If the checks fail, it will give you an explanation for the error.
  2. Fill out the rest of the activity stream information such as title, description and add an icon for your activity stream in “Step 4.”
  3. Next, go to your Jive instance’s Add-on manager (Profile Picture > Add-Ons) and upload the add-on.
  4. After uploading the add-on, we need to go to the Jive group settings and add the activity stream integration to it.
  5. Copy the webhook endpoint URL that’s given to you in the integration configuration screen.
  6. Go to the StatusPage notification page and subscribe the endpoint URL that was copied, to StatusPage webhook.
  7. Fin. That’s it! Give it a whirl and watch the status updates stream in.

 

Repo on GitHub:

https://github.com/jivesoftware/jive-statuspage-addon

 

Hot Tips

  • You can add extra JS code to make the stream more powerful. For this example, we take the component ID’s from StatusPage and are giving them their appropriate known names.
  • Filter out/in content based on relevance to the group.
  • Use the external objects to make the activity actionable and invite others to collaborate.
  • If you update the extract and update the files, be sure you zip from within the root folder.

 

What's Next?

Ready to take your activity stream integration to the next level? Add an App by checking out the second episode of this trilogy.

Introduction

Continuing on our journey of developing quickly and easily with the Simple Stream Integration Builder, we're going to be diving a little deeper from the first guide in this trilogy. In this episode, we'll be taking the StatusPage.io Simple Stream Integration Add-on that we created earlier and adding a Jive App. The benefit of having a App is that we can now take this data we're getting from our external source and add our own custom HTML, CSS, and JavaScript to create a better presentation and add some simple business logic—all without the need for middleware. So what does that mean for you? Well, other than just making the app have a richer look that is well matched to your theme or create a better looking personalized experience for the individual user, you can add custom JavaScript to create actions within the app itself and make calls to other API's—including making Jive's REST API calls. You can read about Jive Apps and their features, either before or after diving into this guide to find out more.

 

The Goal

What we're going to do here is create a Jive App to add to our Simple Stream Integration that we created in Episode 1 in under 30 minutes. Our tools will be to use the Simple Stream Integration Builder and the latest node Jive-SDK . The External Object's app view will include all of the data that is available to you from this app, and you can think of creative ways that you'd like to display your StatusPage.io webhook activity.

 

Screen Shot 2015-08-04 at 12.55.09 AM.png

 

Files Used

  • \extension-src\data\xform.js
  • \apps\ext-object\definition.json

 

Quick Walk-Through Video

Watch this instructional video to help walk you through creating your own StatusPage.io Simple Stream Integration App:

 

Steps for Simple Activity Stream Integration + App

This guide assumes you have already gone through the first of this three part series—if you haven't yet done that, please start there. This guide also assumes you have the Jive-SDK installed.

  1. Use terminal (Mac/Linux) or Command Prompt (Windows) to get to where you'd like this app to exist locally on your machine, and create a new directory and place your terminal into that directory:
    mkdir [YourDirectoryName]
    cd [YourDirectoryName]
                   

     

  2. Locate the zip file that you downloaded from the Simple Stream Integration Builder after you completed the first guide. Place that zip into the folder you just created.
    NOTE: Do not use extracted files that you re-zipped. You must use the original zip file that was outputted from the Builder.
  3. Be sure you have the latest version of the Jive-SDK (version 1.201 and above):
    npm update jive-sdk -g
                   

     

  4. Unpack the zip file using the Jive-SDK.
    jive-sdk unpack [zipfile].zip
                   

     

  5. Create an App out of this freshly unpacked zip and pick a name for the app (optional). This is the name that will show up in your add-on list. If you omit this attribute, then it will auto-populate the name from the name of the zip file.
    jive-sdk create app-ext-object --name="StatusPage.io Activity App"
                   

     

  6. Locate the Simple Stream Integration's transform file in \extension-src\data\xform.js and open it in your editor. We need to add a new object called "jive" within the activityInfo object. Your activityInfo object initialization line should look like the following:
    var activityInfo = {actor:{},object:{},jive:{}};
                   

     

  7. Continuing our work on the xform.js file, we need to take the UUID for the app from \apps\ext-object\defintion.json. We're going to be adding some code to push the contents of the body from the Simple Stream Integration to the App. You can place this code anywhere in the function BEFORE we call the callback function. Since the App exists in it's own iFrame in the external object view on Jive, this is how we send the object over to the app and it will display in the view we are defining as "ext-object" (the view displayed by the app is set in \apps\ext-object\public\app.xml). You can see other examples here.
    activityInfo.jive.app = {
      'appUUID': "[YOUR APP's UNIQUE UUID FROM \apps\ext-object\definition.json]",
      'view': "ext-object",
      'context': {
        'timestamp': new Date().getTime(),
        'body': body,
        'headers': headers,
        'options': options,
        'resources': {
            'components': component,
            'descriptions': desc
        }
      }
    }
                   

     

  8. It's time to package up and build our new app add-on. Since all the assets for this app will be served by Jive without middleware, we can set apphosting to "jive":
    jive-sdk build --apphosting="jive"
                   

     

  9. Add your add-on to your instance and then to the activity stream for your group by following the instructions in Getting Started > Deploying a Jive Node SDK Project as an Add-On.
  10. Copy the webhook endpoint URL that’s given to you in the integration configuration screen.
  11. Go to the StatusPage notification page and subscribe the endpoint URL that was copied, to StatusPage webhook.
  12. Change the status of one of your StatusPage components to see the new activity in Jive.
  13. Click the activity title to view the external object that's created and you will see the app load up with all of the JSON contents that you can use to refine your app view.

 

Screen Shot 2015-08-04 at 1.12.50 AM.png

 

Get it on GitHub

https://github.com/jivesoftware/jive-sdk/tree/master/jive-sdk-service/generator/examples/app-ext-object/apps/ext-object

 

Hot Tips

  • An app can have custom HTML, CSS, and JavaScript within it. You can customize the app view have the look and feel that you're looking for in order to display the content your group needs. You can see more on what you can do with apps here.
  • The app knows where it is in the instance and can be customized to display what it needs based on that.
  • The unpack feature is beta at the moment, it is recommended that it only be used on ZIP's created by the Simple Stream Integration Builder
  • On a Mac, a .DS_Store file is created by finder and can sometimes throw errors if packaged in the file. Try navigating through the folders through Terminal instead of finder to avoid this issue.

 

What's Next?

In the next part of this series, Dev Tool: Simple Stream App with Bi-Directional Communication (3 of 3), we take our example even further and show how to create a dynamic app—providing two-way communication to control StatusPage.io from within the Jive External Object!

Filter Blog

By date: By tag: