Subscriptions are conduits through which events are routed from a source to a destination (endpoint) in Convoy. In addition to defining how to deliver events, subscriptions can be used to specify what retry strategy to use and how many times you should receive alerts for failing event attempts. They can also be used to trigger a circuit breaker when an endpoint is returning an error multiple times in a row. They represent the core of event routing for both Incoming and Outgoing events.

How Event Routing Works?

In an Incoming webhooks project, events are routed to a source; then we subscribe multiple endpoints to receive from that source. If no subscriptions are present, events are only saved in the Event Log for reference purposes. If subscriptions are present, we match the event against its subscription filters, only endpoints whose subscription filters match will receive events.

In an Outgoing webhooks project, events are routed specifically to an endpoint from the API. If the endpoint has no subscription, we create a subscription that will receive all events on-the-fly, create an event delivery and forward the event to your endpoint. When a subscription is present, we match the event first, against the event_type then against the subscription filters. If both are present, both have to be true, else events will not be sent to the endpoint.

Read on to understand how to create subscription filters.

Creating an Outgoing Subscription

An outgoing subscription can be created both from the API and the UI. The API allows for a full programmatic experience. Creating it from the UI looks like this:

create outgoing subscription

Creating an Incoming Subscription

Creating an Incoming subscription from the UI looks like this:

create incoming subscription

Where you do not want to inherit the subscription configuration details, use the buttons below to add more granular configuration to each subscription.

More configuration

Functions

Wehbook functions are used to mutate webhook payloads (event data) before they are dispatched based on a passed user-defined Javascript function.

Convoy uses goja to provide a JavaScript runtime environment in Go, providing full ECMAScript 5.1 support (including regex and strict mode). Most of the ECMAScript 6 spec is implemented, but this is a work in progress. To enhance the runtime, console support from goja_nodejs was also added.

Importing Modules

require support also exists but is currently disabled. Imports via require should in the future work similarly to NodeJS.

Caveats

Certain constraints exist while using functions:

  • Multiple functions can be written but only the transform function is called for the mutation to occur.
  • Only the first argument is used in the transform function and that is the payload data.
  • The transform method must return a value.

You can configure the function when creating or updating a subscription.

Create Webhook Function

Filters

Subscription filtering is used to decide what events an endpoint will receive based on the webhook event payload. The subscription filter is an enriched JSON syntax for both simple and complex filters (such as special logical and arithmetic operators $or, $gte, $eq).

Subscription filters can be configured from the subscriptions’ page:

subscription filter

The filters are configured in the Filter Schema editor and the event payload in the Event Payload editor to validate the schema.

Subscription filter

Simple filters

Simple filters directly match keys to values, and they can be nested. They can also match items in an array.

Direct object match

This filter is used to validate simple JSON webhook payloads.

object match filter
{
	"event_type": "created"
}

subscription filter modal

Nested object match

This filter is used to validate nested webhook payloads.

object match filter
{
	"event": {
		"type": "created"
	}
}

subscription filter modal

Array contains match

contains match
{
	"dish": {
		"ingredients": "rice"
	}
}

subscription filter modal

Complex filters

Complex filters contain more logic such as logical operators and special operators. Complex filters are employed to filter events using one or more conditions, e.g., $or logical operator filter.

$neq filter

This filter matches event which directly does not match the event type in the webhook payload.

filter
{
	"event": {
		"$neq": "created"
	}
}

$neq subscription filter

$or and $and filters

This filter is used to match multiple conditions defined in the schema.

filter
{
	"$or": [
		{
			"cities": "london"
		},
		{
			"type": "weekly"
		}
	]
}

filter
{
	"$and": [
		{
			"age": {
				"$gte": 10
			}
		},
		{
			"$or": [
				{
					"type": "weekly"
				},
				{
					"cities": "lagos"
				}
			]
		}
	]
}

$and filter

Array Contains filters

This filter is used to match keys where the value can be a range of values. It can be used in place of $or if you are comparing on the same field. The opposite of this operator $nin can be used to match keys where the value is not in a range of values.

filter
{
	"operation": {
		"$in": ["created", "deleted"]
	}
}

filter
{
	"operation": {
		"$nin": ["updated", "truncated"]
	}
}

$in filter

Arithmetic filters

These filters match events based on arithmetic operators. For example, the filter below will match all events where the age is greater than 1. The operators supported are $gt, $gte, $lt, $lte

filter
{
	"age": {
		"$gt": 1
	}
}

Array positional filters

These filters match events with payloads that are array either in the root or nested.

positional filters
{
	"$.venues.$.lagos": "lekki"
}

Array positional $. filter

Regex filters

These filters match events with payloads that match the supplied regex.

filters
{
	"event_type": {
		"$regex": "^es_[a-zA-Z]+$"
	}
}

Regex filter

NB: Convoy only supports filters with arrays nested up to 3 levels i.e. $.a.$.b.$.c.$.e will throw an error

Here’s a full list of the supported filters:

OperatorSupported TypeDescription
noneallMatch all
$.arrayMatch an array value
$gtenumberGreater than or equal to
$gtnumberGreater than
$ltnumberLess than
$ltenumberLess than or equal to
$eqnumber, object, string, boolEqual
$neqnumber, object, string, boolNot Equal
$inarraychecks if an array contains a value
$ninarraychecks if an array does not contain a value
$orarray of conditionsmatches an array of conditions
$andarray of conditionsmatches an array of conditions
$existarraychecks if a key exists
$regexstringchecks if the regex matches