Webhook
  • 24 Jul 2024
  • 3 Minutes to read
  • Contributors
  • Dark
    Light
  • PDF

Webhook

  • Dark
    Light
  • PDF

Article summary

Webhook Nodes are Nodes that allow you to receive JSON-based webhooks using the HTTP(S) POST method.

The root path (/) MUST be used for the POST.

Allowed Content-Type values:

  • application/json
  • Any MIME type ending in +json. For example, model/gltf+json, application/calendar+json, etc.

NOTE - The Message Type that you specify as the Send Message Type MUST be JSON compatible and SHOULD match the MIME type or be more generic (e.g. - echo.json or echo.text)

Allowed Content-Encoding values:

  • br - a lossless data compression algorithm developed by Google.
  • deflate - a lossless data compression algorithm that uses a combination of LZ77 and Huffman coding.
  • gzip -a lossless data compression algorithm based on deflate.

Note - gzip is the most common, br is the most compact.

Api Authenticator Function

To secure your Webhook Node you must supply an Python function. You may provide this Python function either directly in the Webhook Node (an inline function) or by specifying the name of a Api Authenticator Function in your Tenant's Function Library.

Api Authenticator functions are also allowed to have the async keyword prior to their definition.

Api Authenticator functions must conform to the following template:

def authenticator(*, context, request, **kwargs):
    from typing import TYPE_CHECKING, cast

    from fastapi import HTTPException
    from starlette.authentication import AuthCredentials, BaseUser, SimpleUser
    
    if TYPE_CHECKING:
        from echostream_function_context import Context
        from fastapi import Request

        context = cast(Context, context)
        request = cast(Request, request)

    # TODO - Perform authentication using the context and request here
    # You must either return None or return a tuple containing an AuthCredentials
    # and a subclass of BaseUser. These will be placed in the request.scope under "auth"
    # and "user", respectively. If you return None or a Base User that returns False
    # from is_authenticated, then the Request will be rejected with a 403.
    
    return AuthCredentials(), SimpleUser("foobar")

NOTE - you must not have any Python code outside of the single function def statement!!

Arguments

The arguments for your api authenticator functions are all keyword arguments. An explanation of the arguments are below:

ArgumentTypeDescription
contextobjectThe Context object providing execution environment information and helper objects and methods.
requestfastapi.RequestThe Request object providing all attributes of the request as received.
kwargsdictThis is present specifically to future-proof your function. If, in the future, EchoStream Webhook Nodes pass additional arguments to your api authenticator function, those additional arguments will not break the call to your function.

Return

Your processor function must return one of the following types; None, tuple[starlette.authentication.AuthCredentials, starlette.authentication.BaseUser].

  • None: The Webhook Node will accept any webhook from any sender.
  • tuple[starlette.authentication.AuthCredentials, starlette.authentication.BaseUser]: The Webhook Node will only accept the request if the BaseUser instance returns True from is_authenticated. Otherwise it will return a 403 to the client.

NOTE - if you return any type other than those specified, the Webhook Node will throw an exception and cease processing.

Exceptions

You may raise a fastapi.HTTPException from your api authenticator. The Webhook Node will reject the request and return a response to the client as dictated by the exception.

NOTE - raising HTTPException is a effective way to get granular in your response to the client.

Any other exception raised will result in a 500 return to the client.

Requirements

You can use any package available on PyPI that supports Python3.12 or higher in your Api Authenticator function.

Simply add the requirement to the requirements of your Webhook Node and it will be included in your Node. Thisis done using pip requirement specifiers.

For example, to include the most popular PostgreSQL database adapter for Python (psycopyg), you would put the following requirement in your Node's requirements:

  • For the latest release:
psycopg2
  • Pinning the release:
psycopg2 == 2.9.3
  • Ensuring a baseline release
psycopg2 >= 2.9.2

Then in your Api Authenticator function, you can use psycopg2 by importing it, as follows:

def authenticator(*, context, request, **kwargs):
    
    # Make SURE that you import INSIDE of the function!!
    import psycopg2

    ...

NOTE - All imports must occur inside your function definition to be recognized and executed by EchoStream!!


What's Next