用于 Chrome 浏览器的 Google 云消息服务(版本 1)

用于 Chrome 浏览器的 Google 云消息服务(版本 1)很快就要弃用,请使用新的 Google 云消息服务 API

Google Cloud Messaging for Chrome(GCM,用于 Chrome 浏览器的 Google 云消息服务)是为已登录的 Chrome 用户提供的一项服务,帮助开发者从服务器将消息数据发送至他们的 Chrome 应用与扩展程序,该服务是为了唤醒应用或扩展程序和/或提醒用户。例如,即使日历应用没有打开,日历更新也可以推送给用户。

该文档描述了设置和使用 GCM 的方法。如果您想了解更多内容,请阅读 pushMessaging Chrome API 以及 GCM 服务。如果需要帮助或者向我们提供反馈,请参见反馈

推送消息的工作方式

粗略地看,推送消息以如下方式工作:

  1. 您将您的应用或扩展程序客户端上传至 Chrome 网上应用店。
  2. 用户安装您的应用或扩展程序。
  3. 您的应用或扩展程序客户端请求用户的通道标识符,并将该标识符发送至您的服务器。
  4. 您的应用或扩展程序的服务器向消息推送服务发送消息。
  5. 消息推送服务将消息转发至用户已登录的所有 Chrome 浏览器实例。
  6. 当应用或扩展程序启动时,它需要注册一个处理函数接收 pushMessaging.onMessage 事件。
  7. 当消息到达客户端时,Chrome 浏览器启动应用或扩展程序(如果还没有运行的话),并调用注册的处理函数。

再深入一点来看,Chrome 网上应用店为您新发布的应用或扩展程序指派一个唯一的应用标识符。当用户安装您的应用或扩展程序时,客户端需要调用 pushMessaging.getChannelId。消息推送服务为客户端返回通道标识符,该标识符专门链接到您的应用程序标识符以及用户。无论您的客户端用什么方法向服务器发送通道标识符,都必须确保安全(例如使用 https)。例如,客户端可以向您服务器上的 RESTful API 发送一个 XHR 请求。

只要 Chrome 浏览器在后台或前台运行,即使扩展程序或应用还没有运行,它都会被唤醒以便传递消息。为了实现这一点,您的应用或扩展程序必须注册一个处理函数接收事件,就像为 launch 事件注册一样。

您的应用/扩展程序服务器负责向该服务发送推送消息。在所有推送消息请求中,您的服务器必须包含用户的通道标识符以及有效的 OAuth 2.0 访问令牌:访问令牌认证对服务的使用,通道标识符标志接收消息的用户和应用程序。

发送的所有新消息都会传递给以该用户的身份登录的 Chrome 用户配置文件下正在运行的该应用的所有实例,对于目前未连接到消息推送服务的 Chrome 浏览器实例,每一个子通道上发送的最新消息会放入队列以便之后传递。如果在 Chrome 浏览器未连接时发送了多个消息,Chrome 浏览器重新连接时可能只会收到发送的最后一条消息。

子通道也可以用来实现优先级架构。例如,如果您有一个即时通信应用程序,通话或视频聊天的请求可以直接通过,而不用等待所有保存的聊天消息清除。

待办事项清单

如下是您使用消息推送服务时需要做的事情的简明清单(该文档的剩余部分详细介绍所有步骤):

  1. 注册您的应用或扩展程序:
    • 在 Google APIs 控制台中创建客户端标识符。
    • 获取刷新令牌,设置认证来使用该服务。
  2. 配置您的应用或扩展程序使用该服务。
    • 向清单文件添加权限。
    • 为所有会接收消息的用户调用 getChannelId
    • 注册一个处理函数接收 onMessage 事件。
  3. 在 Chrome 网上应用店发布您的应用。
  4. 使用刷新令牌获取有效的访问令牌。
  5. 向用户发送消息。

注册应用或扩展程序

创建客户端标识符

完成下列步骤就能创建客户端标识符:

  1. 使用您用于上传应用的同一个 Google 帐户登录 Google APIs 控制台
  2. 展开左上角的下拉菜单并选择 Create... 菜单项,创建新的项目。
  3. 进入“Services”导航菜单项,并打开 Google Cloud Messaging for Chrome API
  4. 进入“API Access”窗格,并单击 Create an OAuth 2.0 client ID... 这一蓝色按钮。
  5. 如果需要的话,输入请求的商标信息。
  6. “Application type” 中选择 “Web Application”。
  7. 单击“Your site or hostname”旁边的“more options”,并在“Authorized Redirect URIs”下键入以下 URL:https://developers.google.com/oauthplayground
  8. 单击“Create client ID”按钮。

这一步中的客户端标识符以及客户端密钥将会在接下来的步骤中使用,确保将客户端标识符与密钥保存在安全的地方,不要将它们暴露给外界。

获取刷新令牌

您需要两种 OAuth 2.0 令牌认证消息推送服务的每一个调用:刷新令牌与访问令牌。访问令牌为该服务的每一个调用认证,然而该令牌大约在一小时后过期。刷新令牌用来在一段时间内“刷新”访问令牌。这些令牌仅限于代表您的应用程序或扩展程序发送消息,而不能做任何其他事情。

