Skip to content

Ticketing and On-call

FreeSDN raises alerts. These three turn them into work.

Plugin What it does Default floor
jira-tickets Opens a Jira issue, closes it when the alert clears high
servicenow-incidents Creates a ServiceNow incident, resolves it when the alert clears high
pagerduty-incidents Triggers a PagerDuty incident, resolves it when the alert clears critical

All three subscribe to alert.fired and alert.resolved, and all three default to dry_run: true so the first thing you see is the tickets they would have opened.

Why these are plugins and not integrations

Section titled “Why these are plugins and not integrations”

The Integrations page offers a webhook: a URL, a set of event types, and an HMAC secret. That is everything it has. There is no auth field, no custom headers and no payload templating, which is fine for anything that accepts an arbitrary JSON body - a generic endpoint, an n8n webhook trigger, a Make.com scenario - and structurally impossible for a vendor API that needs its own credentials.

There is nowhere to put a Jira token, so the request cannot even authenticate, never mind send the issue shape Jira expects. Integrations still lists all three types, now marked Needs a plugin and pointing here.

An alert rule that flaps publishes alert.fired every time it trips. One ticket per firing gives you forty identical tickets by morning, and the reliable outcome of that is somebody switching the integration off - after which nobody gets any tickets at all.

  • Jira and ServiceNow remember the alert id against the issue they opened. A repeat firing comments on the existing issue instead of filing a new one.
  • PagerDuty gets it for free: it deduplicates server-side on dedup_key, and the FreeSDN alert id is that key. So that plugin keeps no state at all, rather than a second source of truth that can drift out of step with theirs.

Plugins → Jira Tickets → Settings.

Setting Notes
jira_url https://your-org.atlassian.net, no trailing path
jira_email The account the token belongs to. Jira Cloud uses Basic auth with email + token, not the token alone
jira_api_token From id.atlassian.net → Security. Stored encrypted
project_key The prefix in NET-123, not the project name
issue_type Case-sensitive, and must exist in that project
resolve_transition Matched case-insensitively against the transitions your workflow offers

Saving checks two things: that the credentials work, and that the project is readable. Connecting with a token that cannot see the project files nothing, and finding that out from the first real alert is what this check exists to prevent.

Jira Cloud’s v3 API refuses a plain string for description - it wants Atlassian Document Format, and the failure is a 400 that does not say so. The plugin handles that.

Plugins → ServiceNow Incidents → Settings.

Give the integration user itil plus write on the incident table and nothing more. A personal admin account is the usual shortcut here and the usual regret.

ServiceNow has no severity. It models urgency and impact separately and derives priority from a matrix every instance tunes, so urgency_map is yours to set rather than ours to guess:

critical=1,high=2,medium=2,low=3,info=3

impact is a single fixed value because FreeSDN knows how bad the alert is, not how much of your business it affects.

An unknown close_code is refused by ServiceNow rather than defaulted. When that happens the incident is left open with a work note explaining why - an incident that silently stayed open is worse than one that says what stopped it closing.

Plugins → PagerDuty Incidents → Settings. You need the Integration Routing Key from the service you want paged (Service → Integrations → Events API v2). It is 32 characters, and it is a credential: anyone holding it can page your on-call.

The floor defaults to critical rather than high, because this one wakes people up and the cost of a page nobody needed is measured in trust.

Set events_url to https://events.eu.pagerduty.com/v2/enqueue for the EU region.

Every one starts in dry_run. Watch the log, confirm the tickets it reports are the ones you want, then turn it off:

Plugins -> <the plugin> -> Settings -> dry_run -> off -> Save settings

The severity floor is the other dial worth turning before you go live. A ticket queue that fills with informational noise stops being read, which costs more than the tickets it saves.

The pattern is on_event plus a severity floor plus a dedup key, and all three are readable end to end in registry/plugins/. One trap worth knowing if you copy from them:

except Exception as exc:
return False, f"{exc.__class__.__name__}: {exc}" # NOT type(exc).__name__

type is not in the plugin sandbox’s builtin allowlist. Calling it raises NameError from inside the except block, which replaces the real error with a confusing one - and in a settings validator it blanks the warning entirely, so an unreachable host reports nothing at all. See the SDK reference.

All product names, logos, and brands are property of their respective owners. FreeSDN is an independent project and is not affiliated with or endorsed by the vendors it integrates with. See Trademarks.