Skip navigation

Jive Developers

5 Posts authored by: pawans

Hello Jivers,

You all must have seen this document --> OAuth 2.0

It explain a way to use Oauth for REST api calls.

 

If you have registered an add-on using the Oauth flow (famous as Oauth Dance in Jive), you can utilise the jive-sdk on your add-on server to make rest api calls using oauth.

 

You already must have seen this in jive-sdk which can be used to make REST api calls using the tokens sent by jive

 

var jive = require('jive-sdk');
jive.context.persistence.findByID("community", env.jiveUrl).then(function (community) {
        jive.community.doRequest(
            community,
            {
                url: someApiUrl,
                "method": "GET"
            }
        ).then(
        ........
        )
    }


 

 

When we use oauth, by default the add-on has full access.

 

aaa.png

 

So basically if you call any REST apis using this add-on, you can do anything on your jive instance.

If this add-on is performing some actions based on some webhook events or some user actions which are sent from the app, its like saying this automated process can perform super admin tasks.

Obviously we don't want an automated process to have full access every time.

 

There is a simple way to reduce permissions of this add-on.

 

In the screenshot above I have an add-on called jivetest which has the super admin access.

Whenever you register an add-on, something like a service account is created in jive.

You won't be able to find this account in list of users, but you can find this new account under the User overrides under Permissions tabs.

 

Screen+Shot+2015-03-12+at+12.32.56+pm.png

 

You can see an option to edit permissions for this new account.

Here you can change the permissions to something limited which you need for the add-on.

 

Screen+Shot+2015-03-12+at+12.34.05+pm.png

 

People used to the new google apis might know the concept of scopes.

You have to set all individual scopes for a service account to call apis.

example :

 

https://www.googleapis.com/auth/userinfo.email

https://www.googleapis.com/auth/admin.directory.group

https://www.googleapis.com/auth/gmail.compose

https://www.googleapis.com/auth/gmail.readonly

In jive, this is one way to achieve some thing similar to achieve for add-on service accounts.

Hello Jivers,

Recently I have been using webhooks heavily for some of our integrations.

Its one awesome feature in the Jive platform which can have great use cases.

 

Basically the Jive webhook services notifies about some events happening in Jive. Simple.

It might be about a user created, group created, some action on a content, recently in 8c5, users following a content, group or user in some stream (email enabled or a simple stream).

 

I am using system webhooks to perform some actions on an external system which is integrated with Jive.

 

In our case, this external system is google group.

Let me give some context on this.

 

What we wanted to achieve?

 

  • When a new user account is created, a new email enabled stream should be auto generated for the account
  • When user creates a jive group, there should be a google group created with some configs
  • When user deletes jive group, corresponding google group should be disabled / archived.
  • When user follows a jive group in an email enabled stream, the user account should be added to corresponding google group
  • When user unfollows a jive group from an email enabled stream, the user account should be removed from corresponding google group, provided that he is not following that group in any other email enabled stream.
  • When user follows / unfollows a group in a stream with emails off, no action is taken
  • When user turns on emails for a stream from preferences, then for every jive group he is following in that stream, he should be added to corresponding google group.
  • When user turns off emails for a stream from preferences, then for every jive group he is following in that stream, he should be removed to corresponding google group, provided he is not following that group in any other email stream.


The reason we need this is our custom streamonce solution.

Default streamonce syncs content generated in google groups to jive. Beyond that comments generated on both jive and google are synced.

Our custom streamonce even handles discussions created in jive.

We have disabled default jive email notifications for discussions and instead emails are handled through google.

 

Now for above tasks, we have some rules /restrictions on how things should be setup.

  • A new google group created should have email id same as the url name of jive group. This helps streamonce service to auto map the groups and also our add-ons to detect google group name from jive group's url name.
  • Also our add-on assumes the url name and google group name are same. So its easy for us to process incoming webhook events and get google group details from jive data.
  • If a user wants to receive emails for discussions, he has to follow that group in emails enabled stream so that he is added as member to corresponding google mailing list to receive emails.
  • We even have an app to assist group admins to do this from jive.

 

Lets see how we are using webhooks to automate this.

 

The first part of creating a google group for a jive group is taken care by a new app I posted about yesterday.

Its the new flow we have for create group. Check more about that here --> Developer: Alternative to default create group ... | Jive Community

 

We use webhooks for all other tasks..

 

Event : User account created

When a new user account is created, we would like to have an email enabled stream called Email Watches ready for him so that he can use it to receive google emails.

We can even do some other setup before the user logs in.

 

In the webhook event json, jive sends the user id and also the resource url for the user so that we can directly call the api and add streams to the new user.

 

{
    "verb":"jive:user_account_created",
    "timestamp":"2014-11-17T11:07:23.983+0000",
    "jive":{
            "objectID":1000,
            "objectType":3
        },
    "object":{
            "id": "https://company.jiveon.com/api/core/v3/people/1000"
        }
    }
}































 

 

