dcukstreamflow v0.0.8
DCUK Stream Flow
an opinionated guide - for Javascript client
Quick start
First install the client as specified below:
// install via npm
npm install dcukstreamflow --save
To instantiate the client you need an API key and secret, which should have been supplied to you.
var streamFlowClient = getStream("API_KEY, "SECRET");
most common calls
//Create an instance of the feed you wish to add the event to:
var domsFeed = streamFlowClient.feed('user', domuserid);
//add the activity:
domsFeed.addActivity({
actorType: "user",
actorId: userid,
verb: 'add',
object: {
objectType: "message",
id: 123123,
title: "hello world"
},
})
// kierans 'timeline' feed follows doms 'user' feed
var kieranFeed = client.feed('timeline', kieranuserid);
kieranFeed.follow('user', domuserid);
//read 'timeline' for kieran - limit to first 5 activities
kieranFeed.get({ limit: 5, offset: 0 })
.then(function (data) {
var newsFeed = data;
})
.catch(function (reason) {
/* on failure, reason.error contains an explanation */
console.log(reason)
});
//remove activity
domsFeed.removeActivity("ACTIVITYID")
.then(function (data) { /* on success */ })
.catch(function (reason) {
/* on failure, reason.error contains an explanation */
});;;
Activities
Adding activities
According to the http://activitystrea.ms/specs/json/1.0/ spec events are made up of:
- actor
- object
- verb
- target (optional)
we can distil most events using these components.
For example:
"Dom pinned Spain to his Places to Visit Board"
Let's break the example down:
- Actor: "Dom" (User: 1)
- Verb: "pin"
- Object: "Spain" (Place:42)
- Target: "Places to Visit" (Board:1)
Now let's add this activity to a Feed using the API client:
// Instantiate a feed using feed type 'user' and user id '1'
var domsFeed = streamFlowClient.feed('user', '1');
//add the activity:
var activity = {
actorType: "user",
actorId: 1,
verb: 'pin',
object: {
objectType: "place",
id: 42
},
target: {
objectType: "board",
id: 1
}
};
// Asynchronous methods return Promise
domsFeed.addActivity(activity)
.then(function(data) { /* on success */ })
.catch(function(reason) { /* on failure, reason.error contains an explanation */ });
Parameters
Name | Type | Description | Optional |
---|---|---|---|
actorId | string | The actor Id performing the activity | no |
actorType | string | The type of actor performing the activity usually 'user' | |
verb | string | The verb of the activity | no |
object | SFobject | The object of the activity | no |
target | SFobject | The optional target of the activity | yes |
SFobject Parameters
Name | Type | Description | Optional |
---|---|---|---|
objectType | string | the type of object eg comment or place | no |
id | string | A unique id | no |
url | string | Url which refers to this object | yes |
title | string | Descriptive text | yes |
image | string | URL - absolute for an image | yes |
data | object | Dynamic object to store additional information | yes |
important : for newsfeed style aggregation of comments and likes it is essential that you include an Object Type and a unique object ID. The streamflow client provides a method to get a unique ID, or you can create your own. The StreamFlow client provides a method to return a unique ID:
var objectId = streamFlowClient.guid();
Adding activities: Custom fields and images
Using the parameters listed above you can custom fields to your activity. Here's a more expressive example
domsFeed.addActivity({
actorType: "user",
actorId: "10",
verb: 'add',
object: {
objectType: "message",
id: 4,
title: "this is my first message",
url: "http://www.mysite.com/message/4",
image: "https://s-media-cache-ak0.pinimg.com/236x/c4/69/ff/c469ff7218c10cc59913f37546576654.jpg",
data: {
location: {
x: "37.769722",
y: "-122.476944"
},
score: "thatone"
}
}
})
.then(function(data) { /* on success */ })
.catch(function(reason) { /* on failure, reason.error contains an explanation */ });
Retrieving Activities
The example below shows how to read the activities in a feed.
// get activities from 5 to 10 (pagination)
kieranFeed.get({ limit: 5, offset: 0 })
.then(function (data) {
var newsFeed = data;
})
.catch(function (reason) {
/* on failure, reason.error contains an explanation */
console.log(reason)
});
You can also include a enrich_actors:false
parameter to ensure that the system doesnt try to rehydrate the actors from DCUKID. Do this if you are using your internal Identity system for actors.
// get activities from 5 to 10 (pagination)
kieranFeed.get({ limit: 5, offset: 0, enrich_actors:false})
.then(function (data) {
var newsFeed = data;
})
.catch(function (reason) {
/* on failure, reason.error contains an explanation */
console.log(reason)
});
Parameters
Name | Type | Description | Optional |
---|---|---|---|
limit | int | The number of activities to retrieve | no |
offset | int | Index of where to start the retrieval | no |
enrich_actors | boolean | Whether to enrich the Actors via DCUKiD | yes |
mark_seen | boolean | Notification Feeds only - flag activities as seen | yes |
mark_read | boolean | Notification Feeds only - flag activities as read | yes |
Removing Activities
Activities are removed by calling the removeActivity method passing in the Activity ID.
dom.removeActivity("ACTIVITYID")
.then(function (data) { /* on success */ })
.catch(function (reason) {
/* on failure, reason.error contains an explanation */
});;;
Updating Activities
Similarly using the Activity ID you can call the UpdateActivities method. Changes show up on every feed.
domsFeed.updateActivity({
actorType: "user",
activityId: 1492789426365,
_id : 12312,
actorId:"10",
verb: 'add',
object: {
objectType: "message",
id: 4,
title: "this is my fucking last comment",
image: "https://s-media-cache-ak0.pinimg.com/236x/c4/69/ff/c469ff7218c10cc59913f37546576654.jpg",
data: {
name: "thisone",
class: "thatone"
}
}
}).then(function (data) { /* on success */ })
.catch(function (reason) { /* on failure, reason.error contains an explanation */ });;
Batch Add Activities
Multiple activities can be added in a single batch operation:
domsFeed.addActivities([{
actorType: "user",
actorId: "10",
verb: 'add',
object: {
objectType: "message",
id: 4,
title: "this is my first message",
}
Follows
Following Feeds
Example how to follow a feed:
// follow user feed
domsFeed.follow("user", 10);
// you dont have to just follow user feeds you can follow any feed (eg tags)
domsFeed.follow("tag", 22);
Parameters
Name | Type | Description | Optional |
---|---|---|---|
feed | string | The feed type to follow (usually "user") | no |
id | string | The ID of the target feed eg 10 |
The most recent set of activities in the target feed will be added to the follower feed.
Unfollowing Feeds
Stop following a feed specified in the target parameter
// follow user feed
domsFeed.unfollow("user", 10);
Reading Feed Followers
Returns a paginated list of the given feed's followers. Code example below:
domsFeed.following({ limit: '10', offset: '0' });
Reading Followed Feeds
Returns a paginated list of the feeds which are following the feed. Code example below:
dom.followers({ limit: '10', offset: '0' });
Feeds
Feed types
There are 4 feed types:
- Flat
- Aggregated
- Notification
- Timeline
Flat
Flat are the only feeds that can be followed, and therefore are a good type to setup for adding activities. Flat can also be used to consume activities from other feeds - in a "timeline ticker"-like manner.
Aggregated
Aggregated are good for consuming activities in an "aggregated"-like manner. You cannot follow an aggregated feed. They are helpful if you want to group activities. For example:
- Dom followed 12 people
- Kieran and 24 others like your photo
The aggregation format itself is set up at system level, please contact the admin for further information.
Notification
The Notification type makes it easy to add notifications to your app. Notifications cannot be followed by other feeds - but you can write directly to a Notification feed. Notification feeds also record which activities have been viewed and read.
domsNotificationFeed.get({ limit: 5, offset: 0, mark_read: true,mark_seen:true })
.then(function (data) { /* on success */ })
.catch(function (reason) { /* on failure, reason.error contains an explanation */ });;;
Timeline
Timeline feeds are good for consuming activities in an "facebook"-like manner. They support affiliated activities such as Comments and Likes. You cannot follow an aggregated feed.
Likes and comments
Streamflow supports the creation of Facebook-style timeline feeds, with affiliated activities such as Comments and Likes grouped into an Aggregated Activity.
If you wish to set up your feed to support this then here are some notes:
Comments are of object type
message
with verbcomment
Likes are of verb
like
Add a
To
tag (more detail below) to ensure the author(s) of the originalActivity
thats being reacted to receive the Activity too.
Add message example
domsFeed.addActivity({
"actorType":"user",
"actorId":10,
"verb":"add",
"object": {
"objectType":"message",
"id":13,
"title":"this is a message"
}
});
Add like example
domsFeed.addActivity({
"actorType":"user",
"actorId":10,
"verb":"like",
"object": {
"id":13,
"objectType":"like"
}
});
Add comment example
domsFeed.addActivity({
"actorType":"user",
"actorId":12,
"verb":"comment",
"object": {
"objectType":"message",
"id":14,
"title":"this is a comment",
},
"target": {
"id":13,
},
"to": [
{
"id": 10,
"feedGroup": "user"
}
],
});
Adding nested comments / likes
Streamflow supports nested comments a likes to ensure these work as expected please:
Add godfatherid and godfathertype to
target
->data
object to represent the masterActivity
, so we can nest these all inTarget represents the parent of the
Activity
Always a a
To
tag to post comments/likes to the feed of the godfatherActor
. so that they can spawn off to his/hers followers as well
Add nested comment example
domsFeed.addActivity({
"actorType":"user",
"actorId":6,
"verb":"comment",
"object": {
"objectType":"message",
"id":15,
"title":"this is a nested comment",
},
"target": {
"id":14,
"data":{
"godfatherid":13,
"godfathertype":"message"
}
},
"to": [
{
"id": 12,
"feedGroup": "user"
},
{
"id": 10,
"feedGroup": "user"
}
],
});
Add like a comment example
domsFeed.addActivity({
"actorType":"user",
"actorId":10,
"verb":"like",
"object": {
"id":14,
"objectType":"like"
},
"target": {
"id":13,
"objectType":"message"
},
"to": [
{
"id": 10,
"feedGroup": "user"
}
],
});
Add nested like example
domsFeed.addActivity({
"actorType":"user",
"actorId":10,
"verb":"like",
"object": {
"id":15,,
"objectType":"like"
},
"target": {
"id":14,
"objectType":"like"
"data":{
"godfatherid":13,
"godfathertype":"message"
}
},
"to": [
{
"id": 12,
"feedGroup": "user"
},
{
"id": 10,
"feedGroup": "user"
}
],
});
Realtime
You can use the DCUK Pusher account to receive realtime updates to your feeds.
Include the Pusher JS Client:
<script src="https://js.pusher.com/4.0/pusher.min.js"></script>
var pusher = new Pusher('5a43e5de4fa91217fa49', {
cluster: 'eu',
encrypted: true
});
Then subscribe to the channel which represents the users feed. The channel name is the Feed Group Name and the User Id seperated by a hyphen. Eg 'timeline-23' :
var channel = pusher.subscribe('timeline-23');
Then you bind the function you wish to execute to the 'new-activity' event :
channel.bind('new-activity', function (data) {
//insert activity into the timeline
});
Targetting using the TO field
The "TO" field allows you to specify a list of feeds to which the activity should be copied. One way to think about it is as the CC functionality of email.
Using this you can:
ensure that all users in a conversation get activities copied to them regardless of whether they follow the user or not.
add activities explicitly to a users Notification feed
Use the optional term property to support @mentions and notify users.
Use the optional term property to support #hashtags.
For example to copy another user into this activity you:
domsFeed.addActivity({
"actorType":"user",
"actorId":12,
"verb":"add",
"object": {
"objectType":"message",
"id":14,
"title":"this is a message",
},
"to": [
{
"id": 10,
"feedGroup": "user"
}
],
});
Using the term property to support mentions and hashtags:
dom.addActivity({
actorType: "user",
actorId:"10",
verb: 'add',
to: [{
id: 9,
feedGroup: 'notification',
term:'michael'
},
{
id: 3,
feedGroup: 'tag',
term: 'metformin'
}],
object: {
objectType: "comment",
id: 4,
title: "this is my first comment",
image: "https://s-media-cache-ak0.pinimg.com/236x/c4/69/ff/c469ff7218c10cc59913f37546576654.jpg"
}
}).then(function (data) { /* on success */ })
.catch(function (reason) { /* on failure, reason.error contains an explanation */ });;
Parameters
Name | Type | Description | Optional |
---|---|---|---|
feedGroup | string | The feed type to add the activity to (usually "user") | no |
id | string | The ID of the target feed eg 10 | no |
term | string | String containing the hashtag or @username of the To | yes |
Enrichment
The Client also provides a title generator method which will add titles - mainTitle
and mainActivityTitle
to the Activity
object which can aid when displaying
domsFeed.get({ limit: 5, offset: 0 })
.then(function (data) {
if (data.length > 0) {
var titleGenerator = streamFlowClient.title(data, 10);
var enrichedActivities = titleGenerator.addTitles();
var newsFeed = enrichedActivities;
}
})
.catch(function (reason) { /* on failure, reason.error contains an explanation */
console.log(reason)
});