[Yandex Cloud documentation](../../../index.md) > [Monium](../../index.md) > Alerts > Step-by-step guides > Creating a webhook that calls an external API

# Webhook using Cloud Functions

To automate processing of incidents and other events in your cloud, Monium.Metrics supports invoking functions in Cloud Functions. This section provides an example of a webhook configured to send POST requests when an alert triggers. This means you can use alerts to call external API methods. You can also use [escalations](create-escalation.md) to invoke functions in Cloud Functions.

To send POST requests when an alert triggers:

1. Deploy the service for POST request processing with the following attributes:

   * `https://my.url/route/for/alarm`: URL to process a request when the alert gets the `Alarm` status.
   * `https://my.url/route/for/ok`: URL to process a request when the alert gets the `Ok` status.
   * `my_secret_token`: Token or token file for call authorization.

    You can test the function without deploying the POST request processing service. In this case, when sending a request, the function call logs will display a message saying the specified URL is unavailable.

1. [Create a service account](#reate-sa) to invoke your function.
1. [Create a function](#create-function) sending POST requests when the alert gets the `Alarm` or `Ok` status.
1. [Create a channel](#create-alert) that will invoke the function.
1. [Create an alert](#create-alert) that will send notifications to the channel with your function.
1. [Test the function](#test-function).

## Creating a service account {#create-sa}

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), go to the folder containing the resources you need to track in Monium.Metrics.
  1. Navigate to **Identity and Access Management**.
  1. Click **Create service account**.
  1. Enter a name for the service account, e.g., `sa-alert-webhook`.
  1. Add the `functions.functionInvoker` and `functions.viewer` roles.
  1. Click **Create**.

{% endlist %}

## Creating a function {#create-function}

{% list tabs group=instructions %}

- Management console {#console}

  1. Navigate to **Cloud Functions**.
  1. Click **Create function**.
  1. Name the function, e.g., `alert-webhook`.
  1. Click **Create**.
  1. Create a [function version](../../../functions/concepts/function.md#version):
     1. Select the **Python** runtime environment, disable the **Add files with code examples** option, and click **Continue**.
     1. Choose the **Code editor** method.
      1. Click **Create file** and specify a file name, e.g., `index`.
      1. Enter the function code by specifying the URL for processing POST requests and the token:
    
            ```python
            import json
            import requests

            WEBHOOK_ALARM_URL = "https://my.url/route/for/alarm"
            WEBHOOK_OK_URL = "https://my.url/route/for/ok"
            WEBHOOK_AUTH_TOKEN = "my_secret_token"

            def webhook(url, alert_id):
                headers_ = {
                    "Authorization": f"OAuth {WEBHOOK_AUTH_TOKEN}",
                    "Content-type": "application/json"
                }
                try:
                    response = requests.post(url, headers = headers_, json = { "alert_id" : alert_id })
                    if response.ok:
                        return { "status": "OK", "url": url, "response": json.dumps(response.json)}
                    else:
                        return { "status": "ERROR", "url": url, "code": response.status_code, "error": response.text}
                except Exception as e:
                    return { "status": "EXCEPTION", "url": url, "error": e}
                

            def handler(event, context):
                alert = event # For convenience, save the event to the alert variable.
                required_attributes = ["alertId", "alertStatus"] # Array of required input parameters in JSON format.
                
                # If the function input is not JSON or has missing required parameters, the function will not run.
                if not alert or not all(attr in alert for attr in required_attributes):
                    return
                
                result = None
                # If the function is invoked when the alert status is ALARM, send a request to WEBHOOK_ALARM_URL.
                # If the function is invoked when the alert status is OK, send a request to WEBHOOK_OK_URL.
                # Do not invoke the function in case of other alert statuses.
                if alert["alertStatus"] == "ALARM":
                    result = webhook(WEBHOOK_ALARM_URL, alert["alertId"])
                elif alert["alertStatus"] == "OK":
                    result = webhook(WEBHOOK_OK_URL, alert["alertId"])
                else:
                    pass
                
                if not result:
                    return

                # Output the call result to the log
                if result["status"] == "OK":
                    print(f"Successfully invoked {result['url']}. Response: {result['response']}")
                elif result["status"] == "ERROR":
                    print(f"ERROR invoking {result['url']}. Code {result['code']}, error message: {result['error']}")
                else:
                    print(f"{result['status']} when invoking {result['url']}. Error message: {result['error']}")
            ```
  
  1. Under **Parameters**, set the version parameters:
      * **Entry point**: `index.handler`.
      * **Service account**: `sa-alert-webhook`.
  1. Under **Additional settings**:
      1. Enable **Asynchronous call**.
      1. Select **Service account** `sa-alert-webhook`.
  1. Click **Save changes**.

{% endlist %}

## Creating a channel {#create-channel}

{% list tabs group=instructions %}

- Monium UI {#console}

  1. Go to **Monium** and select **Notification methods** on the left.
  1. At the top right, click **Create** → **Notification channel**.
  1. Enter a name for your notification channel, e.g., `channel-function`.
  1. From the **Method** list, select ![image](../../../_assets/console-icons/code.svg) **Cloud Functions**.
  1. Select `alert-webhook` from the **Cloud function** list.
  1. From the **Service account** list, select the `sa-alert-webhook` account.
  1. Click **Create**.

{% endlist %}

## Creating an alert {#create-alert}

{% list tabs group=instructions %}

- Monium UI {#console}

  1. Under **Monium**, select **Alerts**.
  1. Click **Create**.
  1. Enter a name for the alert, e.g., `alert-function`.
  1. Enter the [query](../../concepts/alerting/alert.md#queries) to use for selecting which metrics to track.
  1. Configure the [trigger conditions](../../concepts/alerting/alert.md#condition).
  1. Under **Notifications**, click **Edit** and then **Add**.
  1. Select `channel-function`.
  1. Click **Add**.
  1. Click **Create**.

{% endlist %}

## Testing function invocation {#test-function}

{% list tabs group=instructions %}

- Management console {#console}

  1. Navigate to **Cloud Functions**.
  1. Select the `alert-webhook` function.
  1. Select the **Testing** tab.
  1. As input data, enter:

      ```json
      {
        "alertId": "<alert_ID>",
        "alertName": "alert-function",
        "folderId": "<folder_ID>",
        "alertStatus": "OK"
      }
      ```

  1. Click **Run test**.
  1. In the function call logs, in the **Testing** or **Logs** tab, make sure the request was sent to this URL: `https://my.url/route/for/ok`.

{% endlist %}