要获取刷新令牌以及初始的访问令牌:

  1. 在 Chrome 浏览器中打开隐身窗口,这样可以确保您以正确的 Google 帐户登录。如果您只有一个 Google 帐户,您不需要使用隐身窗口。
  2. 进入 OAuth 2.0 Playground
  3. 单击右上角的 OAuth 2.0 Configuration 按钮。
  4. 选中“Use your own OAuth credentials”,输入客户端标识符及客户端密钥,并单击“Close”。
  5. 在“Step 1”部分,在“Input your own scopes”文本框内输入区域 https://www.googleapis.com/auth/gcm_for_chrome,并单击“Authorize APIs”按钮。
  6. 假设您在隐身模式中,您将被重定向至 Google 登录页面,以您用来上传应用或扩展程序至 Chrome 网上应用店的同一个 Google 帐户登录。
  7. 登录成功后,您将被重定向至一个页面来认证区域,单击“Allow access”按钮,将您重定向回 OAuth 2.0 Playground。
  8. 在“Step 2”中,单击“Exchange authorization code for tokens”按钮。

刷新令牌永远不会过期,除非您显式地撤销访问权限。您需要记录并将刷新令牌嵌入到应用或扩展程序的服务端。

小心:刷新令牌不应该向您所在组织以外的任何人显示,永远不应该在客户端暴露。如果有人获得了您的刷新令牌,他们可能可以以您的服务器的身份发送消息。

配置应用或扩展程序

向清单文件添加权限

要使用消息推送服务,您必须在 manifest.json 中声明 pushMessaging 权限:

"permissions": [
  "pushMessaging",
 ]

获取通道标识符

与电子邮件地址类似,通道标识符用来标志您的应用或扩展程序的某个用户并向他们发送消息。您的应用或扩展程序需要将这一值发送给应用程序服务器,以便让服务器触发推送消息。要获取用户的通道标识符,请调用 pushMessaging.getChannelId,它使用回调函数向您的应用或扩展程序返回通道标识符:

chrome.pushMessaging.getChannelId(boolean interactive, function ChannelIdCallback)

interactive 标志设为 true 时,如果用户还没有登录则要求登录,并显示类似于这样的警告对话框:“您必须登录 Chrome 才能使用日历扩展程序接收推送消息。是否现在登录?”。

要为您的用户提供更好的体验,您的应用或扩展程序第一次调用 getChannelId 时 interactive 标志应该设为 false,否则用户会在启动您的应用或扩展程序之前就看到一个没有上下文的登录对话框。如果由于用户未登录,第一次调用失败,则可以再次调用 getChannelId,并将该标志设为 true。进行第二次调用前,您应该提供一个上下文对话框。

注册消息事件处理函数

每当 Chrome 浏览器接收到应用/扩展程序的推送消息时,它会将推送消息传递给应用或扩展程序的客户端。您的应用或扩展程序必须在每次启动时注册一个处理函数,接收该事件,就像为 launch 事件注册一样。这些应该添加到 background.js 中,例如:

function setupPush() {
  chrome.pushMessaging.onMessage.addListener(messageCallback);
}

当消息到达时,应用或扩展程序不一定正在运行,处理函数可以在消息到达后注册。

发布您的应用

要使用消息推送服务,您必须在 Chrome 网上应用店发布您的应用。

发送消息

获取新的访问令牌

您需要一个有效的访问令牌才能向您的应用或扩展程序推送消息。要获取新的访问令牌,发送一个 HTTPS POST 请求,包含您的客户端标识符以及刷新令牌,在 Web 服务器应用程序中使用 OAuth 2.0 中更详细地描述了这一过程。示例请求如下所示:

POST /o/oauth2/token HTTP/1.1
Host: accounts.google.com
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

这一请求的响应如下所示:

{
  "access_token":"1/fFBGRNJru1FQd44AzqT3Zg",
  "expires_in":3920,
  "token_type":"Bearer"
}

提醒:您应该缓存访问令牌以便使用,直到它过期。您请求访问令牌的频率是有限制的,如果您每次发送推送消息时都获取一个新的访问令牌,可能会被锁定一段时间而无法发送消息。

向用户发送消息

发送一个 POST 请求,包含通道标识符、子通道标识符以及消息内容至 API 端点 https://www.googleapis.com/gcm_for_chrome/v1/messages。如下是一个示例 HTTP 调用:

POST /gcm_for_chrome/v1/messages
Host: www.googleapis.com
Content-Type: application/json
Authorization: Bearer 1/fFBGRNJru1FQd44AzqT3Zg

{
  "channelId": "08144192009958038014/aaaaaaaaaabbbbbbbbbbcccccccccc",
  "subchannelId": "0",
  "payload": "Thanks for installing my app!"
}

消息可能会被合并。例如,如果您在子通道 1 上发送了多个消息,您可能只会看到最后一个消息及其内容。此外,内容有时候也可能被丢弃,将内容视为一项优化。您随时都可以返回服务器获取之前消息的内容,如果内容不存在的话获取数据。

