Google Cloud Messaging for Chrome is a service for signed-in Chrome users that helps developers send message data from servers to their Chrome apps and extensions. The service is intended to wake-up an app or extension, and/or alert a user. For example, calendar updates could be pushed to users even when their calendaring app isn't open. The service handles all aspects of queueing and delivering messages.
At a glance, push messaging works like this:
Diving in a bit more, the Chrome Web Store assigns your newly published app or extension a unique app ID. When a user installs your app or extension, the client needs to call getChannelId. The push messaging service returns a channel ID to the client; this ID is specifically linked to your app ID and to the user. Whatever method your client uses to send the channel ID to the server, it must be secured (https, for instance). For example, the client could send an XHR request to a RESTful API on your server.
As long as Chrome is running in the background or foreground, even if the extension or app is not running, it will be woken up to deliver a message. For this to work, your app or extension must register a handler to receive the event, similar to how they’d register for launch events.
Your app/extension server is responsible for sending a push message to the service. In all push message requests, your server must include the user's channel ID and a valid OAuth2.0 access token: the access token authorizes use of the service and the channel ID identifies the user and app to receive the message.
Any messages sent will be delivered to all instances of that application installed in a Chrome profile signed in as that user. The most recent message sent on each subchannel will automatically be queued for delivery to instances of Chrome which are not connected to the push messaging service at the time. If multiple messages are sent on one subchannel while Chrome is disconnected, then Chrome may only receive the last one sent when it reconnects.
Subchannels can also be used to implement priority schemes. For example, if you had an instant messaging app, requests for a phone call or video chat can go through immediately, instead of waiting for all the backed up chat messages to be cleared.
Here's a quick checklist of what you need to do to use the push messaging service (the remainder of this doc covers the steps in detail):
getChannelId
for any user who will receive a message.onMessage event.Complete the following steps to create the client ID:
https://developers.google.com/oauthplayground.The client ID and the client secret from this step will be used in further steps. Be sure to keep the client ID and secret in a safe place, and don't expose them to outsiders.
You need two types of OAuth 2.0 tokens to authorize each call to the push messaging service: the refresh token and the access token. The access token authorizes each call to the service; however, this token expires after about an hour. The refresh token is used to 'refresh' the access token over time. These tokens are scoped to only send messages on behalf of your application or extension and nothing else.
To get the refresh token and initial access token:
https://www.googleapis.com/auth/chromewebstore into the
"Input your own scopes text box and click "Authorize APIs" button.The refresh token never expires until you explicitly revoke access. You need to record and embed the refresh token in the app or extension server side.
Be careful: The refresh token should not be shown to anyone but yourself; it should never be exposed on the client. If anyone gets your refresh token, they could potentially send messages as your server.
To use the push messaging service,
you must declare the pushMessaging
permission in manifest.json:
"permissions": [ "pushMessaging", ]
Similar to an email address, the channel ID is used to identify and send messages to a specific user of your app or extension. Your app or extension will need to send this value to its application server so that the server can trigger push messages back. To get the user's channel ID, call $ref:pushMessaging.getChannelId. Use the callback function to send the channel ID back to your app or extension.
chrome.pushMessaging.getChannelId(boolean interactive, function ChannelIdCallback)
When the interactive flag is set to true,
the user is asked to log in if they haven't already done so
with a warning dialog that looks something like this:
"You must log into Chrome for the Calendar extension to receive push messages.
Log in now?".
To provide your users with a better experience,
the interactive flag should be set to false the first time
your app or extension calls getChannelId.
Otherwise users will see the sign-in dialog
with no context,
even before they start your app or extension.
If the first call fails because the user is not logged in,
then getChannelId can be called again
with the flag set to true.
You should provide a context dialog
before the second call is made.
Whenever Chrome receives a pushed message for an application/extension,
it delivers the push message to the app or extension client.
Your app or extension must register a handler to receive the event
whenever the app or extension starts up,
similar to how they’d register for launch events.
This gets added to the background.js, for example:
function setupPush() {
chrome.pushMessaging.onMessage.addListener(messageCallback);
}
The app or extension need not be running when the message arrives; the handler can be registered after the message arrives.
To use the push messaging service, you must publish your extension in the Chrome Web Store. Your extension must also be whitelisted. To be added to the whitelist, please email gcm-for-chrome-whitelist@google.com with your extension ID and we will reply appropriately.
{{/is_apps}} {{?is_apps}}To use the push messaging service, you must publish your app in the Chrome Web Store. Your app must also be whitelisted. To be added to the whitelist, please email gcm-for-chrome-whitelist@google.com with your app ID and we will reply appropriately.
{{/is_apps}}You need a valid access token to push messages to your app or extension. To obtain a new access token, make an HTTPS POST that includes your client ID and refresh token. Using OAuth 2.0 for Web Server Applications describes this in greater detail. A sample request would like something like this:
POST /o/oauth2/token HTTP/1.1 Host: accounts.google.com/o/oauth2/token Content-Type: application/x-www-form-urlencoded client_id=291796959215.apps.googleusercontent.com& client_secret=0bKUtXN6ykk7Mj1lQxoBZ2mh& refresh_token=1%wMfyZvGcCxMSNEX4iTRdE0H1_Yt0wvImBz_iCuXF-UM& grant_type=refresh_token
A response from such a request is shown below:
{
"access_token":"1/fFBGRNJru1FQd44AzqT3Zg",
"expires_in":3920,
"token_type":"Bearer"
}
Reminder: You should cache the access token for use until it expires. There is a rate limit on how often you can ask for access tokens. You may find yourself locked out of sending messages for awhile if you get a new access token every time you send a push message.
Send a POST body that includes the channel ID and subchannel ID
along with the message payload to the API endpoint
https://www.googleapis.com/chromewebstore/v1.1/notifications.
Here's what a sample HTTP call would look like:
POST /chromewebstore/v1.1/notifications HTTP/1.1
Host: www.googleapis.com
Content-Type: application/json
Authorization: Bearer 1/fFBGRNJru1FQd44AzqT3Zg
{
'channelId': '08144192009958038014/aaaaaaaaaabbbbbbbbbbcccccccccc',
'subchannelId': '0',
'payload': 'Thanks for installing my app!'
}
Messages can be coalesced. If you send multiple messages on subchannel 1, for instance, you may only see the last message and its payload. Also, payloads can sometimes be dropped; treat a payload as an optimization. You can always go back to the server to check for the contents of previous messages and to get data if the payload is not present.
Here's a simple example that shows a push message as a text notification when it arrives:
function showPushMessage(payload, subChannel) {
var notification = window.webkitNotifications.createNotification(
payload + " [" + subChannel + "]");
notification.show();
}
You will need to add the "notifications" permission
to manifest.json
to use text notifications
(see Desktop Notifications):
"permissions": [ "pushMessaging", "notifications" ]
Push messaging error codes indicate whether the push request was accepted or rejected. Rejection reasons range from sender errors (for example, malformed message), permission errors (for example, revoked push messaging token), and operational errors (for example, push messaging service is currently down).
Here's a brief summary of the push messaging errors:
To test push messaging locally, package a test version of your app or extension on the Extensions management page (go to chrome://extensions in your browser). Your app or extension doesn't need to be running, just installed. You will need to get the channel ID at install time using $ref:app.runtime.onLaunched. Then, use that channel ID on the server to send a test push message through the system. All going well, your app or extension should start and you should receive the test push message.
To test push messaging works in the cloud,
you need to publish to the Chrome Web Store first.
Once you have published,
you need to copy the Chrome Web Store install key in the installed
manifest.json to your source manifest
and then install a test version of your app or extension
on the Extensions management page.
This ensures that you are testing the published version.
To get the key:
~/Library/Application\ Support/Google/Chrome/Default/Extensionsmanifest.json
(pico is a quick way to open the file).manifest.json and
paste it into your app's source manifest file.
The Chrome Web Store app ID is in the URL of any dashboard
or store page that's dedicated to your app or extension.
For example, the URL
https://chrome.google.com/extensions/detail/aaaaaaaaaabbbbbbbbbbcccccccccc?hl=en
has the app ID aaaaaaaaaabbbbbbbbbbcccccccccc.
Each time you reload your extension for testing, you will need to check that the key is present. And anytime you wish to update the published version in the Chrome Web Store, you will need to remove this key because the store doesn't allow manifests with this key.