Event rules dispatch to an action when a matching event occurs, such as sending a webhook request or running a script. Plugins can register their own action types to extend the list of actions an event rule can perform, by subclassing NetBox's EventRuleAction class.
from django.utils.translation import gettext_lazy as _
from netbox.event_rules import EventRuleAction
from .models import Ticket
class OpenTicketAction(EventRuleAction):
slug = 'my_plugin.open_ticket'
label = _('Open ticket')
description = _('Open a ticket in the external ticketing system')
object_model = Ticket
object_required = True
def enqueue(self, *, event_rule, event_context, action_object, action_data):
...
To register one or more event rule actions with NetBox, define a list named event_rule_actions at the end of this file:
event_rule_actions = [OpenTicketAction]
!!! tip
The path to the list of event rule actions can be modified by setting `event_rule_actions` in the PluginConfig instance.
A dotted namespace prefix (e.g. my_plugin.open_ticket) is strongly recommended for slug to avoid collisions with other plugins or with action types added to NetBox core in the future.
slug must begin with a lowercase letter, and may contain only letters, digits, underscores, and dot-separated segments thereafter. Hyphens are not allowed, even though they're common in plugin/package names -- use an underscore instead, e.g. my_plugin.open_ticket as in the example above. register_event_rule_action() raises ImproperlyConfigured immediately for a slug outside this pattern, rather than allowing it to fail later during GraphQL schema assembly.
slug/label are only required at registration time, not at class definition, so an intermediate base class shared by several concrete actions may leave them unset.
!!! warning "Actions must be stateless"
Registration instantiates the class once, and that single instance serves every event rule, request, and background worker thread for the lifetime of the process. Do not stash per-event data on `self` in `enqueue()` or `validate()` -- concurrent dispatches would race over it. Everything an action needs is passed in as an argument.
If an action operates against a specific object (e.g. a webhook targets a Webhook instance, and a script targets a Script instance), set object_model to the relevant model class. NetBox uses this to render the object-selection field on the event rule form and to validate the selected object's type. object_required defaults to False (matching object_model's default of None); set it to True alongside object_model if the target object must always be selected. (Setting object_required without an object_model raises ImproperlyConfigured at registration, as it could never be satisfied.) Override get_object_queryset() to customize which objects are eligible for selection (e.g. to filter or further restrict the queryset).
The object-selection field is labeled with object_model's verbose name; set object_label to override it.
If an action leaves object_model as None, event rules using it must not specify a target object: supplying one is rejected as a validation error rather than being silently stored.
To support resolving a target object from a CSV value during bulk import of event rules, override resolve_import_object(). Raise django.core.exceptions.ObjectDoesNotExist (or a subclass) if the supplied value doesn't resolve to an object. If this method is not overridden, event rules using this action type cannot be targeted at an object via bulk import.
An event rule's action_type is stored as a plain string, and is not validated against the set of currently-registered actions at the database level. This means an event rule can reference an action type provided by a plugin that is later uninstalled or disabled, without the row being deleted or corrupted. While its action type is unavailable:
action_is_available is exposed as a read-only field via the REST API, and as a filter (?action_is_available=false), so affected event rules can be found in bulk.action_type is changed to a currently-registered value.Reinstalling the plugin (and thereby re-registering the action type) automatically restores the event rule to working order, with no need to re-save it.
::: netbox.event_rules.EventRuleAction