Docs Menu
Docs Home
/ /
Atlas App Services
/ /

Configure Service Webhooks [Deprecated]

On this page

  • Overview
  • Procedure

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.

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.

1

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:

  1. Click Services in the left navigation menu.

  2. Click the Service for which you want to add an incoming webhook.

  3. Select the Incoming Webhooks tab for the service.

  4. Click Add Incoming Webhook. App Services will redirect you to the Settings screen for the new webhook.

2

Enter a unique, identifying name for the webhook in the Webhook Name field. This name must be distinct from any other webhooks that you've created for the service.

3

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:

{
"email": "<User's Email Address>",
"password": "<User's Password>"
}
{
"api-key": "<User's API Key>"
}
{
"jwtTokenString": "<User's JWT Token>"
}

Important

Do Not Use Both Headers and Body Fields

If 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.

Note

Application Users

You can configure a webhook that uses application authentication to perform additional user-related work for each request:

  • If you enable Fetch Custom User Data, App Services queries the requesting user's custom user data and, if it exists, exposes the data as an object on the context.user.custom_data property.

  • If you enable Create User Upon Authentication, App Services automatically creates a new user based on the provided user credentials if they don't match an already existing user. The authentication provider that corresponds to the credentials must be enabled at the time of the request to create a new user.

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 }.
The user authentication type input in the UI
click to enlarge
4

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: {}
}
}
The HTTP method dropdown input in the UI
5

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.

The respond with result toggle in the UI
click to enlarge
6

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.

The webhook's Can Evaluate JSON expression input in the UI
click to enlarge
7

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:

  1. Select the request validation method.

  2. Enter a Secret string to use in the request validation process.

The request validation secret input in the UI
click to enlarge
8

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()
)
9

You must save changes to your webhook before they take effect. To do so, click Save from either the Settings screen or the Function Editor.

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.

1

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.

2

Create a new subdirectory with the same name as the webhook in /http_endpoints/<service>/incoming_webhooks/:

mkdir -p http_endpoints/<service>/incoming_webhooks/<webhook name>
3

Add an incoming webhook configuration file named config.json to the new webhook directory.

The configuration file should have the following form:

http_endpoints/<Service Name>/incoming_webhooks/<Webhook Name>/config.json
{
"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>"
}
}
4

Enter a name for the webhook in the configuration file's name field. This name must be distinct from any other webhooks that you've created for the service.

{
"name": "<Unique Webhook Name>"
}
5

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 run_as_authed_user to true:

{
"run_as_authed_user": true,
"run_as_user_id": "",
"run_as_user_id_script_source": "",
}

Example

The following examples demonstrate the field names and values that incoming requests should include as body or header fields for each supported authentication provider:

{
"email": "<User's Email Address>",
"password": "<User's Password>"
}
{
"api-key": "<User's API Key>"
}
{
"jwtTokenString": "<User's JWT Token>"
}

Important

Do Not Use Both Headers and Body Fields

If 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:

{
"run_as_authed_user": false,
"run_as_user_id": "",
"run_as_user_id_script_source": "",
}
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 run_as_user_id to the user's id:

{
"run_as_authed_user": false,
"run_as_user_id": "<App Services User ID>",
"run_as_user_id_script_source": "",
}
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 id string or can specify a system user by returning { "runAsSystem": true}.

To configure a webhook to run as a user determined by a function, set run_as_user_id_script_source to the stringified function code:

{
"run_as_authed_user": false,
"run_as_user_id": "",
"run_as_user_id_script_source": "<Stringified Function>",
}
6

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"
}
}
7

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.

8

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"
]
}
}
9

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.

{
"validationMethod": "NO_VALIDATION"
}
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.

{
"validationMethod": "VERIFY_PAYLOAD",
"secret": "<Secret Value>"
}
Require Secret

Incoming webhook requests must include a secret string value as the secret query parameter in the webhook URL. For details, refer to Secret as a Query Parameter.

{
"validationMethod": "SECRET_AS_QUERY_PARAM",
"secret": "<Secret Value>"
}
10

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!" };
};
11

Once you've set the read preference for the cluster in config.json, you can push the config to your remote app. App Services CLI immediately deploys the update on push.

realm-cli push --remote="<Your App ID>"

Back

Configure Third-Party Services

On this page