如下是一个简单的例子,演示了一个推送消息,当它到达时显示文字通知:

function showPushMessage(message) {
  new Notification('新消息', {
    body: message.payload + " [" + message.subchannelId + "]"
  });
}

您需要在 manifest.json 中添加 "notifications" 权限才能使用文字通知(参见桌面通知):

"permissions": [
  "pushMessaging",
  "notifications"
 ]

错误参考

推送消息的错误码指示推送请求是否被接受或拒绝。拒绝的原因包括发送者错误(例如格式错误的消息)、权限错误(例如已撤销的推送消息令牌)及操作性错误(例如消息推送服务目前不可用)。

如下是推送消息错误的简要概括:

  • Channel ID is invalid.
    无效的通道标识符。
  • Subchannel is invalid (four subchannels available; subchannel value must be 0, 1, 2, or 3).
    子通道无效(有四个子通道可用,subchannel 值必须为 0、1、2 或 3)。
  • Payload is too long (must be 256 bytes or less).
    内容太长(不超过 256 字节)。
  • Daily message quota exceeded (10,000 message requests allowed per day).
    超过了每天的消息数目配额(每天允许 10 000 次消息请求)。
  • Google Account calling the push messaging service does not own the app or extension.
    调用消息推送服务的 Google 帐户不是应用或扩展程序的所有者。
  • An internal error has occurred. This indicates something went wrong on the Google server side (for example, some backend not working or errors in the HTTP post such as a missing access token).
    发生了内部错误,这意味着 Google 服务器端产生了问题(例如,某些后端无法正常工作或 HTTP POST 中的错误,如缺少访问令牌)。

测试

在本地测试

要想在本地测试消息推送:

  1. 在扩展程序管理页面(在您的浏览器中进入 chrome://extensions)上将您的应用或扩展程序的测试版本打包。您的应用或扩展程序不需要运行,只要已安装就可以。
  2. 使用 app.runtime.onLaunched 在安装的时候获取通道标识符。
  3. 在服务器上使用该通道标识符向系统发送一个测试的推送消息。如果一切正常,您的应用或扩展程序应该启动,您也应该收到测试的推送消息。

在云端测试

要测试工作在云端的推送消息,您必须首先确保您测试的应用或扩展程序通过所有者检查。推送消息服务器会检查调用 pushMessaging API 的应用或扩展程序的标识符是否匹配 Chrome 网上应用店中的应用或扩展程序标识符。这一所有者检查是为了防止他人未经您的同意就向您的应用或扩展程序发送消息。如果您的应用或扩展程序尝试使用 pushMessaging API,但是所有者检查失败了,它会收到 HTTP 状态码 500(内部服务器错误)。

所有者检查失败的一种常见情况是您正在开发一个应用,您没有将它上传并重新从 Chrome 网上应用店上下载下来运行。在这种情况下,您的应用的 manifest.json 文件中可能没有 key 字段。key 字段为应用指定了它的 Chrome 网上应用店标识符(一个包含 32 个字母的代码,例如“bafimiidcfafikaonocgmmcpbbhfjjik”)。如果您运行的应用没有 key,应用会使用随机生成的标识符,不会和 Chrome 网上应用店中的应用标识符匹配。例如,如果您从 original_app_dir 目录将您的应用上传至 Chrome 网上应用店,然后下载应用并解压缩至 downloaded_app_dir,然后以未打包扩展程序的方式从 original_app_dir 运行完全相同的应用,original_app_dir 中应用的 manifest.json 文件不会包含已下载的 key,应用的标识符也和已下载应用不同。

要想在云端测试推送消息:

  1. 将您的应用或扩展程序发布到 Chrome 网上应用店。
  2. 确定您的应用或扩展程序的 Chrome 网上引用店标识符。Chrome 网上应用店标识符在您的应用或扩展程序的任何信息中心或 Chrome 网上应用店网页的 URL 中。例如 URL https://chrome.google.com/extensions/detail/aaaaaaaaaabbbbbbbbbbcccccccccc?hl=en 包含标识符 aaaaaaaaaabbbbbbbbbbcccccccccc
  3. 从 Chrome 网上应用店安装您的应用或扩展程序。
  4. 从已安装的应用或扩展程序获取 key:
    1. 进入您的用户配置文件目录
    2. Default/Extensions/<ID>/<versionString>/manifest.json 文件中寻找。
    3. 复制 key 字段。
  5. 将 key 字段粘贴到您的应用或扩展程序测试版本的 manifest.json 中。
  6. 在扩展程序管理网页(chrome://extensions)中安装您的应用或扩展程序的测试版本。

每一次您重新加载您的扩展程序用于测试时,您都需要确保 key 存在。然而每当您希望更新 Chrome 网上应用店中的已发布版本时,您需要移除 key,因为应用店不允许包含 key 的清单文件。

反馈

您可以通过 GCM for Chrome feedback Google 网上论坛提供关于 Google 云消息以及 pushMessaging API 的反馈,使用该群组寻求帮助、报告问题或请求新特性。