Event : Group created


We have an app to create google and jive group, ideally that same app could have handled the extra configs on these groups. But we wanted to make that app light weight, so we moved config part here.

When a new jive group is created, we configure the corresponding google group created by our app.

 

In the event below I get the api resource url for the jive group. Using this I can get the display name of the group which is also email id of the corresponding google group. Then I call google apis to configure the group.

 

{
    "verb":"jive:social_group_created",
    "timestamp":"2014-11-17T11:09:23.983+0000",
    "jive": {
        "objectID": 3727,
        "objectType" : 700
        },
        "object" : {
            "id" : "https://uat.my.company.com/api/core/v3/places/4000"
        }
    }
}































 

 

Event : Group deleted

When jive group is deleted, we disable the google group.

In this event, jive does not send a resource url as the group no more exists.

It send this internal jive id for the group.

We had an interesting solution here.

While creating google group, we add alias to it which is a unique key generated using the internal jive id.

So if my jive group displayName or google group name is jivetestgroup which has internal id as 1000, I add an alias called integration-group-1000 to the google group.

This is used only to get the google group name in the event when jive group is deleted and all i get is jive internal id.

We had an option to use jive DES as it reports the group name, but its not recommended to use for webhooks purpose.

 

{
    "timestamp":"2014-11-27T12:25:52.802+0000",
    "verb":"jive:social_group_deleted",
    "jive":{
        "objectID":3727,
        "objectType":700
        }
}
































 


Event : User starts following group in a stream

In 8c5 cloud release, Jive introduced stream event webhooks, which were of great help for us.

My next 3 examples are related to stream events.

 

Check the first example where I get a notification that user is following something.

The json sent here by jive is rich in content.

 

As seen below, here's what I get about the stream association event

  • user id of the user who triggered this event
  • objectId is the stream id of that user in which he is following something.
  • In properties
    • associatedObjectId is the id of object which the user is following in the stream. This can be place, content or person.
    • associatedObjectURI is the api resource uri of this object. This is particularly helpful in case of content or place where the object id might be different than the one used in api. There are still ways to get data from object id, but this url gives the object directly instead of using a search api on places on content.
    • receiveEmails tells if the stream in which this object was followed has emails on or off.
    • associatedObjectType is a number which tells type of object (example 700 is social group)

 

{
    verb: 'jive:stream_association_added',
    timestamp: '2015-01-14T23:15:15.312+0000',
    jive: {
            userID: 2014,
            objectID: 10,
            properties:
            {
                associatedObjectID: '1004',
                associatedObjectURI: "https://company.jiveon.com/api/core/v3/places/1529",
                receiveEmails: 'false',
                associatedObjectType: '700'
            },
        objectType: -891990144
        }
}































 

In our case when we get this event, if a user is following an object type of group in an email enabled stream, then using apis i will get the username of the user, display name of the group and then add this user to the google group (displayName@domain.com).

If user is following something in non email enabled stream, we ignore the event

 

 

Event : User stops following a group from a stream


