配置服务 Webhook [已弃用]
重要
第三方服务和推送通知弃用
App Services 中的第三方服务和推送通知已弃用,转而创建在函数中使用外部依赖项的 HTTP 端点。
Webhook 已重命名为 HTTPS 端点,行为没有发生变化。您应该迁移现有的 Webhook。
现有服务将继续运行到 9 月30 ,2025 。
由于第三方服务和推送通知现已弃用,因此,默认将其从 App Services 用户界面中删除。如果您需要管理现有的第三方服务或推送通知,可以执行以下操作以将配置重新添加到用户界面中:
在左侧导航栏中的 Manage(管理)部分下面,单击 App Settings(应用设置)。
启用 Temporarily Re-Enable 3rd Party Services(暂时重新启用第三方服务)旁边的切换开关,然后保存更改。
Overview
某些外部服务允许您创建外部客户端可通过 HTTP 调用的传入 webhook。您可以通过 App Services UI 或使用应用服务 CLI 为这些服务创建 Webhook。选择下面与您要使用的方法相对应的标签页。
步骤
设置新的 Webhook
传入的 Webhook 的范围仅限于单个服务。可以从 App Services UI 中的关联服务页面创建和管理 Webhook。
要创建传入 Webhook:
单击左侧导航菜单中的 Services(函数)。
单击要为其添加传入 Webhook 的服务。
选择该服务的 Incoming Webhooks 选项卡。
单击 Add Incoming Webhook。应用服务会重定向到新 Webhook 的 Settings 屏幕。
配置用户身份验证
Atlas Function(包括 Webhook)始终在特定应用程序用户的上下文中或作为系统用户执行,这会绕过规则。要配置 Webhook 的执行用户,请指定 App Services 应对 Webhook 使用的身份验证类型。
身份验证类型 | 说明 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
应用程序身份验证 | 这种类型的身份验证将 Webhook 配置为在每个传入请求指定的现有应用程序用户的上下文中运行。传入请求必须在请求正文或请求标头中包含用户的身份验证提供程序凭据。 以下示例演示了每个受支持的身份验证提供程序的字段名称和值:
重要不要同时使用标头和正文字段如果请求的请求标头和请求正文中均包含凭据,则 App Services 将引发错误并且不会执行该函数。 注意应用程序用户可以配置一个使用应用程序身份验证的 Webhook 来为每个请求执行其他与用户相关的工作:
| ||||||||||
记录 | 这种类型的身份验证将 Webhook 配置为以系统用户身份运行,该用户具有对 MongoDB CRUD 和聚合 API 的完全访问权限,并且不受任何规则、角色或权限的影响。 | ||||||||||
用户 ID | 这种类型的身份验证将 Webhook 配置为始终作为特定应用程序用户来运行。 | ||||||||||
脚本 | 这种类型的身份验证将 Webhook 配置为以特定应用程序用户的身份运行,该特定应用程序用户由您定义的自定义函数的结果确定。该函数必须返回特定用户的 id 字符串,或者可以通过返回 { "runAsSystem": true } 来指定系统用户。 |
选择 Webhook 的 HTTP 方法
您可以要求传入请求使用特定的 HTTP方法 您也可以接受所有HTTP方法,并通过检查上下文的 属性,在 Webhook 函数中单独处理每个方法httpMethod
。请求 对象,如以下示例函数所示:
exports = function(payload, response) { switch(context.request.httpMethod) { case "GET": { /* Handle GET requests */ } case "POST": { /* Handle POST requests */ } case "PUT": { /* Handle PUT requests */ } case "DELETE": { /* Handle DELETE requests */ } case "PATCH": { /* Handle PATCH requests */ } default: {} } }
编写 Webhook 函数
完成配置 Webhook 后,剩下的就是编写在有人调用 Webhook 时执行的函数。App Services 会自动传递两个对象作为 Webhook 函数的参数:
Argument | 说明 |
---|---|
payload | 传入请求有效负载的 EJSON 表示形式。有效负载文档的内容将根据导致触发 Webhook 的服务和事件而有所不同。有关特定服务的 payload 对象的说明,请参阅该服务的参考页。 |
response | 一个 HTTP 响应对象,用于配置对调用 Webhook 的客户端的响应。该对象包含的方法允许设置响应的标头、正文和状态代码。调用任何这些方法都会覆盖默认的响应行为。 |
可以使用以下 Webhook 函数作为自己的 Webhook 的基础:
exports = async function (payload, response) { // Convert the webhook body from BSON to an EJSON object const body = EJSON.parse(payload.body.text()); // Execute application logic, such as working with MongoDB if (body.someField) { const mdb = context.services.get("mongodb-atlas"); const requests = mdb.db("demo").collection("requests"); const { insertedId } = await requests.insertOne({ someField: body.someField, }); // Respond with an affirmative result response.setStatusCode(200); response.setBody(`Successfully saved "someField" with _id: ${insertedId}.`); } else { // Respond with a malformed request error response.setStatusCode(400); response.setBody(`Could not find "someField" in the webhook request body.`); } // This return value does nothing because we already modified the response object. // If you do not modify the response object and you enable *Respond with Result*, // App Services will include this return value as the response body. return { msg: "finished!" }; };
注意
如果要从函数编辑器调试 Webhook 函数响应,则必须在运行该函数时手动提供 HTTP 响应对象。
exports( { body: "This document is the webhook payload" }, new HTTPResponse() )
重要
检查 CLI 版本
此过程使用Realm 命令行界面(Realm CLI)的2版本 [已弃用]。 如果您使用的是旧版本的realm-cli
,请升级到最新版本或使用--help
标志来获取您的版本支持的命令列表。
添加 Webhook 配置文件
将名为config.json
的传入 Webhook 配置文件添加到新的 Webhook目录中。
配置文件应采用以下形式:
{ "name": "<Webhook Name>", "can_evaluate": { <JSON Expression> }, "run_as_authed_user": <Boolean>, "run_as_user_id": "<App Services User ID>", "run_as_user_id_script_source": "<Function Source Code>", "respond_result": <Boolean>, "fetch_custom_user_data": <Boolean>, "create_user_on_auth": <Boolean>, "options": { "httpMethod": "<HTTP Method>", "validationMethod": "<Webhook Validation Method>", "secret": "<Webhook Secret>" } }
配置用户身份验证
指定App Services应用于 Webhook 的身份验证类型。 App Services支持以下 Webhook身份验证方法:
身份验证方法 | 说明 | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
应用程序身份验证 | 这种类型的身份验证将 Webhook 配置为在每个传入请求指定的现有应用程序用户的上下文中运行。传入请求必须在请求正文或请求标头中包含用户的身份验证提供程序凭据。 要将 Webhook 配置为使用应用程序身份验证,请将
例子以下示例演示了传入请求应包含的字段名称和值,作为每个受支持的身份验证提供者的正文或标头字段:
重要不要同时使用标头和正文字段如果请求的请求标头和请求正文中均包含凭据,则 App Services 将引发错误并且不会执行该函数。 | |||||||||||||||
记录 | 这种类型的身份验证将 Webhook 配置为以系统用户身份运行,该用户具有对 MongoDB CRUD 和聚合 API 的完全访问权限,并且不受任何规则、角色或权限的影响。 要将 Webhook 配置为以系统用户身份运行,请不要设立任何其他身份验证字段:
| |||||||||||||||
用户 ID | 这种类型的身份验证将 Webhook 配置为始终作为特定应用程序用户来运行。 要将 Webhook 配置为始终以特定用户身份运行,请将
| |||||||||||||||
脚本 | 这种类型的身份验证将 Webhook 配置为根据您定义的自定义函数的结果确定的特定应用程序用户运行。 该函数必须返回特定用户的 要将 Webhook 配置为以由函数确定的用户身份运行,请将
|
指定 Webhook 的 HTTP 方法
您可以要求传入请求使用特定的 HTTP方法 您也可以接受所有HTTP方法,并通过检查上下文的 属性,在 Webhook 函数中单独处理每个方法httpMethod
。请求 对象,如以下示例函数所示:
exports = function(payload, response) { switch(context.request.httpMethod) { case "GET": { /* Handle GET requests */ } case "POST": { /* Handle POST requests */ } case "PUT": { /* Handle PUT requests */ } case "DELETE": { /* Handle DELETE requests */ } case "PATCH": { /* Handle PATCH requests */ } default: {} } }
要指定 Webhook 方法,请使用全大写字母或"ANY"
将options.httpMethod
字段设立为方法名称。
{ "options": { "httpMethod": "POST" } }
指定授权表达式
您可以通过定义Can Evaluate表达式,根据每个请求的内容动态授权请求。 App Services会对 Webhook 收到的每个传入请求的表达式求值。 表达式可以扩展标准表达式变量,包括%%request
扩展。
要定义授权表达式,请将can_evaluate
字段的值设立为表达式。 如果未指定表达式,则App Services会自动授权所有经过身份验证的传入请求。
例子
仅当发件人的IP解决未包含在地址列表中时,以下表达式才会授权传入请求。
{ "%%request.remoteIPAddress": { "$nin": [ "248.88.57.58", "19.241.23.116", "147.64.232.1" ] } }
指定请求验证方法
为了验证 Webhook 请求是否是从可信来源发送的,某些外部服务要求传入请求以几种规定方式之一包含密钥字符串。其他服务,例如 HTTP 服务,允许选择性地要求请求验证。
您可以在 Webhook 配置的options
文档中配置 Webhook 的请求授权方法。 App Services支持以下请求验证方法:
方法 | 说明 | ||||
---|---|---|---|---|---|
无需额外授权 | 传入的 Webhook 请求不需要额外授权。
| ||||
验证有效负载签名 | 传入的 Webhook 请求必须包含请求正文的哈希签名和密钥值。 有关详细信息,请参阅有效负载签名验证。
| ||||
需要密钥 | 传入的 Webhook 请求必须包含密钥string值作为 Webhook URL中的
|
添加 Webhook 函数源代码
将名为source.js
的文件添加到新的 Webhook目录中。 该文件应包含有效的函数,该函数将在调用 Webhook 时执行。
App Services 会自动传递两个对象作为 Webhook 函数的参数:
Argument | 说明 |
---|---|
payload | 传入请求有效负载的 EJSON 表示形式。有效负载文档的内容将根据导致触发 Webhook 的服务和事件而有所不同。有关特定服务的 payload 对象的说明,请参阅该服务的参考页。 |
response | 一个 HTTP 响应对象,用于配置对调用 Webhook 的客户端的响应。该对象包含的方法允许设置响应的标头、正文和状态代码。调用任何这些方法都会覆盖默认的响应行为。 |
可以使用以下 Webhook 函数作为自己的 Webhook 的基础:
exports = async function (payload, response) { // Convert the webhook body from BSON to an EJSON object const body = EJSON.parse(payload.body.text()); // Execute application logic, such as working with MongoDB if (body.someField) { const mdb = context.services.get("mongodb-atlas"); const requests = mdb.db("demo").collection("requests"); const { insertedId } = await requests.insertOne({ someField: body.someField, }); // Respond with an affirmative result response.setStatusCode(200); response.setBody(`Successfully saved "someField" with _id: ${insertedId}.`); } else { // Respond with a malformed request error response.setStatusCode(400); response.setBody(`Could not find "someField" in the webhook request body.`); } // This return value does nothing because we already modified the response object. // If you do not modify the response object and you enable *Respond with Result*, // App Services will include this return value as the response body. return { msg: "finished!" }; };