handlers.link_fact_sheet_by_subscription_handler

class LinkFactSheetBySubscriptionHandler(handlers.eventhandler.EventHandler):

Example use case: If an Application Owner is added or removed from an Application, this automation looks up the Organization of the subscribed user and links it as owning Organization (usageType: owner).

Generic logic: We configure a mapping of roles and usageTypes, like this:
"Application Owner": "owner", "Component Manager": "componentOwner", and also a means to identify the corresponding fact sheet: "user_field_source": "userProperty" or "lansweeper" or "entraID" (to be implemented) "user_field": "Department", "linked_fs_type": "Organization", "match_field": "shortName" "role_field": "usageType" The automation will then monitor all subscription events (added/removed/updated), look up the correct fact sheet, unlink any previously-linked fact sheets of this usage type and link all fact sheets that need to be linked, or update the usage type if the fact sheet is already linked.

To specify what happens if a user is unsubscribed, you can use the following options: "deletion_action": "delete_relation" or "delete_usage_type"

LinkFactSheetBySubscriptionHandler(config, **kwargs)
name = 'Link Fact Sheets by Subscription'
description = 'Looks up and links or unlinks a fact sheet whenever a user in a specific role is subscribed / unsubscribed.'
conditions = {'event_types': ['SubscriptionCreatedEvent', 'SubscriptionDeletedEvent', 'SubscriptionUpdatedEvent']}
supports_initial_sync = True
config_template = {'fs_types': ['Application', 'ITComponent', 'Interface'], 'role_mapping': {'Application': {'Application Owner': 'applicationOwnership', 'Component Manager': 'componentOwnership', '__ALL__': 'applicationAndComponentOwnership'}, 'ITComponent': {'Component Manager': 'owner'}, 'Interface': {'Interface Manager': 'owner'}}, 'user_field_source': 'lansweeper', 'user_field': 'department', 'linked_fs_type': 'Organization', 'linked_fs_relations': {'Application': 'relApplicationToOrganization', 'ITComponent': 'relITComponentToOrganization', 'Interface': 'relInterfaceToOrganization'}, 'match_field': 'shortName', 'role_field': 'usageType', 'deletion_action': 'delete_usage_type'}
def data_requirements(self):

Declare the exact fact-sheet data this handler needs, so the webhook event loop (process_event in workspace/views_module.py) can load a single lean FastFactSheet per event instead of the full fact sheet.

Return a dict: { "fields": [], "relations": [], "subscriptions": bool, # True if handle() reads fs["subscriptions"] "tags": bool, # True if handle() reads tags / has_tag() "documents": bool, "acls": bool, "completion": bool, # True if handle() reads fs["completion"] "base_fields": [], # optional; omit/None = full # default base field set. A list restricts the # base scalars to just those (id and type are # always loaded). Advanced opt-in for max speed. } Fields referenced by this handler's trigger are folded in automatically by the event loop (into "fields"), so only declare what handle() itself needs on top of them.

Return None (the default) to signal "requirements cannot be declared statically" - e.g. handlers that exec/eval config-supplied code. The event loop then loads the full fact sheet for that event, so correctness is always preserved. This is a standalone hook (deliberately not tied to the initial_sync_* hooks, which are slated to migrate onto it later).

def handle(self, event, fs, **kwargs):

Called automatically whenever a FactSheetUpdated event comes in via webhook.