CloudServices/Presence: Difference between revisions

From MozillaWiki
Jump to navigation Jump to search
 
(101 intermediate revisions by 7 users not shown)
Line 6: Line 6:


==Overview==
==Overview==
The goal of Mozilla Presence is to provide a way for applications to know when their users are online,
even if they don't have the application running.


XXX find a better sentence here
Presence is a proposed Cloud Service that tracks a Firefox OS device's Internet connectivity status as ''online'', ''offline'' or ''unavailable'' by the device's Firefox Account. A Firefox OS Web App may request permission on behalf of its publisher to read status. Once approved, the publisher may poll the Presence service and, once the device is back online, push messages to the Web App.
 
See [[#Architecture Overview]] for more details.


==Project Contacts==
==Project Contacts==
''Principal Point of Contact'' - <i>Tarek Ziadé</i> <i>tarek@mozilla.com</i>


''IRC'' - #<i>presence-wg</i>
''Principal Point of Contact'' - <i>Tarek Ziade</i> <i>tziade@mozilla.com</i>
 
 
* ''IRC'' - #<i>presence-wg</i>
* ''Group Email'' - https://mail.mozilla.org/listinfo/wg-presence
 
===Team===
 
==== Cloud Services ====
 
 
* <i>Tarek Ziade</i> <i>tziade@mozilla.com</i>
* <i>Ben Bangert</i> <i>bbangert@mozilla.com</i>
* <i>Robert Lord</i> <i>rlord@mozilla.com</i>
* Firefox Account Engineer - TBD


''Group Email'' - [https://mail.mozilla.org/listinfo/wg-presence wg-presence@mozilla.org]
==== Firefox OS ====


==Goals==
* <i>Fabrice Desré</i> <i>fabrice@mozilla.com</i>
<i>How will you know things are working?</i>
<i>What problems does this solve?</i>


==Use Cases==
==Presence on other Mobile Platforms==


===Presence on iOS===


=== Facebook ===
In iOS >= 7.x, applications that want to provide a presence feature can
keep a socket opened in the background even if the application is not
running anymore in the foreground.


Jeff wants to appear online on Facebook (he's already determined on Facebook who can see him, etc).
The feature is called setKeepAliveTimeout (https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplication_Class/Reference/Reference.html#//apple_ref/occ/instm/UIApplication/setKeepAliveTimeout:handler:)
and will give the app the ability to register a handler that
will be called periodically to check on the socket connection. Only approved VOIP apps are
allowed by Apple to always keep a socket alive and not be terminated. Apple
is very discerning about which apps get to use this functionality.


He's already installed the Facebook app on his FFOS phone, he goes to the Settings and touch, "Authorize Presence",
The handler has a limited time to do it (max 10 seconds) but
his screen loads a doorhanger (provided by Mozilla Presence) asking if he wants to authorize the app.
this is enough to handle presence for the user by interacting with a
server.  


Jeff clicks "Yes" on the doorhanger page, and the Facebook app waits while Facebook recieves the redirect, stores
The Apple Push Notification Service https://en.wikipedia.org/wiki/Apple_Push_Notification_Service
his UID, and closes the doorhanger (and likely needs to do something else to register this with the device so that
is also often used by applications to keep a connection opened on a
it will appear in the Presence Settings page).
server to receive push notifications. That's comparable to the Simple Push
service Mozilla has added in Firefox OS.


The next day, Jeff wakes up, and goes to check his e-mail on his phone. Upon seeing his idle drop, the phone's
Therefore, building an application with device-level presence on an iOS device
simple-push client (which is always running) includes an 'O' in its next PING to simplepush to indicate the user
is doable but requires the publisher to maintain one or several connections per user
is now online. Mozilla Presence gets notified of this and acts on it to batch the status change to Facebook. The
opened all the time and very few applications qualify for VOIP status.  
batch of updates goes to Facebook including Jeff's, so Facebook knows that Jeff is now online, and updates its
database indicating this.


Jeff's friend Marsha goes to Facebook to see if any of her friends are online. Marsha sees that Jeff is now online
=== Presence on Android ===
and sends a chat request. Facebook uses SimplePush to notify Jeff of the chat request. Jeff sees the chat request


=== AppMaker ===
Like iOS, Android provides features to run some services in the background,
see http://developer.android.com/guide/components/services.html


Sue has signed up to be an appmaker tutor -- Bob is a new appmaker teacher, and is stuck in a workshop, Bob wants to know which of the tutors are available to help w/ a togetherJS session
However, the service can be killed when the memory becomes low, and
if TCP/IP is used it can be hard to have a reliable service.


Sue is an appmaker expert. She previously authorized AppMaker to see her Online Presence - as Jeff did in with
Google also provides a "Google Cloud Messaging" (GCM) service - http://developer.android.com/google/gcm/index.html
Facebook in the previous story. She also configured her notifications so any message coming from AppMaker
That provides similar features than Simple Push, to push notifications to users.
when she's online would display a message on her screen and let her start the app.


Bob is building a cool new application with his class in AppMaker and would like some input from someone. Appmaker maintains a mapping of which helpers are appropriate for which users (e.g. by language skills). He's currently working in AppMaker from his FFOS Phone and sees that Sue is online.
There's also a new feature called GCM Cloud Connection Server - (CSS)
http://developer.android.com/google/gcm/ccs.html - that allows applications to communicate
with the device via XMPP and on the client side "Intent Services".  
The app and the devices interact with CSS, which relays the messages back and forth.


Bob clicks on Sue's name in his contact lists and hit "invite Sue for peer design session".
There's a full example on that page, of a Python server interacting with the GCM service
AppMaker sends a notification to Sue using the Simple Push service.
to interact with users.  


Sues gets the notification instantly on her phone via her simple-push client and joins Bob on the  
The architecture is quite similar to what we want to build with Mozilla Presence
design page.
since GCM acts as an intermediary between the app server and the device.


AppMaker uses Together.js so Bob and Sue can interact live on the page.
However, CSS is a neutral messaging relay and does not keep track of users online
status. It sends back and forth what the server and the device have pushed in the pipe.


=== Support ===
So it's still up to the app to leverage this service to keep track of connected
devices to get device-level presence.


(This is about a tentative and unnamed Firefox OS support tool.)
'''if we decide not to build presence, maybe we would just need to build that relay to make sure we offer FFOS apps the ability to implement presence the right way, like what Google provides on Android'''


Maria is a Mozillian who wants to helpful to other Firefox OS users.  She signs up with a support application (an application that Mozilla creates).  She indicates what she knows about, and what languages she speaks.
XXX stuff to dig: can we use CSS with BOSH or with websockets


Javier wants to activate developer mode on his phone, but can't find the right setting.  He goes into '''Help &gt; Live Support'''.  The phone sends a request to the support app: someone wants support with Settings in es-MX.  The application looks in its database of contributors to see who has the appropriate expertise (and language) to help him, and who is online.  Among the pool of possible people it selects Maria, and pings her to see if she can provide support.  If she doesn't respond then another person is selected from the pool (or maybe many people are asked at once), and if someone else helps Javier then Maria is notified that her help is no longer needed.
==Goals==


Note that Maria would be participating under an alias specific to the support application (though not anonymous), and she will not be fielding support requests all the time (e.g., she may not provide support at work, only after hours).
Phone UI for users to:
* see at a glance and manage what applications they granted presence access to.
* see lively notifications and act on them or ignore them.
* manage how much idling is considered to be 'online' vs. 'away' vs. 'offline'
* set custom status updates


=== Talkilla ===
Mozilla Cloud Services run system that:
* allows a user to authorize an AppService access to the users presence
* sends notifications to the users device that they can act on
* sends user presence updates to authorized AppServices


XXX
Note: Lively notifications are different than SimplePush style Notifications in that they can require immediate action else they'll become stale, like a missed phone call.


=== SUMO ===
The project will be a success if an application registered with Mozilla Cloud Services is able to reach out to users that are "online" (active on their phone or desktop but with the app not running) via Mozilla Presence.


XXX See with Lloyd about the user story there (sumo experts summoned etc)
==Use Cases==
 
See [https://wiki.mozilla.org/CloudServices/Presence/UseCases Detailed Use Cases].


==Requirements==
==Requirements==
* <i>List of requirements</i>
* <i>List of requirements</i>
==Get Involved==
==Get Involved==


Line 90: Line 123:


[https://id.etherpad.mozilla.org/presence Identity Presence Etherpad]
[https://id.etherpad.mozilla.org/presence Identity Presence Etherpad]
[https://etherpad.mozilla.org/presence-meeting Presence Meeting Wiki]
== Meetings ==
We try to meet every Thursday at 10:00 Pacific Time
For mozilla employees, we meet in the "Services" vidyo room, and use IRC channel #presence-wg (irc.mozilla.org)
For participants outside of mozilla, you can call into the meeting using the following numbers:
* Phone (US/Intl): 650 903 0800 x92 Conf: 98616#
* Phone (Toronto): 416 848 3114 x92 Conf: 98616#
* Phone (US): 800 707 2533 (pin 369) Conf: 98616#
Please mute yourself with '* 1' upon joining to prevent needless noise and feedback. You can unmute yourself with '* 1' again to speak.


=== Meeting Notes ===
=== Meeting Notes ===
https://etherpad.mozilla.org/presence-meeting-20140311


[[Services/Roadmaps/Presence/Meetings/notes_20131014]]
[[Services/Roadmaps/Presence/Meetings/notes_20131014]]


[[Services/Roadmaps/Presence/Meetings/notes_20131031]]
[[Services/Roadmaps/Presence/Meetings/notes_20131031]]
https://etherpad.mozilla.org/presence-2013-11-26


=Design=
=Design=
==Points of Contact==
==Points of Contact==
Engineer - <i>Name</i> <i>contact@info</i>


== General Overview ==
Services Engineers:
 
* <i>Ben Bangert</i> <i>bbangert@mozilla.com</i>
* <i>Tarek Ziadé</i> <i>tarek@mozilla.com</i>
 
==Architecture Overview==
 
There are two levels of presence:
 
1/ app-level presence
 
* online: you are connected in the app, and using it
* offline: you are disconnected from the app
 
2/ device-level presence.
 
* online : you are using your FXOS phone or your desktop browser
* offline: you are not on your FXOS phone or your browser
 
Sometimes you might be online in 1/ or 2/ and not wishing other users to know about it. And you also might want to appear online for app B but not for app C.
 
1/ is solved by every application. they all have their ad-hoc system, their social graph, rosters, contacts, etc. Large social networks don't care as much about 2/ because they would prefer you to use *only* their application for talking to your friends. By solving 2/, we can enable non-dominant social/communication applications to get useful presence information they can act on.
 
Mozilla Presence acts as a <b>trusted intermediary between the user's device (solving 2/) and the applications the user has allowed to see their presence, as well as a short-lived notification system for applications to engage available users</b>.
 
[[File:PresenceOverview.jpg]]
 
Channel communication overview:
 
[[File:MPChannels.jpg]]
 
== Terminology ==
 
;AppDeveloper : A developer that creates applications which may or may not have server-backed resources.
 
;AppService : An Internet-accessible server that an application talks to. For example, Facebook's locally installed application talks to Facebook's API server to get data. The Facebook API server in that case is the AppService as it acts as a service to the application.
 
;Application : A website application that might run locally on a device with or without needing to talk to an AppService.
 
;FxAID : A Firefox Accounts user ID.
 
;Device Presence Channel : A channel of communications between a phone/browser device and Mozilla Presence that carries live notifications from Presence and presence data to Presence.
 
;AppService Presence Channel : A channel of communication between Mozilla Presence and an AppService that carries presence updates for users sharing their presence with the AppService and live notifications from the AppService to be delivered to a PUID.
 
; LiveNotification : A live notification is an alert requiring a response within a set period of time (5 seconds up to several minutes) before its considered 'missed' and stored on the device separately to indicate it can no longer be acknowledged. A response is considered acknowledgement and switches the user to the appropriate application to act on the LiveNotification.
 
; Presence : For our purposes the definition of presence definined by XMPP also applies, but in our case 'contacts' happen to be AppServices that the presence is broadcast to. See http://xmpp.org/rfcs/rfc6121.html#presence-fundamentals
 
;PUID : A Presence Unique Identifier. Every AppService authorized by a user to see presence updates will be assigned a PUID that it should store and associate with the user (who may or may not be logged into the application).
 
== API Reference/Documentation ==
 
The Presence service has several functions:
 
# '''Device Channel to Mozilla Presence''' - let a '''user''' update her online status and set a custom status message
# '''Applications registration''' - let a '''developer''' register an application
# '''Applications permissions''' - let a '''user''' manage applications access to their presence
# '''Status updates''' - let an '''application''' receive status updates
# '''Live Notifications''' - let an '''application''' send a live notification and a user receive it.
 
=== 1. Device Channel to Mozilla Presence ===
 
Mozilla Presence provides a secured web socket endpoint at '''wss://presence.services.mozilla.com/presence''' for
devices to connect to.
 
The user may connect to the socket using a valid FxA (which will entail a BrowserID Assertion per FxaSSO), and send status updates.
 
The data must be sent in JSON and is based on a simple protocol where a first request must be made to create a new session.
Each subsequent request is a status update. The server or the user can disconnect from the socket at any time and for
any reason. In that case the session is lost and a new session must be initiated.
 
==== Session Request ====
 
Example of a session request:
 
    {'type': 'connect',
    'application_ids': [421, 492, 9592, 391],
    'assertion': 'valid persona assertion'}
 
where:
* '''assertion''' is a valid persona assertion
* '''type''' is the type of request. in that case "connect"
* '''application_ids''' is the list of applications IDs presence updates should be sent to.
 
The '''application_ids''' field is used because Mozilla Presence does not retain a list of applications
authorized to see updates. This data is kept only on the phone. As a result, the device must
indicate what application ID's presence data should be sent to when connecting.
 
The server validates the assertion by sending it to a persona/fxaccount verifier,
and if valid, creates a unique session id and sends it back to the cient.
 
Example:
  {'result': true, 'session_id': '61539351-1f02-4b62-a136-205000ece41a'}
 
In case there's an issue, like an invalid assertion, the server will send back a
request with a result flag set to false, an '''errno''' field with
an error code (to be documented) - and an error message in the '''reason''' field.
 
Example:
 
  {'result': false, 'errno': 34, 'reason': 'Invalid assertion'}
 
 
==== Status Update Request ====
 
Once the session is set, the client can send status updates.
 
Example:
 
    {'type': 'status',
    'session_id': '61539351-1f02-4b62-a136-205000ece41a'
    'status': 'online'}
 
where:
* '''session_id''' the session ID
* '''type''' is the type of request. in that case "status"
* '''status''' the presence status. The value must be one of "online", "offline", "unavailable".
 
In case the device wants to send a status update to a specific subset
of applications, it can use the 'application_ids' key on a status update
request, it will override the value set on a visibility call, just for
that call.
 
Example:
 
    {'type': 'status',
    'session_id': '61539351-1f02-4b62-a136-205000ece41a'
    'application_ids': [421, 391],
    'status': 'offline'}
 
For every status request received, the server sends back an ACK message.
 
Example:
  {'result': true}
 
In case of an error, the server will send back an extra 'errno' field with an
error code (codes to be documented) and an optional 'reason' message.
 
Example:
 
  {'result': false, 'errno': 34, 'reason': 'Assertion expired'}
 
The error codes have to be documented, but in case the errno value is
a negative value, the session is lost and the client has to recreate a new one.
 
The user can send as many updates as it wants, but the server can ask it to
slow down with a specific  error code  (codes to be documented)
 
The server or the user can disconnect from the socket at any time and for any reason.
The number of socket connections is limited to one connection per device and per email.
 
=== 2. Applications registration ===
 
An App developer can register a new application into Mozilla Presence
 
An application is defined by:
 
* a domain
* an email
* a name
* a description
 
Registering a new application is done in 3 steps
 
# validation of the domain ownership
# attribution of a unique application ID
# activation of presence notifications
 
'''Domain Ownership Validation'''
 
Mozilla Presence provides a web page at '''https://presence.mozilla.com/myapps'''
where an application developer can connect by logging in with her persona account.
 
Once logged in, the developer can fill a
form with a domain, name and description of the application to register.
 
Mozilla Presence generates a unique key of 1024 characters, the developer needs
to place in this URL: ''http://<domain>/__presence'' in a plain/text file that
can be reached pubicly.
 
Once the key is placed, the developer can hit a '''Verify''' button.
Mozilla Presence will then visit ''http://<domain>/__presence'' to verify
that the domain is owned by the developer.
 
'''Application ID'''
 
Once the domain has been verified, Mozilla Presence generates a unique id for the
application, and displays an entry point the developer will need to visit to
get status updates.
 
The entry point is in the form of '''ws://<node>.presence.mozilla.com/<appid>'''
and is a web socket the developer's application may connect to, in order to
receive status updates.
 
 
'''Activation of presence notifications'''
 
To activate the status update stream, the app developer needs to visit
'''https://presence.mozilla.com/myapps''' and click on the '''Activate'''
button located besides the application name (a developer may have several apps.)
 
By clicking on '''Activate''', an API key is generated for the application and
displayed besides the application. An API key is a string of 1024 chars.
 
This API key has to be used by the application in order to get status updates.
 
Getting status updates is done by connecting to the websocket located at
'''ws://<node>.presence.mozilla.com/<appid>''' with the API key.
 
Example:
 
  {'key': 'e3b0c44298fc1c149afbf4c8....996fb92427ae41e4649b934ca495991b7852b855'}


This service is hooked onto SimplePush, such that when a client ping comes in that includes presence info (either O,
Once connected, the application will receive status updated as they happen,  
A, or U to indicate Online/Away/Unavailable based on the devices Presence policy dictated by the devices user
in the form of a list. Each element is composed of an uid and a status.
and its idel time), then SimplePush will broadcast that to Presence somehow, that client id XXYYY is now O/A/U or
whatever. Presence then updates its record and relays the status update to the services the user has authorized.


The service stores records for every user that has Presence 'activated'. The device is tied to the users FxA such
Example:
that if the device is lost, when they get a new one they will still identify the same. If/When a client needs to
re-register for SimplePush, the SimplePush client-id is sent to Presence to tie it to the existing FxA record.


Presence stores a set of data (rough schema):
  [{'UID': 2123131, 'status': 'online'},
  {'UID': 12345, 'status': 'offline'}
  ]


Where '''UID''' is a user identifier as described in the next section.


    Client-Mappings:
=== 3. Applications permissions ===
        Client-ID  | Corresponds to the client-id that is used for SimplePush
        FxA-ID      | The FxA of the presence user


    Presence-Authentications
Granting presence access requires user interaction to indicate to Mozilla Presence that the user wants an AppService to see their presence information. In the event that the user might have multiple identities or profiles on a single AppService, a user-meaningful string should be included in the authorization request to Mozilla Presence.
        FxA        | The FxA of the presence user
        Service-ID  | Service ID that the app developer registered for this service
        UUID        | A unique ID for this user on this service, to avoid leaking the FxA ID
        Status      | Boolean flag on whether the user currently wants presence broadcast to this service


Here's what a users interaction with an application to grant it presence might look like:
[[File:WPPhoneOverview.jpg]]


   
The following steps occur in this flow:
When the user changes the toggle on their device to turn on/off Presence, their device must be able to
# User clicks Authorize button
contact our server so that we can update their Presence choice in the Presence-Authentications table.
# User acknowledges the AppService they're granting and allows it
This is because Presence is broadcast in the background by the SimplePush UA, and we don't want to
# User is redirected back to the AppService
have to include a list of all the 'apps' that should get the presence update in every ping request.
   
When Presence gets a status update from simplepush, it looks up the client-id in the Client-Mappings, then uses that
to lookup all the services in Presence-Authentications that the user wants notified of this change. It filters out
services that the user has currently chosen not to recieve presence. The remaining services have their webhook URL's
called with the UUID and presence change so that the services can decide what they want to do.


To avoid a call for every single status change, the Presence service may batch updates to the various services so
==== Technical Details ====
that the webhook URL for each service is only called every 30+ seconds with all the updates intended for it (in the
list POST format explained above).


== Architecture Overview ==
The page URL the Authorize buttons posts to is:
https://<node>.presence.mozilla.com/<appid>/grant?redirect=<url>&id=<userstring>


http://ziade.org/presence.jpg
Where <node> and <appid> are values known by the registered application, <url> is the url to redirect back to, and <userstring> is the user-meaningful string indicating that should usually be their login name (or something short and meaningful to distinguish multiple identities on a single AppService if applicable).


# appmaker asks for a token
In the example above, the user Marge happens to be logged into BeerChat as 'Fred', so this identifier is attached during authorization so that when Marge manages her Presence she can see that she appears online as Fred to BeerChat.
# appmaker register to the presence server to ask for presence info - basically a POST with the web hook + the token as an auth
## Bob decides to give appmaker Presence access.
## Bob is redirected with appmaker token to Presence service.
## Bob hits 'Yes' to grant appmaker access to his Presence
## Bob is redirected back to appmaker with token that includes Presence UID (the one you'll get with the update in step 5)
# bob updates his status with the presence
# sarah updates her status with the presence
# the presence service calls the webhook to notify status updates


=== Proposed Modifications to SimplePush ===
The user is expected to already be signed into their Firefox Account in this example, otherwise they will need to first login to Prsence before seeing the authorization page.
SimplePush protocol is [https://wiki.mozilla.org/WebAPI/SimplePush/Protocol defined here].


Principle changes to the protocol involve introducing a change to the "hello" and "ping" packets.  
Authorizing the AppService performs a POST on https://<node>.presence.mozilla.com/<appid> containing the redirect url and the answer.


The "hello" packet needs to be modified to include a GUID as the user's Presence ID (PrID). This is required because SimplePush UserAgentIDs (UIAD) can change at any time, where the PrID is more "stable", but only active when the user opts into Presence.
If user has accepted, Mozilla Presence generates a unique ID (PUID) to identify the user in the context of the application.


In an effort to save bandwidth, keys are reduced to x + "p" + sub identifier.
The user then is redirected back to <url> with an encoded PUID in a <Presence-UID> header.


old format:
The application is responsible to store the PUID and associate it with the user.


    {messageType": "hello", "uaid":"...", "channelIDs":[...]}
The redirect flow looks like this:
[[File:WPAuthInteraction.jpg]]


new format:
=== 5. Status updates ===


    {"messageType": "hello", "uaid":"...", "channelIDs":[...], "'''xpi'''":"..."}
When Mozilla Presence gets a status update from someone, it looks up all the
registered applications and sends to the one that are activated to see the updates.


It is important to note that future simplepush reregistrations use the same "xpi" value (if defined). This will allow the SimplePush socket plugin monitor to associate the correct to the correct Presence server.  
Since statuses are fetched via a web socket at ws://<node>.presence.mozilla.com/<appid>, each application gets its own messaging queue that is dequeued when the application is connected via the web socket. A status message is dropped from the queue if not
consumed within an hour.


"ping" packets would use the optional long form and contain the Presence Status (xps).  
=== 6. Live notifications ===


    {"messageType": "ping", "'''xps'''":"(UAO)?"}
Live notifications are a way for applications to reach out online users that are not active in the application.
It can be used to give the opportunity to the user to react when something is happening in the application.


A simplepush "ping" packet is exchanged between the client and server when the user's status changes. User's status is indicated by
Examples:
* "A"way (user is idle or temporarily unavailable)
* "U"navailable (user has gone offline)
* "O"nline


This information would be picked up by the Presence Plug-in to SimplePush which would send the status change to the Presence monitoring system using ''TBD'' REST calls.
* ChatRoom: Your nick was used in a message sent to the room.
* ChatRoom: Someone wants you to join the room.


=== For App Developers ===


An app developer wishes to get presence information, the following can be addd to the app manifest:
AppService sends a notifications to Mozilla Presence via a POST request :


    {
  POST https://<node>.presence.mozilla.com/<appid>/notification
        "permissions": {
 
            "push": {"description": "To receive notifications about the newest phone releases"},
  [{'UID': 'userid',
            "presence": {"description": "To broadcast presence"}
    'message': '<message>',
        },
    'action': '<url>'},
        "messages": [
    ...
            {"push": "/view_to_launch.html"},
  ]
            {"push-register": "/view_to_launch.html"}
        ]
    }


Note that the existing bits for SimplePush are retained, as Presence merely add's broadcast of the user's Presence
AppService can send notifications by batches.
to the app.


The application developer must register their application separately with Mozilla Presence and set a "Webhook URL"
Details:
that will be called with presence updates for users that look like the following:


    POST /some/webhook/callback
* ''userid'': the user ID provided by the presence system.
   
* ''message'': a message to display to the user. Limited to 512 chars.
    {[
* ''action'': an action that will happen on the device if the user agrees - it can be an url to visit or an application to run. Limited to 512 chars.
        ["UID2949293", "away"],
        ["UID4823888", "online"],
        ["UID482838", "offline"],
        ["UID4828382", "online"]
    ]}


When the user grants access, your application will get a unique ID that you should associate with the user record
Mozilla Presence pushes the message into a FIFO queue. There's one queue per user id + app id combination, and its size
your application stores.
is limited to 100 items. When the queue is full, the oldest item is dropped before the new item is added.
For each item, it appends in the mapping the ''appid'' value.


A doorhanger will be needed in applications to prompt the user to grant an application Presence notification data
Once the message is stored, the service sends back an ack message to AppService, with the  
should the user not grant it initially when installing the app (and for websites that don't necessarilly install
current size of the queue:
as 'apps').


Setup of a doorhanger will require the app developer to register their application with Mozilla Services and get
  {'result': 'OK',
an application token. This application token can be used with Mozilla TokenServer to register access with the
    'queue_size': <size>}
Mozilla Presence server. The app developer may then enter the "Webhook URL" in their Settings page for Mozilla
Presence.


When a user signs-in to your application/website and you wish to ask for Presence notifications, you may redirect
Receiving the ack is a guarantee that the message was stored on the server, but
the user to Mozilla Services asking for "Presence" access. The user will be prompted to grant access or deny and
is not a guarantee that it was delivered to the user.
redirected back to your application. If the user granted access, the redirect will include an encoded UID that you
should store and associate with the user as this UID will be the one sent in the Webhook calls.


App developers should account for the possibility that 'updates' may get lost, and automatically mark a user as
If the user is connected to Mozilla Presence via the Presence daemon, it gets all
offline if no status is sent in an hour.
the items from the queue and the queue is purged.


=== For Device Users ===
The Presence daemon on the device is responsible to dispatch the messages to
the different applications:


* '''on desktop''', it displays a notification with the url contained in the action for the user to click
* '''on mobile''', it displays a notification with a link to run the app XXX


A separate Settings page is available, that looks similar to the iOS Notifications page, showing a list of apps and
The application has no feedback on whether a notification was seen by the user.
websites that have been granted Presence access. The page also lets one set a "Presence Policy" that determines
what liveliness is communicated, for example:


    Presence Policy
==FAQ==
   
    Show me online when I've used this device in the past:
    5 - 10 - 15 - 20  (minutes)
   
    Show me away when I haven't used this device in at least:
    5 - 10 - 15 - 20  (minutes)
   
    Show me offline when I haven't used this device in at least:
    10 - 25 - 35      (minutes)


To help people get up to speed faster and prevent backtracking, commonly asked questions by those getting involved are listed here with an answer.


Perhaps these will be sliders, UX is not determined this is only a possible example of how the user determines
=== Is this going to use XMPP? ===
what type of 'livliness' data is sent based on whether they're using the device or not, and how recently.


A list of toggles for each app the user has granted access to will be here, so that a user may turn off Presence
The presence channel to AppServices will have an XMPP option. It's useful to remember that Mozilla Presence is in very early stages at this moment. Worrying about the exact implementation is a detail that we're not addressing yet as we build some prototypes to test ideas out and prove the overall concept is worthwhile.
for individual apps temporailly without fully revoking possible future Presence broadcasts to the app/website.


<!--
=== Shouldn't Mozilla have a way for me to see my contacts online? ===
==API Reference/Documentation==
=== Data Schema ===
<i>How will data be stored</i>
=== API ===
<i>How to call the data</i>
==== <i>method</i> <i>URI</i> ====
<i>description</i>


Arguments <i>argument descriptions</i>
Nowadays, peoples' personal connections are spread across multiple online services (Facebook, Google+, Skype, etc). These services usually already have done the work of ensuring both people want to see each other's presence and have ways to facilitate a conversation. All they need is a way to be aware of a users presence when their app might be closed or suspended (on a phone). By serving as the underlying plumbing notifying AppService's when users are online, Mozilla Presence avoids having to try and change users expectations about where their 'friends' are and can facilitate new social interaction applications that need presence data.
Returns: <i>returned contents</i>
-->


==Platform Requirements==
==Platform Requirements==
Line 282: Line 495:


==Code Repository==
==Code Repository==
<i>Links to the published code bases</i>
 
Repository: https://github.com/mozilla-services/presence
 
Diagrams: https://github.com/mozilla-services/presence-graffles
 
==Release Schedule==
==Release Schedule==
<i>Predicted code delivery dates</i>
 
===Prototype===
 
Server-side implementation:
 
* Allows AppServices to send LiveNotifications
* Sends AppServices presence stanzas
* Holds WebSocket connection to devices
* Sends LiveNotifications to devices
* Allows a device when connecting to toggle what AppServices should have presence stanzas relayed
 
Client-side implementation:
 
* Settings screen to manage
** Applications that can use Presence (On/Off toggles)
** Online - Away - Offline sliders to set how much idle is away vs. offline
** Custom status message
** Custom away message (if additional info should accompany it)
* LiveNotifications pop-up with Accept/Dismiss button
* Background service that sends pings, accepts LiveNotifications
 
===Production V.1===
 
Everything in the Prototype, designed for scale, in addition:
 
* Possibly a QUIC-derived UDP-based device-presence channel
* XMPP interface for AppServices <-> Presence
* FxA Integration for device user (Requires https://wiki.mozilla.org/Identity/Firefox_Accounts/SSO)
* Developer Registration page to acquire Presence Application ID, linked to from the Developer page in Marketplace
 
=QA=
=QA=
==Points of Contact==
==Points of Contact==

Latest revision as of 18:50, 11 March 2014

Last updated: 2014/03/11
Draft-template-image.png THIS PAGE IS A WORKING DRAFT Pencil-emoji U270F-gray.png
The page may be difficult to navigate, and some information on its subject might be incomplete and/or evolving rapidly.
If you have any questions or ideas, please add them as a new topic on the discussion page.

Presence

Overview

Presence is a proposed Cloud Service that tracks a Firefox OS device's Internet connectivity status as online, offline or unavailable by the device's Firefox Account. A Firefox OS Web App may request permission on behalf of its publisher to read status. Once approved, the publisher may poll the Presence service and, once the device is back online, push messages to the Web App.

See #Architecture Overview for more details.

Project Contacts

Principal Point of Contact - Tarek Ziade tziade@mozilla.com


Team

Cloud Services

  • Tarek Ziade tziade@mozilla.com
  • Ben Bangert bbangert@mozilla.com
  • Robert Lord rlord@mozilla.com
  • Firefox Account Engineer - TBD

Firefox OS

  • Fabrice Desré fabrice@mozilla.com

Presence on other Mobile Platforms

Presence on iOS

In iOS >= 7.x, applications that want to provide a presence feature can keep a socket opened in the background even if the application is not running anymore in the foreground.

The feature is called setKeepAliveTimeout (https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplication_Class/Reference/Reference.html#//apple_ref/occ/instm/UIApplication/setKeepAliveTimeout:handler:) and will give the app the ability to register a handler that will be called periodically to check on the socket connection. Only approved VOIP apps are allowed by Apple to always keep a socket alive and not be terminated. Apple is very discerning about which apps get to use this functionality.

The handler has a limited time to do it (max 10 seconds) but this is enough to handle presence for the user by interacting with a server.

The Apple Push Notification Service https://en.wikipedia.org/wiki/Apple_Push_Notification_Service is also often used by applications to keep a connection opened on a server to receive push notifications. That's comparable to the Simple Push service Mozilla has added in Firefox OS.

Therefore, building an application with device-level presence on an iOS device is doable but requires the publisher to maintain one or several connections per user opened all the time and very few applications qualify for VOIP status.

Presence on Android

Like iOS, Android provides features to run some services in the background, see http://developer.android.com/guide/components/services.html

However, the service can be killed when the memory becomes low, and if TCP/IP is used it can be hard to have a reliable service.

Google also provides a "Google Cloud Messaging" (GCM) service - http://developer.android.com/google/gcm/index.html That provides similar features than Simple Push, to push notifications to users.

There's also a new feature called GCM Cloud Connection Server - (CSS) http://developer.android.com/google/gcm/ccs.html - that allows applications to communicate with the device via XMPP and on the client side "Intent Services". The app and the devices interact with CSS, which relays the messages back and forth.

There's a full example on that page, of a Python server interacting with the GCM service to interact with users.

The architecture is quite similar to what we want to build with Mozilla Presence since GCM acts as an intermediary between the app server and the device.

However, CSS is a neutral messaging relay and does not keep track of users online status. It sends back and forth what the server and the device have pushed in the pipe.

So it's still up to the app to leverage this service to keep track of connected devices to get device-level presence.

if we decide not to build presence, maybe we would just need to build that relay to make sure we offer FFOS apps the ability to implement presence the right way, like what Google provides on Android

XXX stuff to dig: can we use CSS with BOSH or with websockets

Goals

Phone UI for users to:

  • see at a glance and manage what applications they granted presence access to.
  • see lively notifications and act on them or ignore them.
  • manage how much idling is considered to be 'online' vs. 'away' vs. 'offline'
  • set custom status updates

Mozilla Cloud Services run system that:

  • allows a user to authorize an AppService access to the users presence
  • sends notifications to the users device that they can act on
  • sends user presence updates to authorized AppServices

Note: Lively notifications are different than SimplePush style Notifications in that they can require immediate action else they'll become stale, like a missed phone call.

The project will be a success if an application registered with Mozilla Cloud Services is able to reach out to users that are "online" (active on their phone or desktop but with the app not running) via Mozilla Presence.

Use Cases

See Detailed Use Cases.

Requirements

  • List of requirements

Get Involved

Documents so far

Services Presence Etherpad

Identity Presence Etherpad

Presence Meeting Wiki

Meetings

We try to meet every Thursday at 10:00 Pacific Time

For mozilla employees, we meet in the "Services" vidyo room, and use IRC channel #presence-wg (irc.mozilla.org)

For participants outside of mozilla, you can call into the meeting using the following numbers:

  • Phone (US/Intl): 650 903 0800 x92 Conf: 98616#
  • Phone (Toronto): 416 848 3114 x92 Conf: 98616#
  • Phone (US): 800 707 2533 (pin 369) Conf: 98616#

Please mute yourself with '* 1' upon joining to prevent needless noise and feedback. You can unmute yourself with '* 1' again to speak.

Meeting Notes

https://etherpad.mozilla.org/presence-meeting-20140311

Services/Roadmaps/Presence/Meetings/notes_20131014

Services/Roadmaps/Presence/Meetings/notes_20131031

https://etherpad.mozilla.org/presence-2013-11-26

Design

Points of Contact

Services Engineers:

  • Ben Bangert bbangert@mozilla.com
  • Tarek Ziadé tarek@mozilla.com

Architecture Overview

There are two levels of presence:

1/ app-level presence

  • online: you are connected in the app, and using it
  • offline: you are disconnected from the app

2/ device-level presence.

  • online : you are using your FXOS phone or your desktop browser
  • offline: you are not on your FXOS phone or your browser

Sometimes you might be online in 1/ or 2/ and not wishing other users to know about it. And you also might want to appear online for app B but not for app C.

1/ is solved by every application. they all have their ad-hoc system, their social graph, rosters, contacts, etc. Large social networks don't care as much about 2/ because they would prefer you to use *only* their application for talking to your friends. By solving 2/, we can enable non-dominant social/communication applications to get useful presence information they can act on.

Mozilla Presence acts as a trusted intermediary between the user's device (solving 2/) and the applications the user has allowed to see their presence, as well as a short-lived notification system for applications to engage available users.

PresenceOverview.jpg

Channel communication overview:

MPChannels.jpg

Terminology

AppDeveloper
A developer that creates applications which may or may not have server-backed resources.
AppService
An Internet-accessible server that an application talks to. For example, Facebook's locally installed application talks to Facebook's API server to get data. The Facebook API server in that case is the AppService as it acts as a service to the application.
Application
A website application that might run locally on a device with or without needing to talk to an AppService.
FxAID
A Firefox Accounts user ID.
Device Presence Channel
A channel of communications between a phone/browser device and Mozilla Presence that carries live notifications from Presence and presence data to Presence.
AppService Presence Channel
A channel of communication between Mozilla Presence and an AppService that carries presence updates for users sharing their presence with the AppService and live notifications from the AppService to be delivered to a PUID.
LiveNotification
A live notification is an alert requiring a response within a set period of time (5 seconds up to several minutes) before its considered 'missed' and stored on the device separately to indicate it can no longer be acknowledged. A response is considered acknowledgement and switches the user to the appropriate application to act on the LiveNotification.
Presence
For our purposes the definition of presence definined by XMPP also applies, but in our case 'contacts' happen to be AppServices that the presence is broadcast to. See http://xmpp.org/rfcs/rfc6121.html#presence-fundamentals
PUID
A Presence Unique Identifier. Every AppService authorized by a user to see presence updates will be assigned a PUID that it should store and associate with the user (who may or may not be logged into the application).

API Reference/Documentation

The Presence service has several functions:

  1. Device Channel to Mozilla Presence - let a user update her online status and set a custom status message
  2. Applications registration - let a developer register an application
  3. Applications permissions - let a user manage applications access to their presence
  4. Status updates - let an application receive status updates
  5. Live Notifications - let an application send a live notification and a user receive it.

1. Device Channel to Mozilla Presence

Mozilla Presence provides a secured web socket endpoint at wss://presence.services.mozilla.com/presence for devices to connect to.

The user may connect to the socket using a valid FxA (which will entail a BrowserID Assertion per FxaSSO), and send status updates.

The data must be sent in JSON and is based on a simple protocol where a first request must be made to create a new session. Each subsequent request is a status update. The server or the user can disconnect from the socket at any time and for any reason. In that case the session is lost and a new session must be initiated.

Session Request

Example of a session request:

   {'type': 'connect',
    'application_ids': [421, 492, 9592, 391],
    'assertion': 'valid persona assertion'}

where:

  • assertion is a valid persona assertion
  • type is the type of request. in that case "connect"
  • application_ids is the list of applications IDs presence updates should be sent to.

The application_ids field is used because Mozilla Presence does not retain a list of applications authorized to see updates. This data is kept only on the phone. As a result, the device must indicate what application ID's presence data should be sent to when connecting.

The server validates the assertion by sending it to a persona/fxaccount verifier, and if valid, creates a unique session id and sends it back to the cient.

Example:

  {'result': true, 'session_id': '61539351-1f02-4b62-a136-205000ece41a'}

In case there's an issue, like an invalid assertion, the server will send back a request with a result flag set to false, an errno field with an error code (to be documented) - and an error message in the reason field.

Example:

  {'result': false, 'errno': 34, 'reason': 'Invalid assertion'}


Status Update Request

Once the session is set, the client can send status updates.

Example:

   {'type': 'status',
    'session_id': '61539351-1f02-4b62-a136-205000ece41a'
    'status': 'online'}

where:

  • session_id the session ID
  • type is the type of request. in that case "status"
  • status the presence status. The value must be one of "online", "offline", "unavailable".

In case the device wants to send a status update to a specific subset of applications, it can use the 'application_ids' key on a status update request, it will override the value set on a visibility call, just for that call.

Example:

   {'type': 'status',
    'session_id': '61539351-1f02-4b62-a136-205000ece41a'
    'application_ids': [421, 391],
    'status': 'offline'}

For every status request received, the server sends back an ACK message.

Example:

  {'result': true}

In case of an error, the server will send back an extra 'errno' field with an error code (codes to be documented) and an optional 'reason' message.

Example:

  {'result': false, 'errno': 34, 'reason': 'Assertion expired'}

The error codes have to be documented, but in case the errno value is a negative value, the session is lost and the client has to recreate a new one.

The user can send as many updates as it wants, but the server can ask it to slow down with a specific error code (codes to be documented)

The server or the user can disconnect from the socket at any time and for any reason. The number of socket connections is limited to one connection per device and per email.

2. Applications registration

An App developer can register a new application into Mozilla Presence

An application is defined by:

  • a domain
  • an email
  • a name
  • a description

Registering a new application is done in 3 steps

  1. validation of the domain ownership
  2. attribution of a unique application ID
  3. activation of presence notifications

Domain Ownership Validation

Mozilla Presence provides a web page at https://presence.mozilla.com/myapps where an application developer can connect by logging in with her persona account.

Once logged in, the developer can fill a form with a domain, name and description of the application to register.

Mozilla Presence generates a unique key of 1024 characters, the developer needs to place in this URL: http://<domain>/__presence in a plain/text file that can be reached pubicly.

Once the key is placed, the developer can hit a Verify button. Mozilla Presence will then visit http://<domain>/__presence to verify that the domain is owned by the developer.

Application ID

Once the domain has been verified, Mozilla Presence generates a unique id for the application, and displays an entry point the developer will need to visit to get status updates.

The entry point is in the form of ws://<node>.presence.mozilla.com/<appid> and is a web socket the developer's application may connect to, in order to receive status updates.


Activation of presence notifications

To activate the status update stream, the app developer needs to visit https://presence.mozilla.com/myapps and click on the Activate button located besides the application name (a developer may have several apps.)

By clicking on Activate, an API key is generated for the application and displayed besides the application. An API key is a string of 1024 chars.

This API key has to be used by the application in order to get status updates.

Getting status updates is done by connecting to the websocket located at ws://<node>.presence.mozilla.com/<appid> with the API key.

Example:

 {'key': 'e3b0c44298fc1c149afbf4c8....996fb92427ae41e4649b934ca495991b7852b855'}

Once connected, the application will receive status updated as they happen, in the form of a list. Each element is composed of an uid and a status.

Example:

 [{'UID': 2123131, 'status': 'online'},
  {'UID': 12345, 'status': 'offline'}
 ]

Where UID is a user identifier as described in the next section.

3. Applications permissions

Granting presence access requires user interaction to indicate to Mozilla Presence that the user wants an AppService to see their presence information. In the event that the user might have multiple identities or profiles on a single AppService, a user-meaningful string should be included in the authorization request to Mozilla Presence.

Here's what a users interaction with an application to grant it presence might look like: WPPhoneOverview.jpg

The following steps occur in this flow:

  1. User clicks Authorize button
  2. User acknowledges the AppService they're granting and allows it
  3. User is redirected back to the AppService

Technical Details

The page URL the Authorize buttons posts to is:

https://<node>.presence.mozilla.com/<appid>/grant?redirect=<url>&id=<userstring>

Where <node> and <appid> are values known by the registered application, <url> is the url to redirect back to, and <userstring> is the user-meaningful string indicating that should usually be their login name (or something short and meaningful to distinguish multiple identities on a single AppService if applicable).

In the example above, the user Marge happens to be logged into BeerChat as 'Fred', so this identifier is attached during authorization so that when Marge manages her Presence she can see that she appears online as Fred to BeerChat.

The user is expected to already be signed into their Firefox Account in this example, otherwise they will need to first login to Prsence before seeing the authorization page.

Authorizing the AppService performs a POST on https://<node>.presence.mozilla.com/<appid> containing the redirect url and the answer.

If user has accepted, Mozilla Presence generates a unique ID (PUID) to identify the user in the context of the application.

The user then is redirected back to <url> with an encoded PUID in a <Presence-UID> header.

The application is responsible to store the PUID and associate it with the user.

The redirect flow looks like this: WPAuthInteraction.jpg

5. Status updates

When Mozilla Presence gets a status update from someone, it looks up all the registered applications and sends to the one that are activated to see the updates.

Since statuses are fetched via a web socket at ws://<node>.presence.mozilla.com/<appid>, each application gets its own messaging queue that is dequeued when the application is connected via the web socket. A status message is dropped from the queue if not consumed within an hour.

6. Live notifications

Live notifications are a way for applications to reach out online users that are not active in the application. It can be used to give the opportunity to the user to react when something is happening in the application.

Examples:

  • ChatRoom: Your nick was used in a message sent to the room.
  • ChatRoom: Someone wants you to join the room.


AppService sends a notifications to Mozilla Presence via a POST request :

  POST https://<node>.presence.mozilla.com/<appid>/notification
  
  [{'UID': 'userid',
   'message': '<message>',
   'action': '<url>'},
   ...
  ]

AppService can send notifications by batches.

Details:

  • userid: the user ID provided by the presence system.
  • message: a message to display to the user. Limited to 512 chars.
  • action: an action that will happen on the device if the user agrees - it can be an url to visit or an application to run. Limited to 512 chars.

Mozilla Presence pushes the message into a FIFO queue. There's one queue per user id + app id combination, and its size is limited to 100 items. When the queue is full, the oldest item is dropped before the new item is added. For each item, it appends in the mapping the appid value.

Once the message is stored, the service sends back an ack message to AppService, with the current size of the queue:

  {'result': 'OK',
   'queue_size': <size>}

Receiving the ack is a guarantee that the message was stored on the server, but is not a guarantee that it was delivered to the user.

If the user is connected to Mozilla Presence via the Presence daemon, it gets all the items from the queue and the queue is purged.

The Presence daemon on the device is responsible to dispatch the messages to the different applications:

  • on desktop, it displays a notification with the url contained in the action for the user to click
  • on mobile, it displays a notification with a link to run the app XXX

The application has no feedback on whether a notification was seen by the user.

FAQ

To help people get up to speed faster and prevent backtracking, commonly asked questions by those getting involved are listed here with an answer.

Is this going to use XMPP?

The presence channel to AppServices will have an XMPP option. It's useful to remember that Mozilla Presence is in very early stages at this moment. Worrying about the exact implementation is a detail that we're not addressing yet as we build some prototypes to test ideas out and prove the overall concept is worthwhile.

Shouldn't Mozilla have a way for me to see my contacts online?

Nowadays, peoples' personal connections are spread across multiple online services (Facebook, Google+, Skype, etc). These services usually already have done the work of ensuring both people want to see each other's presence and have ways to facilitate a conversation. All they need is a way to be aware of a users presence when their app might be closed or suspended (on a phone). By serving as the underlying plumbing notifying AppService's when users are online, Mozilla Presence avoids having to try and change users expectations about where their 'friends' are and can facilitate new social interaction applications that need presence data.

Platform Requirements

What are the things this needs (OS, language, databases, etc.)?

XXX explain here how simple push is running on the different platforms - Firefox OS : built-in, what about Desktop ? a separate service that wakes up Firefox ?

Libraries Required

List of external project dependencies. (Stuff that's not pulled in via the installation script)

Code Repository

Repository: https://github.com/mozilla-services/presence

Diagrams: https://github.com/mozilla-services/presence-graffles

Release Schedule

Prototype

Server-side implementation:

  • Allows AppServices to send LiveNotifications
  • Sends AppServices presence stanzas
  • Holds WebSocket connection to devices
  • Sends LiveNotifications to devices
  • Allows a device when connecting to toggle what AppServices should have presence stanzas relayed

Client-side implementation:

  • Settings screen to manage
    • Applications that can use Presence (On/Off toggles)
    • Online - Away - Offline sliders to set how much idle is away vs. offline
    • Custom status message
    • Custom away message (if additional info should accompany it)
  • LiveNotifications pop-up with Accept/Dismiss button
  • Background service that sends pings, accepts LiveNotifications

Production V.1

Everything in the Prototype, designed for scale, in addition:

  • Possibly a QUIC-derived UDP-based device-presence channel
  • XMPP interface for AppServices <-> Presence
  • FxA Integration for device user (Requires https://wiki.mozilla.org/Identity/Firefox_Accounts/SSO)
  • Developer Registration page to acquire Presence Application ID, linked to from the Developer page in Marketplace

QA

Points of Contact

Engineer - Name contact@info

Test Framework

Security and Privacy

Fill out the security & privacy bug template: https://bugzilla.mozilla.org/form.moz-project-review (https://wiki.mozilla.org/Websites/Kick-Off_Form)

For security reviews, there's: https://wiki.mozilla.org/Security/ReviewProcess

Points of Contact

Questionnaire Answers

1.1 Goal of Feature

2. Potential Threat Vectors and Mitigation Points

Review Status

Bugzilla Tracking # - see https://wiki.mozilla.org/Security/Reviews

Issues and Resolutions

Operations

Points of Contact

Deployment Architecture

Bugzilla Tracking # -

Escalation Paths

Lifespan Support Plans

Logging and Metrics

Points of Contact

Tracking Element Definitions

Data Retention Plans

Dashboard URL

Customer Support

Points of Contact

Sumo Tags

Review Meeting