Configure Service Webhooks [Deprecated]
Important
Third Party Services & Push Notifications Deprecation
Third party services and push notifications in App Services have been deprecated in favor of creating HTTP endpoints that use external dependencies in functions.
Webhooks have been renamed to HTTPS Endpoints with no change in behavior. You should migrate existing Webhooks.
Existing services will continue to work until September 30, 2025.
Because third party services and push notifications are now deprecated, they have been removed by default from the App Services UI. If you need to manage an existing third party service or push notification, you can add the configurations back to the UI by doing the following:
In the left navigation, under the Manage section, click App Settings.
Enable the toggle switch next to Temporarily Re-Enable 3rd Party Services, and then save your changes.
Overview
Some external services allow you to create incoming webhooks that external clients can call over HTTP. You can create webhooks for these services from the App Services UI or with App Services CLI. Select the tab below that corresponds to the method you want to use.
Procedure
Set Up a New Webhook
Incoming webhooks are scoped to individual services. You can create and manage a webhook from its associated service page in the App Services UI.
To create an incoming webhook:
Click Services in the left navigation menu.
Click the Service for which you want to add an incoming webhook.
Select the Incoming Webhooks tab for the service.
Click Add Incoming Webhook. App Services will redirect you to the Settings screen for the new webhook.
Configure User Authentication
Atlas Functions, including webhooks, always execute in the context of a specific application user or as the system user, which bypasses rules. To configure the webhook's execution user, specify the type of authentication that App Services should use for the webhook.
Authentication Type | Description | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
Application Authentication | This type of authentication configures a webhook to run in the context of an existing application user specified by each incoming request. Incoming requests must include the user's authentication provider credentials in either the request body or the request headers. The following examples demonstrate the field names and values for each supported authentication provider:
ImportantDo Not Use Both Headers and Body FieldsIf a request includes credentials in both the request headers and the request body, then App Services throws an error and does not execute the function. NoteApplication UsersYou can configure a webhook that uses application authentication to perform additional user-related work for each request:
| ||||||||||
System | This type of authentication configures a webhook to run as the
system user, which has full
access to MongoDB CRUD and Aggregation APIs and is
not affected by any rules, roles, or permissions. | ||||||||||
User ID | This type of authentication configures a webhook to always run
as a specific application user. | ||||||||||
Script | This type of authentication configures a webhook to run as a
specific application user determined by the result of a
custom function that you define. The
function must return a specific user's id string or can
specify a system user by returning { "runAsSystem": true } . |
Select the Webhook's HTTP Method
You can require that incoming requests use a specific HTTP
method or you can accept all HTTP methods and
handle each one individually in the webhook function by inspecting the
httpMethod
property on the context.request object, as in the following example function:
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: {} } }
Configure the Webhook Response
You can send a configurable HTTP Response to external services that call the webhook.
If you enable Respond With Result, the webhook will
respond to incoming requests with a basic HTTP 200 response that includes the webhook function
return value as its body
field. You can configure a custom HTTP
response from within the webhook function using the response
object that App Services automatically passes as the second argument.
Specify an Authorization Expression
You can dynamically authorize requests based on the contents of each request by defining a Can Evaluate expression. App Services evaluates the expression for every incoming request that the webhook receives. If you do not specify an expression then App Services automatically authorizes all authenticated incoming requests.
The expression can expand standard expression variables,
including the %%request
expansion.
Specify the Request Validation Method
To validate that a webhook request was sent from a trusted source, some external services require that incoming requests incorporate a secret string in one of several prescribed manners. Other services, like the HTTP service, allow you to optionally require request validation.
If your webhook requires request validation:
Select the request validation method.
Enter a Secret string to use in the request validation process.
Write the Webhook Function
Once you've configured the webhook, all that's left is to write the function that executes when someone calls the webhook. App Services automatically passes two objects as the webhook function's arguments:
Argument | Description |
---|---|
payload | An EJSON representation of the incoming request payload. The
contents of the payload document will vary depending on the
service and event that caused a webhook to fire. For a
description of the payload object for a specific service,
see that service's reference page. |
response | An HTTP response object that
configures the response to the client that called the
webhook. The object has methods that allow you to set the
response's headers, body, and status code. Calling any of these
methods overrides the default response behavior. |
You can use the following webhook function as a base for your own 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!" }; };
Note
If you want to debug a webhook function response from the function editor, you must manually provide the HTTP response object when you run the function.
exports( { body: "This document is the webhook payload" }, new HTTPResponse() )
Important
Check your CLI version
This procedure uses version 2 of the Realm CLI [deprecated].
If you have an older version of realm-cli
, upgrade to the latest
version or use the --help
flag for a list of commands supported
in your version.
Pull the Latest Version of Your App
To define an incoming webhook with realm-cli
, you need a local copy of your
application's configuration files.
To pull a local copy of the latest version of your app, run the following:
realm-cli pull --remote="<Your App ID>"
Tip
You can also download a copy of your application's configuration files from the Deploy > Export App screen in the App Services UI.
Add a Webhook Configuration File
Add an incoming webhook configuration file named config.json
to the new webhook directory.
The configuration file should have the following form:
{ "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>" } }
Configure User Authentication
Specify the type of authentication that App Services should use for the webhook. App Services supports the following webhook authentication methods:
Authentication Method | Description | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Application Authentication | This type of authentication configures a webhook to run in the context of an existing application user specified by each incoming request. Incoming requests must include the user's authentication provider credentials in either the request body or the request headers. To configure a webhook to use application authentication, set
the value of
ExampleThe following examples demonstrate the field names and values that incoming requests should include as body or header fields for each supported authentication provider:
ImportantDo Not Use Both Headers and Body FieldsIf a request includes credentials in both the request headers and the request body, then App Services throws an error and does not execute the function. | |||||||||||||||
System | This type of authentication configures a webhook to run as the system user, which has full access to MongoDB CRUD and Aggregation APIs and is not affected by any rules, roles, or permissions. To configure a webhook to run as a system user, do not set any other authentication fields:
| |||||||||||||||
User ID | This type of authentication configures a webhook to always run as a specific application user. To configure a webhook to always run as a specific user, set
| |||||||||||||||
Script | This type of authentication configures a webhook to run as a
specific application user determined based on the result of a
custom function that you define. The
function must return a specific user's To configure a webhook to run as a user determined by a
function, set
|
Specify the Webhook's HTTP Method
You can require that incoming requests use a specific HTTP
method or you can accept all HTTP methods and
handle each one individually in the webhook function by inspecting the
httpMethod
property on the context.request object, as in the following example function:
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: {} } }
To specify a webhook method, set the options.httpMethod
field to
the name of the method using all capital letters or "ANY"
.
{ "options": { "httpMethod": "POST" } }
Configure the Webhook Response
You can send a configurable HTTP Response to external services that call the
webhook. To configure the webhook to send a response to incoming
requests, set respond_result
to true
.
If you enable Respond With Result, the webhook will
respond to incoming requests with a basic HTTP 200 response that includes the webhook function
return value as its body
field. You can configure a custom HTTP
response from within the webhook function using the response
object that App Services automatically passes as the second argument.
Specify an Authorization Expression
You can dynamically authorize requests based on the contents of each request
by defining a Can Evaluate expression. App Services
evaluates the expression for every incoming request that the webhook receives.
The expression can expand standard expression variables,
including the %%request
expansion.
To define an authorization expression, set the value of the
can_evaluate
field to the expression. If you do not specify an
expression then App Services automatically authorizes all authenticated
incoming requests.
Example
The following expression only authorizes incoming requests if the sender's IP address is not included in the list of addresses.
{ "%%request.remoteIPAddress": { "$nin": [ "248.88.57.58", "19.241.23.116", "147.64.232.1" ] } }
Specify the Request Validation Method
To validate that a webhook request was sent from a trusted source, some external services require that incoming requests incorporate a secret string in one of several prescribed manners. Other services, like the HTTP service, allow you to optionally require request validation.
You can configure a webhook's request authorization method in the
options
document of the webhook configuration. App Services supports the
following request validation methods:
Method | Description | ||||
---|---|---|---|---|---|
No Additional Authorization | Incoming webhook requests do not require additional authorization.
| ||||
Verify Payload Signature | Incoming webhook requests must include a hashed signature of the request body and a secret value. For details, refer to Payload Signature Verification.
| ||||
Require Secret | Incoming webhook requests must include a secret string value as
the
|
Add the Webhook Function Source Code
Add a file named source.js
to the new webhook directory. The file
should contain a valid function that will execute when the webhook is
called.
App Services automatically passes two objects as the webhook function's arguments:
Argument | Description |
---|---|
payload | An EJSON representation of the incoming request payload. The
contents of the payload document will vary depending on the
service and event that caused a webhook to fire. For a
description of the payload object for a specific service,
see that service's reference page. |
response | An HTTP response object that
configures the response to the client that called the
webhook. The object has methods that allow you to set the
response's headers, body, and status code. Calling any of these
methods overrides the default response behavior. |
You can use the following webhook function as a base for your own 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!" }; };