1<meta name="doc-family" content="apps"> 2<h1>Google Cloud Messaging for Chrome</h1> 3 4<p class="note"> 5If you are looking for the new Google Cloud Messaging API, please click 6<a href="cloudMessagingV2">here</a>. 7</p> 8 9<p> 10Google Cloud Messaging for Chrome (GCM) is a service 11for signed-in Chrome users 12that helps developers send message data from servers 13to their Chrome apps and extensions. 14The service is intended to wake up an app or extension, 15and/or alert a user. 16For example, calendar updates could be pushed to users 17even when their calendaring app isn't open. 18</p> 19 20<p>This document describes how to set up and use GCM. 21For additional information see the reference documentation 22for the <a href="pushMessaging">pushMessaging Chrome API</a> and the 23<a href="gcm_server">GCM service</a>. 24To get help with GCM or to give us feedback, see <a href="#feedback">Feedback</a>. 25</p> 26 27<h2 id="one">How push messaging works</h2> 28 29<p> 30At a glance, push messaging works like this: 31</p> 32 33<ol> 34 <li>You upload your app or extension client to the Chrome Web Store.</li> 35 <li>A user installs your app or extension.</li> 36 <li>Your app or extension client requests the user's channel ID 37 and sends this ID to your server.</li> 38 <li>Your app or extension server sends a message 39 to the push messaging service.</li> 40 <li>The push messaging service routes the message 41 to all instances of Chrome where the user is signed in.</li> 42 <li>When the app or extension starts, 43 it needs to register a handler to receive the 44 $(ref:pushMessaging.onMessage) event.</li> 45 <li>When the message arrives on the client, 46 Chrome starts the app or extension, if it is not already running, 47 and calls the registered handler.</li> 48</ol> 49 50<p> 51Diving in a bit more, 52the Chrome Web Store assigns your newly published app 53or extension a unique app ID. 54When a user installs your app or extension, 55the client needs to call $(ref:pushMessaging.getChannelId). 56The push messaging service returns a channel ID to the client; 57this ID is specifically linked to your app ID and to the user. 58Whatever method your client uses to send the channel ID to the server, 59it must be secured (https, for instance). 60For example, 61the client could send an XHR request 62to a RESTful API on your server. 63</p> 64 65<p> 66As long as Chrome is running in the background or foreground, 67even if the extension or app is not running, 68it is woken up to deliver a message. 69For this to work, 70your app or extension must register a handler to receive the event, 71similar to how they’d register for launch events. 72</p> 73 74<p> 75Your app/extension server is responsible 76for sending a push message to the service. 77In all push message requests, 78your server must include the user's channel ID 79and a valid OAuth 2.0 access token: 80the access token authorizes use of the service and 81the channel ID identifies the user and app to receive the message. 82</p> 83 84<p> 85Any messages sent are delivered 86to all instances of that application installed 87in a Chrome profile signed in as that user. 88The most recent message sent on each subchannel is automatically queued 89for delivery to instances of Chrome which are not connected to the push 90messaging service at the time. If multiple messages are sent on one subchannel 91while Chrome is disconnected, then Chrome may only receive the last one sent 92when it reconnects. 93</p> 94 95<p> 96Subchannels can also be used to implement priority schemes. 97For example, 98if you had an instant messaging app, 99requests for a phone call or video chat can go through immediately, 100instead of waiting for all the backed up chat messages to be cleared. 101</p> 102 103<h2 id="checklist">To Do Checklist</h2> 104 105<p> 106Here's a quick checklist of what you need to do 107to use the push messaging service 108(the remainder of this doc covers the steps in detail): 109</p> 110 111<ol> 112 <li>Register your app or extension: 113 <ul> 114 <li>Create the client ID in the Google APIs Console.</li> 115 <li>Get the refresh token to set up authorization to use the service.</li> 116 </ul> 117 </li> 118 <li>Set up your app or extension to use the service: 119 <ul> 120 <li>Add the permission to the manifest.</li> 121 <li>Include a call to <code>getChannelId</code> 122 for any user who is to receive a message.</li> 123 <li>Register a handler to receive the 124 <code>onMessage</code> event.</li> 125 </ul> 126 </li> 127 <li>Publish your app in the Chrome Web Store. </li> 128 <li>Use refresh token to get a valid access token.</li> 129 <li>Send message to user.</li> 130</ol> 131 132<h2 id="two">Register app or extension</h2> 133 134<h3 id="clientid">Create client ID</h3> 135 136<p> 137Complete the following steps to create the client ID: 138</p> 139 140<ol> 141 <li>Login to the 142 <a href="https://code.google.com/apis/console/">Google APIs Console</a> 143 using the same Google Account that you will use to upload your app.</li> 144 <li> Create a new project by expanding the drop-down menu in the top-left corner 145 and selecting the <strong>Create...</strong> menu item.</li> 146 <li>Go to the "Services" navigation menu item and 147 turn on the <strong>Google Cloud Messaging for Chrome API</strong>.</li> 148 <li>Go to the "API Access" pane and click on the 149 <strong>Create an OAuth 2.0 client ID...</strong> blue button.</li> 150 <li>Enter the requested branding information, if needed</li> 151 <li>For “Application type” select “Web application”.</li> 152 <li>Click "more options" beside "Your site or hostname" 153 and under "Authorized Redirect URIs", enter the following URL: 154 <code>https://developers.google.com/oauthplayground</code>.</li> 155 <li>Click "Create client ID" button.</li> 156</ol> 157 158<p> 159The client ID and the client secret 160from this step are used in further steps. 161Be sure to keep the client ID and secret in a safe place, 162and don't expose them to outsiders. 163</p> 164 165<h3 id="refresh">Get refresh token</h3> 166 167<p> 168You need two types of OAuth 2.0 tokens to authorize 169each call to the push messaging service: 170the refresh token and the access token. 171The access token authorizes each call to the service; 172however, this token expires after about an hour. 173The refresh token is used 174to 'refresh' the access token over time. 175These tokens are scoped to only send messages on behalf 176of your application or extension and nothing else. 177</p> 178 179<p> 180To get the refresh token and initial access token: 181</p> 182 183<ol> 184 <li>Open an Incognito window in Chrome; 185 this ensures that you are logged into the correct Google Account. 186 If you only have one Google Account, 187 you don't need to use an incognito window.</li> 188 <li>Go to the 189 <a href="https://developers.google.com/oauthplayground/">OAuth 2.0 Playground</a>.</li> 190 <li>Click the <img src="{{static}}/images/gearsicon.png" width="29" height="23" align="middle"/> 191 <strong>OAuth 2.0 Configuration</strong> button in the top right corner.</li> 192 <li>Check the box "Use your own OAuth credentials", 193 enter the client ID and client secret, and click "Close".</li> 194 <li>In the "Step 1" section, enter the scope 195 <code>https://www.googleapis.com/auth/gcm_for_chrome</code> into the 196 "Input your own scopes" text box and click "Authorize APIs" button.</li> 197 <li>Assuming you are in Incognito mode, 198 you should be redirected to the Google log in page. 199 Login with the same Google Account that you will use to upload your app or extension 200 to the Chrome Web Store.</li> 201 <li>After successful log in, you are redirected to a page to authorize the scopes. 202 Click "Allow access" button, redirecting you back to the OAuth 2.0 playground.</li> 203 <li>In "Step 2", click "Exchange authorization code for tokens" button.</li> 204</ol> 205 206<p> 207The refresh token never expires until you explicitly revoke access. 208You need to record and embed the refresh token in the app or extension server side. 209</p> 210 211<p class="caution"> 212<b>Be careful:</b> 213The refresh token should not be shown to anyone outside your organization; 214it should never be exposed on the client. 215If anyone gets your refresh token, 216they could potentially send messages as your server. 217</p> 218 219<h2 id="three">Set up app or extension</h2> 220 221<h3 id="manifest">Add permission to manifest</h3> 222 223<p> 224To use the push messaging service, 225you must declare the <code>pushMessaging</code> 226permission in <code>manifest.json</code>: 227</p> 228 229<pre data-filename="manifest.json"> 230"permissions": [ 231 "pushMessaging", 232 ] 233</pre> 234 235<h3 id="channelid">Get channel ID</h3> 236 237<p> 238Similar to an email address, 239the channel ID is used to identify and send messages 240to a specific user of your app or extension. 241Your app or extension needs to send this value 242to its application server so that the server 243can trigger push messages back. 244To get the user's channel ID, 245call $(ref:pushMessaging.getChannelId). 246Use the callback function 247to send the channel ID back to your app or extension. 248</p> 249 250<pre> 251chrome.pushMessaging.getChannelId(boolean interactive, function ChannelIdCallback) 252</pre> 253 254<p> 255When the <code>interactive</code> flag is set to true, 256the user is asked to log in if they haven't already done so 257with a warning dialog that looks something like this: 258"You must log into Chrome for the Calendar extension to receive push messages. 259Log in now?" 260</p> 261 262<p> 263To provide your users with a better experience, 264the interactive flag should be set to false the first time 265your app or extension calls <code>getChannelId</code>. 266Otherwise users will see the sign-in dialog 267with no context, 268even before they start your app or extension. 269If the first call fails because the user is not logged in, 270then <code>getChannelId</code> can be called again 271with the flag set to true. 272You should provide a context dialog 273before the second call is made. 274</p> 275 276<h3 id="registerPush">Register message event handler</h3> 277 278<p> 279Whenever Chrome receives a pushed message for an application/extension, 280it delivers the push message to the app or extension client. 281Your app or extension must register a handler to receive the event 282whenever the app or extension starts up, 283similar to how they’d register for launch events. 284This gets added to the <code>background.js</code>, for example: 285</p> 286 287<pre> 288function setupPush() { 289 chrome.pushMessaging.onMessage.addListener(messageCallback); 290} 291</pre> 292 293<p> 294The app or extension need not be running when the message arrives; 295the handler can be registered after the message arrives. 296</p> 297 298<h2 id="store">Publish your app</h2> 299 300{{^is_apps}} 301<p> 302To use the push messaging service, 303you must publish your extension in the 304<a href="https://developers.google.com/chrome/web-store/docs/get_started_simple">Chrome Web Store</a>. 305</p> 306{{/is_apps}} 307 308{{?is_apps}} 309<p> 310To use the push messaging service, 311you must publish your app in the 312<a href="https://developers.google.com/chrome/web-store/docs/get_started_simple">Chrome Web Store</a>. 313</p> 314{{/is_apps}} 315 316<h2 id="five">Send messages</h2> 317 318<h3 id="access">Get new access token</h3> 319 320<p> 321You need a valid access token to push messages 322to your app or extension. 323To obtain a new access token, 324make an <code>HTTPS POST</code> 325that includes your client ID and refresh token. 326<a href="https://developers.google.com/accounts/docs/OAuth2WebServer">Using OAuth 2.0 for 327 Web Server Applications</a> 328describes this in greater detail. 329A sample request would like something like this: 330</p> 331 332<pre> 333POST /o/oauth2/token HTTP/1.1 334Host: accounts.google.com 335Content-Type: application/x-www-form-urlencoded 336 337client_id=291796959215.apps.googleusercontent.com& 338client_secret=0bKUtXN6ykk7Mj1lQxoBZ2mh& 339refresh_token=1%wMfyZvGcCxMSNEX4iTRdE0H1_Yt0wvImBz_iCuXF-UM& 340grant_type=refresh_token 341</pre> 342 343<p> 344A response from such a request is shown below: 345</p> 346 347<pre> 348{ 349 "access_token":"1/fFBGRNJru1FQd44AzqT3Zg", 350 "expires_in":3920, 351 "token_type":"Bearer" 352} 353</pre> 354 355<p class="note"> 356<b>Reminder:</b> 357You should cache the access token for use 358until it expires. 359There is a rate limit on how often you can ask for access tokens. 360You may find yourself locked out of sending messages for awhile 361if you get a new access token every time you send a push message. 362</p> 363 364<h3 id="message">Send message to user</h3> 365 366<p> 367Send a <code>POST</code> body that includes the channel ID and subchannel ID 368along with the message payload to the API endpoint 369<code>https://www.googleapis.com/gcm_for_chrome/v1/messages</code>. 370Here's what a sample HTTP call would look like: 371</p> 372 373<pre> 374POST /gcm_for_chrome/v1/messages 375Host: www.googleapis.com 376Content-Type: application/json 377Authorization: Bearer 1/fFBGRNJru1FQd44AzqT3Zg 378 379{ 380 "channelId": "08144192009958038014/aaaaaaaaaabbbbbbbbbbcccccccccc", 381 "subchannelId": "0", 382 "payload": "Thanks for installing my app!" 383} 384</pre> 385 386<p> 387Messages can be coalesced. 388If you send multiple messages on subchannel 1, for instance, 389you may only see the last message and its payload. 390Also, payloads can sometimes be dropped; 391treat a payload as an optimization. 392You can always go back to the server to check 393for the contents of previous messages and 394to get data if the payload is not present. 395</p> 396 397<p>Here's a simple example that shows a push message 398as a text notification when it arrives: 399</p> 400 401<pre> 402function showPushMessage(message) { 403 var notification = window.webkitNotifications.createNotification( 404 '', 'New notification', message.payload + " [" + message.subchannelId + "]"); 405 notification.show(); 406} 407</pre> 408 409<p> 410You need to add the "notifications" permission 411to <code>manifest.json</code> 412to use text notifications 413(see <a href="desktop_notifications">Desktop Notifications</a>): 414</p> 415 416<pre data-filename="manifest.json"> 417"permissions": [ 418 "pushMessaging", 419 "notifications" 420 ] 421</pre> 422 423<h2 id="six">Error reference</h2> 424 425<p> 426Push messaging error codes indicate whether the push request was accepted or rejected. 427Rejection reasons include sender errors (for example, malformed message), 428permission errors (for example, revoked push messaging token), 429and operational errors (for example, push messaging service is currently down). 430</p> 431 432<p> 433Here's a brief summary of the push messaging errors: 434</p> 435 436<ul> 437 <li>Channel ID is invalid.</li> 438 <li>Subchannel is invalid (four subchannels available; 439 subchannel value must be 0, 1, 2, or 3).</li> 440 <li>Payload is too long (must be 256 bytes or less).</li> 441 <li>Daily message quota exceeded (10,000 message requests allowed per day).</li> 442 <li>Google Account calling the push messaging service does not own the app or extension.</li> 443 <li>An internal error has occurred. 444 This indicates something went wrong on the Google server side 445 (for example, some backend not working 446 or errors in the HTTP post such as a missing access token).</li> 447</ul> 448 449<h2 id="test">Testing</h2> 450 451<h3 id="test-local">Testing locally</h3> 452 453<p> 454To test push messaging locally: 455</p> 456 457<ol> 458 <li><a href="packaging">Package</a> a test version of 459 your app or extension on the Extensions management page 460 (chrome://extensions). 461 Your app or extension doesn't need to be running; it just needs 462 to be installed.</li> 463 464 <li>Get the channel ID at install time using 465 {{?is_apps}}$(ref:app.runtime.onLaunched).{{/is_apps}} 466 {{^is_apps}}$(ref:runtime.onInstalled).{{/is_apps}}</li> 467 468 <li>Use that channel ID on the server to send a test 469 push message through the system. 470 If all goes well, 471 your app or extension should start 472 and you should receive the test push message. 473 </li> 474</ol> 475 476<h3 id="test-cloud">Testing in the cloud</h3> 477 478<p>To test push messaging in the cloud, you must first make sure that the 479app or extension you are testing passes an ownership check. 480The Push Messaging server checks that the ID of an app or extension 481that calls the pushMessaging API matches the ID of the app or extension 482in the Chrome Web Store. This ownership check is designed to prevent people 483from sending messages to your app or extension without your permission. 484If your app or extension attempts to use the pushMessaging API and 485the ownership check fails, it will receive 486HTTP status code 500 (Internal Server Error). 487</p> 488 489<p> 490One circumstance in which the ownership check commonly fails is when you are 491developing an app and you run the app without uploading it and re-downloading 492it from the Chrome Web Store. In this situation your app may not have a 493<a href="manifest/key">key</a> field in its manifest.json file. 494The <code>key</code> field gives an app its Chrome Web Store ID 495(a 32 character alphabetic code, such as "bafimiidcfafikaonocgmmcpbbhfjjik"). 496If you run a version of your app without a key, the app will use a 497randomly generated ID that will not match the app's ID in the Chrome Web Store. 498For example, if you upload your app to the Chrome Web Store from the directory 499original_app_dir, then download the app and unpack it to downloaded_app_dir, 500and then run the exact same app as an unpacked extension from original_app_dir, 501the manifest.json file of the app in original_app_dir would not have 502the downloaded key, and the app's ID would appear to be different than 503the ID of the downloaded app. 504</p> 505 506<p> 507To test push messaging in the cloud: 508</p> 509 510<ol> 511 <li>Publish your app or extension to the Chrome Web Store.</li> 512 513 <li>Determine the Chrome Web Store ID of your app or extension. 514 The Chrome Web Store ID is in the URL of any dashboard 515 or Chrome Web Store page that's dedicated to your app or extension. 516 For example, the URL 517 <code>https://chrome.google.com/extensions/detail/aaaaaaaaaabbbbbbbbbbcccccccccc?hl=en</code> 518 has the ID <code>aaaaaaaaaabbbbbbbbbbcccccccccc</code>.</li> 519 520 521 <li>Install your app or extension from the Chrome Web Store.</li> 522 523 <li>Get the key from the installed app or extension: 524 525 <ol style="list-style-type: lower-alpha;"> 526 <li>Go to your 527 <a href="http://www.chromium.org/user-experience/user-data-directory">user data directory</a>. 528 </li> 529 530 <li>Look in the file <code>Default/Extensions/<<i>ID</i>>/<<i>versionString</i>>/manifest.json</code>. 531 </li> 532 533 <li>Copy the key field.</li> 534 </ol> 535 </li> 536 537 <li>Paste the key field into manifest.json in 538 the test version of your app or extension.</li> 539 540 <li>Install a test version of your app or extension on the 541 Extensions management page (chrome://extensions).</li> 542</ol> 543 544<p> 545Each time you reload your app or extension for testing, 546you need to check that the key is present in the manifest file. 547And anytime you wish to update the published version in the Chrome Web Store, 548you need to remove the key because the Store does not currently allow manifests 549with keys. 550</p> 551 552<h2 id="feedback">Feedback</h2> 553 554<p>You can provide feedback about Google Cloud Messaging 555and the pushMessaging API through the Google Group 556<a target="_blank" href="https://groups.google.com/forum/#!forum/gcm-for-chrome-feedback">GCM for Chrome feedback</a>. 557Use this group to ask for help, file bug reports, and request features.</p> 558