Space Proposal
Scope of change: Major
Champion Name: Evgeny Bogdanov
Spec Editors: Evgeny Bogdanov
Ref implementation: Apache Shindig 3.next
Background
Despite the fact that OpenSocial solves the problem of social media platform’s extensibility and gadgets portability, it has two major limitations. First, it is user-centric but does not take the user's context into account. In many social media platforms context is a crucial component and if gadgets were able to retrieve the user's context (from the hosting platform), it would greatly improve user’s experiences.
Conceptual changes
In the proposed extension a widget does not belong only to a person, it might belong to either a space or to a person. Such space or person we call the context. If a user is viewing another person's profile, then this profile is the context. If a user is viewing a space (a group, a community page, an event page, a course), then this space is the context. The opensocial's concept viewer is still valid here since only a person (not space) can view the widget. Though, the concept owner has to be redefined. Owner of a widget might be a space or a person in a sense that this widget belong to either a space or a person.
We suggest the word Space to be used. However, some other namings were proposed as well: "Community", "Group". We believe that the word Space covers broader area than "Community" or "Group" that are people centric. For example, event space or course space does not necessarily imply the community or a group of people.
Please refer to this paper on Contextual spaces for detailed information.
Difference between OpenSocial Space and Group
Space is a concept different from Group concept of OpenSocial.
Group is a way to tag people (collection of friends, relatives, etc). It is very similar to a circle concept of Google+. People in such group do not know that they are in the group, it is not the place shared with several members. Space represents another concept - a place where group of people gathered together for some activity: University course, collaborative project, event organization, discussion thread, etc. Every person in a space is aware about other participants. Imagine a group or an event on Facebook or discusion thread in google groups. If we add a gadget there it will be shared by people in that group or event. This is a Space concept.
Social graph clarification (Person vs Space)
Person
|-- his apps
|-- his connections (people with whom he is connected)
|-- his albums
|-- his activity streams
|-- his groups (friends, close friends, collegues)
Space
|-- its apps
|-- its connections (participants of a space)
|-- its albums
|-- its activity streams (actions within a space)
|-- its groups (members, admins, etc.)
Person can belong to different spaces.
APIs proposal
We provide here only JavaScript APIs with explanations to show what kind of requests are needed from widgets to work with spaces.
The initial proposal and first OpenSocial REST and JS APIs for Spaces can be found in the links section below. The APIs try to provide backward compatibility as much as posible.
Be aware that OpenSocial is planning to have IRI to identify resources.
0. security token
Security token should contain the appId information, which helps a server to identify the running app.
1. osapi.getContext (new)
osapi.getContext
Gadget should be able to know whether it belongs to a space or to a person and their respective ids.
This API retrieves info about where widget lives
osapi.getContext(function(context){ context.id; // IRI id of the item context.service; // "people" or "spaces" context.object; // object that contains info about Space or Person });
2. osapi.people
osapi.people.getViewer
Get the user who looks at widget at the moment (Viewer)
osapi.people.getViewer().execute(function(viewer){ viewer.id; viewer.displayName; });
osapi.people.get
(new) Get a list of members in a space with IRI = example.org/spaces/18
osapi.people.get({userId: "example.org/spaces/18", groupId: "@members"}).execute(function(response){ response[0].displayName; });
Get space owners (or members)
Get a list of owners in a space.
osapi.groups.get({id: "example.org/spaces/18"}).execute(function(groups){ // groups[0].id - owners = "ID49" // groups[1].id - members = "ID50" osapi.people.get({groupId: groups[0].id}).execute(function(owners){ owners[0].displayName; // owners of a space with IRI = "example.org/space/18" }); });
3. osapi.spaces (new)
osapi.spaces.get
(new) Get a list of spaces for a person or for a space
osapi.spaces.get({resourceId: "example.org/people/john.doe"}).execute(function(response){ response[0].displayName; });
4. osapi.apps (new)
Such API should be introduced to OpenSocial. App-Id exists in OpenSocial but is never defined.
Also the identification for API should be revised. It is quite possible that user would like to add few
gadgets with the same URL on his page or to a space. Consider an example of an RSS gadget: a user adds two gadgets
with the same URL and sets different RSS links in different gadgets.
osapi.apps.get
(new) Get list of apps for a person or for a space
osapi.apps.get({resourceId: "example.org/space/18"}).execute(function(response){ response[0].displayName; });
osapi.apps.getCurrent
(new) Get the currently running app
osapi.apps.getCurrent().execute(function(curApp){ curApp.displayName; });
osapi.apps.getParent
(new) Get a parent of the running app (either space or person)
osapi.apps.getParent().execute(function(parent){ parent.displayName; parent.id; });
5. osapi.appdata
Appdata should be saved either for widget context (space or person where widget belongs) or per
any other user (viewer, for example).
osapi.appdata.update
Update/Save appdata for a space or for a person
osapi.appdata.update({resourceId: "example.org/spaces/1", data: {key: value}).execute(function(){ });
osapi.appdata.get
Get appdata from the container for a space or for a person
osapi.appdata.get({resourceId: "example.org/spaces/1", keys: ['key']).execute(function(data){ data['user1']['key']; });
6. osapi.activitystreams
ActivityStreams can belong to a space or a person.
osapi.activitystreams.get
Retrieve activities of people within a space.
osapi.activitystreams.get({resourceId: "example.org/spaces/1", count: 20}).execute(function(){ });
7. osapi.albums / osapi.mediaitems
Albums and mediaitems can be associated with a space or a person.
Once albums/mediaitems are replaces with CMIS's folders/files, the new API will be adapted accordingly.
osapi.albums.get
Retrieve albums existing in a space.
osapi.albums.get({resourceId: "example.org/spaces/1"}).execute(function(){ });
8. osapi.groups
Groups represent a collection of people. They can exist for both a person (friends, collegues, etc) and a space (admins, owners, participants, viewers).
A Space can have many different groups. The groups can be created and deleted. Below is a list of generic (container-independent) groups for a space:
@members - all people who explicitely joined the space
@owners - space members with unlimited rights
@contributors - people who contribute content to the space (but less rights than owners)
@creator - the creator of a space
@followers & @following
osapi.groups.get
Retrieve groups existing in a space
osapi.groups.get({resourceId: "example.org/spaces/1"}).execute(function(results){ // results = [{id: "1", name: "members"},{id: "2", name: "owners"}] });
Shindig patch with spaces
Shindig-2.5 is taken as a base. Patch is attached (with tests)
Links
Space proposal draft based on OpenSocial 2.5 spec
Patch with spaces for OpenSocial spec 2.5
Space proposal issue for OpenSocial spec