In this case if a user stops following a group from an email enabled stream, we remove the user form corresponding google group, provided he is not following this group in any other email enabled stream.

This second part to verify if any other association is present between user and place is a simple api call.

Check the REST api documentation here --> Jive REST Rest API v3.10 → Place service

As admin I have to use run-as feature to call followingIn for the group under consideration (https://company.jiveon.com/api/core/v3/places/placeID/followingIn)

 

This will give me list of streams in which the user is following the group, with the stream email preferences too.

This helps me decide if I should be removing the user from google group or not.

 

{
    verb: 'jive:stream_association_removed',
    timestamp: '2015-01-14T23:14:56.859+0000',
    jive: {
            userID: 2014,
            objectID: 10,
            properties:
            {
                associatedObjectID: '1004',
                associatedObjectURI: "https://company.jiveon.com/api/core/v3/places/1529",
                receiveEmails: 'false',
                associatedObjectType: '700'
            },
            objectType: -891990144
        }
}































 

 

 

Event : User changes email preferences for a stream


Some day a user might decide to just turn off emails for all or one of his streams.

Even this preference change is sent by webhook stream event.

Whenever I change my email preferences for stream, Jive sends me user id who is owner of the stream and also detail about each stream with previous and current receive email status, though the change is only on one stream .


The stream which ha a change in preferences, I will pull all the group associations for that streams (as there might be people and content associations).

And then check where I need to add or remove user from a google group.

 

 

{
    verb: 'jive:stream_config_modified',
    timestamp: '2015-01-14T23:17:38.982+0000',
    jive: {
            userID:10004,
            objectID: 10,
            properties: {
                receiveEmails: 'false',
                previousReceiveEmails: 'false'
            },
            objectType: -891990144
        }
}
{
    verb: 'jive:stream_config_modified',
    timestamp: '2015-01-14T23:17:38.982+0000',
    jive: {
            userID: 1000,
            objectID: 11,
            properties: {
                receiveEmails: 'false',
                previousReceiveEmails: 'true'
            },
            objectType: -891990144
        }
}































 

 

Event : User's membership with a group removed


Our google group memberships have no connection with jive group memberships. Its more connected with email preferences and email streams.

So we never have to handle membership created event.

By default when user joins as member, he starts following that group in connection stream too, and jive does notify about it through webhooks.


Now when users group membership is revoked, all his stream associations with that group are also removed.

But in this case jive sends only one event "'jive:user_membership_removed". There is no association removed event.


But as we know all associations are removed as thats the way jive works, we simply get the group id from the event, call jive api to get the displayName and then call google group api to revoke user's membership for that group in google world.

{
    verb: 'jive:user_membership_removed',
    object : {
        id: 'https://company.jiveon.com/api/core/v3/people/2113'
    },
    timestamp: '2015-03-04T10:06:06.310+0000',
    jive : {
        containerType: 700,
        containerID: 1195,
        objectID:2113,
        objectType:3
    }
}




 

This is how we are using webhooks to improve the experience with our integrations.

Obviously there is much more you can do with this kind of data that you get from jive webhooks service.

Hello Jivers,

Recently we have been working on migrating from Jive 7.0.1 hosted instance to jive cloud.

Happy to say we are very very close to finally achieve this with all our customisations.

 

Before I talk about the particular solution here, I must say I had a fun ride working on Jive platform since more than 2 years now.

Working with this platform since jive 5.x, 6.x, 7.x and now cloud, things have changed a lot and improved.

Appreciate the effort jive folks have put in improving the platform which has personally helped me design and implement better solutions.

 

In 2013, we had a complex but successful integration between jive and google group with help of streamonce.

Well, not the default one, but a custom streamonce made for Thoughtworks.

 

In Jiveworld 2013, we had showcased this concept in customer showcase.

 

img.png

 

I will mention more about this in a separate post.

To work properly, streamonce service required some setup to be done for every group.

Some of them being, admin owning a google group and then manually map it to jive using streamonce app.

We wanted to avoid all the extra steps to achieve this integration and instead keep it simple for end user - just create a jive group.

 

So I designed a solution for this called google connector and we created a plugin for this.

 

This plugin use to create  / disable google groups and add/remove members from google group on some triggers from Jive.

And as this was a plugin, we could control the jive events triggering these actions on google and also block jive from performing some things if there was error from google.


We wanted to move to cloud to take advantage of the latest features and improvements announced.

The blocker was the plugins we had which are not supported in cloud.

We managed to convert most of the plugins into apps, all thanks to jive-sdk.

My move content app  was one of the first attempts where I could develop an app with simple jquery and jive-sdk. (Developer: Jive add-on to move content in bulk ... | Jive Community)

 

Here I would like to tell about one of these apps.

 

Why we wanted to control Jive's create group flow?

 

On our jive instance, we have connected every jive group with a google group.

We still have some old google groups with no connection to jive.

But new groups are all mapped.

 

Our plugin on hosted instance right now always creates a google group when a user is trying to create a jive group.

And streamonce auto mapper maps these groups so that it can handle the sync between the two worlds.

So for a end user, there's just a step of creating jive group. Beyond that everything is setup automatically.

 

Now this was very easy in hosted due to plugin.

It helped us handle some cases like - if google throws an error, user should not be able to create jive group.

Or if there is some conflict in google, user should know it.

And user should still be able to manage everything from one jive group instead of going to google groups console or streamonce app.

We have developed apps in jive which helps map jive membership with google. More on that soon

 

In cloud, there are no plugins and hence no way to customise the create group flow.

We had an option though to use Create Group event from jive webhooks service.

Basically when we receive an event that a jive group is created, our service creates a google group.

But what if there is a conflict in google group (due to some very old groups or some aliases our users have in their email accounts?)

What if the service goes down which is responsible for creating the google group?

 

For end user, he will see a success on jive side, and so he assumes everything is setup.

Only later they realise its not working as expected (sad user experience).

 

We wanted more control in create group flow.

The only option was to create a new app for this.

 

But then user will have two ways to create group.

So, I decided to hide the default option on cloud.

 

Disabling the default create group flow in jive cloud

 

Actually we cannot do this type of customization of hiding this feature.

But there is one easy way in this case. I changed the permissions for create group as shown in the image below.

Screen Shot 2015-02-19 at 7.00.40 PM.png

 

Wow, that was easy. So no create group option any more, anywhere on the site.

But I still want to ensure an end user has an ability to create a group

and he should be the owner

and google group created

and streamonce mapping should all be set....

 

Given the above permissions, what a user might go through now?

 

  1. Send a request to admin to create group with name, url name, description, group type, etc.
  2. The super admin receives the request,
  3. The super admin tries creating a google group first.
  4. If that goes well, he creates the jive group.
  5. All well? then he makes the requestor the owner of the new jive group, and removes himself (super admin) from the list of owners .
  6. Admin notifies user that groups are created and he can start using it.

And he can start adding people, start sharing stuff, etc..

 

 

Obviously this is not cool, user wants self service

 

Thats too much manual work and worst user experience in today's world.

But what if we automate the above process?

For end user it still the same experience, but all the above steps are taken care by a new app


First, thanks a lot to jive-sdk,  Jive #REST-api and Jive #connects-api


Now the solution.

 


The new Create group app


So going back to the above steps and how they look in our new app.

 

1. User sends a request, well thats in technical terms.

For end user, there is still a view like the default one where a group details can be entered and submitted.

The app auto-generates the group url the same way as it happens on default flow.

 

Here's now the difference in what a super admin and other users see in create menu.

Screen Shot 2015-03-07 at 4.31.37 PM.png

 

 

Here's the new app. its almost similar to default create group popup, but with minimal options.

 

 2 Actions   myThoughtWorks.png

 

 

2. Now we have configured our service endpoint in jive add-ons services console and used connects api to send request.

So through this the service received the request (the service is in the same node server where the app is deployed and has super admin privileges as it was registered with jive oauth)

 

3. This service now attempts to create a google group using google apis.

The group url of the jive group is used to create the email address.

 

var groupEmail = groupUrlName+emaildomain;
googleapis.admin('directory_v1').groups.insert({
  auth: jwt,
  resource: { email: groupEmail }
  }, function(err, data){
  });







 

 

4 On success, this service calls jive apis through jive-sdk and creates a group there too.

 

      var jive = require('jive-sdk')
      var data = {
            "type": "group",
            "displayName": displayName,
            "description": description
            "name": name,
            "groupType": groupType
        }
        var placeServiceUrl = "https://jive_url/api/core/v3/places"

        jive.community.doRequest(community,
            {
                url: placeServiceUrl,
                "method": "POST",
                "postBody": data
            }
        ).then(function (response) {
        });







 

 

Streamonce auto mapper in a while maps these new detected groups in google and jive.


If any thing goes wrong in google or jive, service reverts the state and responds back with an appropriate message.

 

5. Now the service adds the requesting user as an owner to the group and removes the super admin account which created the group.

 

    jive.community.doRequest(community, {url: groupMembersResourceUrl,
            "method": "POST",
            "postBody": {"person": userResourceUrl, "state": "owner"}
        }
    ).then(function (resp) {







 

 

 

6. The user gets a success message, a tip on how to add users, etc and is then navigated to the new group.

 

 1  Actions   myThoughtWorks.png

 

Life moves on.

 

So what are the awesome jive features used for this app?

  • Jive-sdk, REST apis and jive connects api

 

 

What about other settings on group? External Storage? Default page?

Group admins can still do this after the group is created.

In the last image above, the link "Go to new group" can be changed to go to the settings page instead where user can do these settings first.

 

In our case most of our users end up doing this at a later stage.

The main objective for most of our users is fulfilled here which is - they need to create a group and start sharing / collaborating through jive and emails.

 

Due to the permission changes, there is one thing a group admin cannot do - changing the group type (private to open, open to .... etc)

We anyway have a plan to create an app for that too as these settings control some permissions on google group too.

Basically our apps have been ensuring the changes made by user has right impact on jive and google.

 

Why not use Create Group webhook event?

That obviously was my first option. But i wanted a control when the create group event is in progress, not after it has happened.

Consider a case where something goes wrong on google side, if a specific email id is not available, or if google group not created due to node server shutting down?

The jive group is already created and user obviously starts using it, only to realize later something is wrong.

Many other cases.

Like what we had in the plugin where I had control when event is in progress, I needed the same control in app.

 

What advantage does jive connects give here?

I think I have overused this in most of my apps.

We can develop any service with our own authentication strategy.

Jive gives facility for all these auth types in admin console app services.

My app does not really have to care about service auth or url.

So tomorrow if I decide to change the service end point, i can do it independent of the app.

 

Also, by moving most logic to service, I could have build pipelines, easily auto deploy stuff to prod, run tests, etc for the service. A well tested and automated setup.


What exactly is the custom streamonce? and why we need all this customization?

 

Thats a long answer, worth a separate blog (already in process).

I will soon post the entire customization we did with jive-sdk and REST apis for this jive-email integration.

 

But in short about #streamonce, the default streamonce makes jive a hub and gets outside information into jive.

Jive still generates it own emails for discussions, which are more like notifications.

Both jive and gmail are equally important for our users.

We wanted emails to be emails and not notifications. And also a complete 2 way sync betweeb jive and streamonce.

The default streamonce does a 2 way sync for comments, but conversation has to be initiated from google groups.

In our case, it does not matter where it was initiated. Its real 2-way sync. content created in both the systems gets synced.

 

How can this solution be improved?

 

It would have been great if Jive has given the option to hide default create group option without the permission changes I had to do.

In this case I could have used REST apis "run-as" feature to create group from my service.

I had to do this permission change just to hide the link, which resulted into using a service account to do all stuff and then add user as owner.

 

Other one is not directly impacting the app.

But it would be great if Streamonce itegrations can be managed through apis.

Apis can give us or anyone else better control on these integrations.

 

Not sure if Jive can allow the hiding link option without permission changes in cloud.

But for streamonce, we have already given a feature request with a list of apis.

 

Source Code for app and service ???

 

Will be uploading it to github in a few days time.

Hi Jivers,

Recently we had a requirement from group admins to enable them to add user's as email followers to a group (associate group with user's email enabled stream so that they receive communication in gmail).

We had this admin essential add-on by Ryan Rutan which allowed us to add user as member, not as a email follower though.

We could extend this add-on to fit our requirements. And also could utilize system webhooks to enhance this.

 

 

The customization and google groups

We have google groups integrated with jive using custom streamonce. What this means is we have a two way sync between jive and google groups.

People can now start discussion on jive or google group and it reaches people living in both jive and gmail world.

 

Now jive has its own email notification system and email preferences.

Due to the integration we wanted the email prefs in sync between google and jive.

When a user joins a jive group as member, he starts following group in Connections, which by default is not email enabled.

People have to either enable email for this stream or create a new email enabled stream and follow group in that stream to get emails.

Complex. We simplified this for our users.

 

Our Approach: An email enabled stream for all users

 

First we decided to create an email enabled stream for all existing users and also for every new user account using webhooks.

And then if user followed a group in this (or any other) email enabled stream, he gets added to the corresponding google group.

If he unfollows group from email enabled stream, then he gets removed from the google group.

 

If he follows/un-follows a group from an non email enabled stream, nothing happens on google group.

Our java plugin has the google logic right now which will be moved to add-on soon.

 

Jive's system webhooks notifies about every new user account created/enabled on jive.

I used this trigger to create a new email stream.

 

Webhooks based logic

Before getting into changes to Ryan's app, here's what I did with webhooks initially

 

Create the example webhook by running command "jive-sdk create example-webhooks".

In this example go to explicit_routes.js in folder services-->webhooks-->backend-->routes.

In exports.postWebhooks check forr following activity

 

if(activity['verb'] === "jive:user_account_created" || activity['verb'] === "jive:user_account_enabled"){.....}

 

This event gives me api url for the new user account created.

var api_url = activity['object']['id'].

Now is the time to create new stream.

 

var postRequest = {
            'authz': "signed",
            url: api_url+"/streams",
            method:'POST',
            'auth': env.auth,
            body:'{"name":"Email Watches","source":"custom","receiveEmails":"true"}'
        };

var request = require('request');
request(postRequest, function (error, response, body){......});

I used this same api call to create stream for existing users too.

 

Associating group with user's Email watches stream

You all would have already check Ryan Rutan's admin essential add-on available at jiveapps/addons/admin-essentials at master · jivesoftware/jiveapps · GitHub.

 

Check method clickPickerAddMembers() in  group-addmembers.js in this code.

The method looks like this

 

clickPickerAddMembers : function() {
        var appObj = this;
        var batchRequests = osapi.newBatch();

        $("div.selected-user span.userid").each(function( index ) {
            batchRequests.add(
                $(this).attr("pos"),
                appObj.currentCtx.createMember({
                    "person" : $(this).text(),
                    "state" : "member"
                },
                {
                    "fields" : "username"
                }
                )
            );
        });

        batchRequests.execute(appObj.handlePickerAddMembers);
    },

 

This adds user as member in the group.

This is where I changed the logic

 

Here is my method which uses jive's connects api to call my node service

 

 

clickPickerAddMembers : function() {
        var appObj = this;

        var batchRequests = osapi.newBatch();
        $("div.selected-user span.userid").each(function( index ) {
            batchRequests.add(
                $(this).attr("pos"),
                osapi.jive.connects.post({
                    authz:"signed",
                    alias: "forceAddUserService",
                    headers : { "Content-Type" : "application/json" },
                    format: 'json',
                    "body": {"groupid": $("#currentGroup").attr("data-groupid") ,"userid":$(this).text()}
                })
            );
        });

        batchRequests.execute(appObj.handlePickerAddMembers);
    },

Now my node.js service has a route to accept this request params groupid and userid.

Using webhooks code I already have Email watches for every user (a user might decide to delete this though which my app detects and notifies about).

 

Now that the control is on my node.js service. I use jive REST api do following stuff :

  • Add user to the group as member (this is what Ryan's app was doing using javascript api)'
  • Checking if user has the email enabled email watches stream.
  • Associating the group with user's email watches stream
  • The email stream association event triggers our custom plugin which add's user to google group. I am in process of moving that part to jive add-on.

 

Post request for user membership to group

 

var addMemberRequest = {
            'authz': "signed",
            url: 'jive_url/api/core/v3/members/places/"+groupid,
            method:'POST',
            'auth': env.auth,
            body:'{"person":"jive_url/api/core/v3/people/"+userid,","state" : "member"}'
        };

 

Post request for associating group with email stream

First we need to find the Email Watches stream for the user.

We get all stream of users using this get request and find the streamid for email watches

 

var getRequest = {
            'authz': "signed",
            url:'ive_url/api/core/v3/people'+userid+'streams'',
            method:'GET',
            'auth': env.auth
        };

 

And the the post request to associate group with stream

 

var associationRequest = {
            'authz': "signed",
            url: 'jive_url/api/core/v3/streams/'+streamId+'/associations',
            method:'POST',
            'auth': env.auth,
            body:'["' + jive_url/api/core/v3/places/'+placeId + '"]'
        };

At this  point right now our plugin gets triggered which adds user to corresponding google group.

This same plugin also takes care to adding/removing user from google group when that users follows/unfollows corresponding jive group in an email enabled stream.

We are in process of moving that to add-on.

 

Thats all what my extended version of Ryan Rutan's add-on does.

 

Going back to client side from where the request to my server is made.

We had to move this app from path "jive/settings/places/group" to "jive/actions/places/group" so that its easy to access for users.

Unfortunately there is no way to restrict app link to admins/super admins.

So I wrote some client side logic to achieve this.

I wrote some promises to get current groupID, current user's ID, group's admin and super admin.

 

I would like to share the simple jquery promises (I know Q is better) i wrote for this.

Here are the promises:

 

var jivePromises = {
    isSuperAdmin : function(){
        var adminPromise = $.Deferred();
        osapi.jive.corev3.securityGroups.get({"id": "1001"}).execute(function(data){
            if(data.status != '403' && data.type && data.type.toUpperCase() == 'SECURITYGROUP'){
                adminPromise.resolve(true);
            } else {
                adminPromise.reject(false);
            }
        });
        return adminPromise
    },
    getGroupAdmins: function(group){
        var groupAdminPromise = $.Deferred();
        group.getMembers({"state":"owner"}).execute(
            function (groupAdmins) {
                groupAdminPromise.resolve(groupAdmins);
            },
            function(error){
                groupAdminPromise.reject(error);
            }
        );
        return groupAdminPromise;
    },
    getGroup: function(groupId){
        var groupPromise = $.Deferred();
        osapi.jive.corev3.places.get({ entityDescriptor: 700 + "," + groupId }).execute(
            function(response) {
                groupPromise.resolve(response.list[0]);
            },
            function(error){
                groupPromise.reject(error);
            }
        );
        return groupPromise;
    },
   getCurrentUser:function(){
        var currentUserPromise = $.Deferred();
        osapi.people.getViewer().execute(
            function (currentUser) {
                currentUserPromise.resolve(currentUser.id);
            },
            function(error) {
                currentUserPromise.reject(error);
            }
        );
        return currentUserPromise;
    }
}

Thats all. One more nice example of what node.js based jive add-on can do.

Hi Jivers,

In jive 5 and jive 6, we had a custom java plugin called Moved Content which enabled us to move contents from one group / space to other in bulk.

As Jive 7 arrived, we decided to create add-on for the same feature to get rid of plugins and get advantage of the easy development and deployment that jive-sdk has.

We have this working on our production site.

 

The Add-on

This add-on is totally based on jive's javascript apis.

I have some other apps which use combination of javascript apis on website and REST api through a connected node service.

Thats how I have modified Ryan Rutan's admin essentials to control google group memberships and stream associations from jive.

I will share that soon..

 

How the app looks


Displaying the content in current place as per selected filter options and picker for target place at the top.

First is the blog posts view.

Internally in jive, blog posts are not linked directly to a group but to a place type called blog, which is then linked to the parent group.

So keeping two separate views to avoid complexity


Screen Shot 2015-01-09 at 1.47.31 PM.png


Showing all other supported content types on other pane


Screen Shot 2015-01-09 at 1.47.43 PM.png


Showing the progress post processing



Screen Shot 2015-01-09 at 2.37.38 PM.png


 

Our dev krunalpatel helped me design the UI.

 

Some Code

The code I have shared here is the simplest possible javascript code coz my intention is to help anyone with basic JS knowledge to understand and use this app and jive-sdk.

Trust me, with basic knowledge of javascript and jquery and jive's apis, you can create wonders.

You can use some promises and other jquery utils  to beautify the code below.

 

First the user is provided with place pickers to select source and target places.

 

var displaySourcePlacePicker = function(){
    osapi.jive.corev3.places.requestPicker({
        success : function(data) {
            $("#toGroup").val(data.name);
            $("#toGroup").attr("data-groupid", data.placeID);
        }
    });
}




Then user can select content types as shown in screenshot.

 

On either selection of source group or content types, I refresh the content by making a new api call to jive with content types.

I push every selected content type in array contentTypes to be sent to jive api.

And I send the groupID, contenttypes array and current index to the method below.


var displayContentInGroup = function (groupId, contentTypes, index){
    osapi.jive.corev3.contents.get({
        "place":opensocial.getEnvironment()['jiveUrl']+"/api/core/v3/places/"+groupId,
        "type":contentTypes.join(","),
        "startIndex":index.toString(),
        "count":itemsPerPage.toString()
    }).execute(function(data){
        $("#content-body").html("");
        var contentList = [];
        if(data.list.length != 0){
            contentList.push(createHtml(data, $("#selectAll:checked").val()));
            if (data.links && data.links.next)
                setupNextPaginationButton(index+itemsPerPage);
            if (data.links && data.links.previous)
                setupPrevPaginationButton(index-itemsPerPage);
        } else {
            contentList.push("<tr> \n<td colspan=4> <h3>No content to display</h3> </td> \n</tr>");
        }
        $("#content-body").append(contentList.join(""));
    });
};





After the user selects the contents and clicks Move Content button, I call this function.

 

var moveContent = function(targetGroupId){
    var contentIds = getIdsForSelectedContent();

        for (var i in contentIds){
            content_url = opensocial.getEnvironment()['jiveUrl']+"/api/core/v3/contents/"+contentIds[i]
            osapi.jive.corev3.contents.get({"uri":content_url}).execute(function(data){
                data.parent = opensocial.getEnvironment()['jiveUrl']+"/api/core/v3/places/"+$("#toGroup").attr("data-groupid");
                data.update().execute(function (data) {
                    if(i == (contentIds.length-1)){
                        displaySuccessMessage("Successfully Moved the content");
                        refreshContentList();
                    }
                });
            })
        }
};





The above api calls changes the parent place without changing the date of the content.

And no notification is shown in activity stream for this action, so its a silent move.

 

Please find the initial version of my move content app here --> Move-content-app by shahpawan

 

Special thanks to shilpak to help me with this and all the other jive add-ons we developed for Thoughtworks

 

Enjoy node.js and jive_sdk.

Node.js has awesome possibilities, and hence now Jive has awesome possibilities.

 

Note : For people on jive cloud version 8c4+, you can just download the extension.zip attached with this blog and upload it to jive instance.

No need to download the source code, no node server required to build it locally.

Filter Blog