Skip to content

Notifications ​

OpsMerge fires email notifications at several points during a ticket's lifecycle — to the client, to your team, to specific stakeholders. This article covers what fires when, and how to customise.

Where the editors live

Everything described here is configured under PSA → Workflows:

  • The built-in notifications are System-badged rules on the Workflows list — open one to enable it or tune when it fires.
  • What the emails say — system and custom alike — lives at PSA → Workflows → Email templates.
  • Custom "when X happens, do Y" automations: the same Workflows list.

See Workflows for the full rule-engine reference. The legacy paths (Settings → PSA → Notifications, Settings → PSA → Rules, and the old separate Notifications page) still redirect.

The default notifications ​

Out of the box, OpsMerge sends:

TriggerRecipientDefault behaviour
Ticket created (inbound email)SenderAuto-acknowledgement — "we've got your message, ticket #N"
Ticket created (manually, via portal)Ticket contactAcknowledgement with ticket details
Comment added (public)Ticket contactEmail with the comment body
Status changedTicket contact (optional)"Your ticket is now In Progress"
Ticket assignedAssignee"You've been assigned ticket #N"
Ticket resolvedTicket contact"Your ticket has been resolved"
Ticket reopenedAssignee"Ticket #N has been reopened"
Approaching SLA breachAssignee + managerInternal-only escalation
VIP ticket createdVIP escalation listInternal-only — see Tickets

Toggle each on the PSA → Workflows list — the built-in ones carry a System badge.

Customising templates ​

Each notification has a template — subject line + body. All of them, system and custom, live at PSA → Workflows → Email templates. The editor's Available variables panel lists every placeholder with click-to-copy.

The editor is a WYSIWYG (q-editor under the hood) that lets you write HTML emails without writing HTML. It supports:

  • Standard formatting (bold, italic, lists, links).
  • Variables — drop-in placeholders for ticket data ({{.ticket_subject}}, {{.requester_name}}, {{.ticket_ref}}, etc.). Templates use Go's text/template and html/template syntax (leading dot), not Handlebars. The variable names are flat — {{.ticket_subject}}, not {{.ticket.subject}}.
  • Conditional blocks — {{if eq .ticket_priority "urgent"}}...{{end}} blocks that only render when the condition is true.
  • Branding pulled from your Brand setup.

You can also edit the raw HTML if you want full control.

Common variables ​

  • {{.ticket_ref}} — the human-readable reference, e.g. "INC-1042" (per-tenant prefix)
  • {{.ticket_number}} — the short threading id (8 hex characters), used in the subject anchor — see below
  • {{.ticket_subject}} — subject line
  • {{.ticket_priority}} — low / medium / high / urgent
  • {{.ticket_status}} — current status
  • {{.ticket_url}} — link to the ticket in the app
  • {{.requester_name}} / {{.requester_email}} — the ticket's requester
  • {{.assignee_name}} / {{.assignee_email}} — the assigned agent
  • {{.comment_body}} / {{.comment_body_html}} — the comment text / HTML, for comment notifications
  • {{.comment_author_name}} — who posted the comment
  • {{.comment_author_job_title}} — the posting tech's job title, from their profile (empty when unset)
  • {{.comment_author_signature}} — the posting tech's reply signature, from My profile (renders as nothing when they haven't set one; see below)
  • {{.org_name}} — your business name, for body footers

Threading id vs display reference

{{.ticket_number}} and {{.ticket_ref}} are not the same thing, and it matters which you use where.

  • {{.ticket_number}} is an internal short id (the first 8 characters of the ticket's UUID). Its only job is to anchor email threading: the seeded subjects render it as [#{{.ticket_number}}], and the inbound mail handler re-threads replies by matching that token. Don't show it to clients as "your ticket number", and don't remove it from the subject.
  • {{.ticket_ref}} is the human reference (e.g. "INC-1042" — the prefix follows the ticket type, and is customisable per tenant). This is the one to put in body copy where you'd say "your ticket reference".

Tech reply signatures ​

Each staff user can set a personal ticket reply signature on their own profile (user menu → My profile). It's optional: a tech with no signature simply signs off with whatever your template says.

The signature lands in outgoing reply emails through the {{.comment_author_signature}} variable. The default Notify requester on public reply template places it between the reply body and the "Kind regards" footer; because it's just a variable, you control the position (or remove it entirely) by editing the template.

A few things worth knowing:

  • Empty renders as nothing. No placeholder text, no blank block. Templates degrade cleanly for techs without a signature.
  • It's HTML, and it's sanitised. Formatting and links survive; scripts and anything dodgy are stripped on save and again at send time.
  • It's per-tech, not per-template. The same signature follows the tech across every template that uses the variable. For a company-wide sign-off, put it directly in the template and pair it with {{.comment_author_name}} / {{.comment_author_job_title}} so the identity line always renders even when the personal signature is empty.
  • Canned responses can use it too. {{user.signature}} inserts it into the reply body itself when a canned response is rendered, useful if you want it visible in the composer rather than added at send time.

Auto-acknowledgement specifics ​

When a client emails you and a ticket is created, OpsMerge sends an automatic "got it" reply. This is non-optional in the sense that something gets sent (otherwise your client thinks the email went into a void) — but you can customise heavily.

The auto-ack uses:

  • RFC 3834 guards — sets Auto-Submitted: auto-replied and other headers so receiving mail systems don't bounce-loop on it.
  • Subject anchor with the threading id — the seeded subject is Re: {{.ticket_subject}} [#{{.ticket_number}}], so the recipient sees something like Re: Printer offline [#3f8a1c2d].
  • A "if you didn't expect this" note — for the case where the email was misrouted to your support address.

Don't disable this entirely. Mail loops happen when one auto-reply meets another auto-reply meets... infinite mail. The RFC 3834 headers prevent that. If you want the auto-ack body to say almost nothing, that's fine; just keep the headers.

Comment notifications ​

When you post a public comment on a ticket, OpsMerge sends it as an email to the ticket contact. The email:

  • From: your client-facing sending address (the connected mailbox the reply is sent from).
  • Reply-To: a unique per-ticket address (so client replies thread correctly).
  • Subject: Re: <original subject> [#<threading id>] — the seeded template is Re: {{.ticket_subject}} [#{{.ticket_number}}], and the [#…] anchor is what threads the client's reply back to the ticket.
  • Body: your comment + the template wrapper (signature, footer, etc.).

The template wraps the comment, so you don't have to repeat Hi {{.requester_name}}, ... Best, {{.org_name}} in every comment — the template does that automatically.

Internal notes don't notify clients ​

Internal notes (toggle "Internal" before posting) never email clients. They appear only in the ticket's internal timeline.

Internal notes can trigger internal-team notifications (e.g. @mention a colleague). Configure via the Notify assignee on comment System rule on the Workflows list.

Notification rules ​

For more bespoke notifications, set up rules.

PSA → Workflows → New workflow.

A rule has:

  • Trigger — what event. Seven choices: ticket.created, ticket.updated, ticket.commented, ticket.sla_warning, ticket.scheduled_stale, ticket.scheduled_customer_silence, ticket.scheduled_resolved_aging.
  • Conditions — a tree of AND/OR groups. Each leaf compares one ticket field (client, priority, status, requester, queue, subject, etc.) with an operator. Leave it empty and the rule matches every event of its trigger kind.
  • Actions — what to do. Thirteen choices including send_email, assign_to_user, set_status, set_priority, escalate_to_team, add_note, send_webhook, run_ai_action, and spawn_project_from_template.

Full reference plus worked examples, guards (cooldown / max-fires / business hours / throttle), and the audit drawer in Workflows.

Examples:

  • "When a Critical ticket is created for client Acme, email Bob and the on-call rotation".
  • "When a ticket has been Open for 3 days with no response, email the assignee's manager".
  • "When a portal user creates a ticket, send to support@your-msp instead of the default queue".

Frequency and digest ​

By default, every event sends an email immediately. To slow things down for a noisy notification, open the rule on the Workflows list and raise the Throttle (seconds) in its Email sending panel. A second send to the same address within the throttle window is dropped. "Max sends per ticket" caps lifetime fires per ticket, and the business-hours toggle holds sends to your working hours.

Most MSPs don't need to tune this. The defaults are conservative.

Email vs in-app ​

OpsMerge fires both:

  • Email goes to the recipient's address (or the ticket contact for client-facing notifications). Which emails fire is an organisation-level choice, made on the Workflows list as described above.
  • In-app lands in the notification bell in the top bar for your team, and on the phone of anyone using the mobile app. What reaches each person is their own choice, made on My profile (the account menu, top right) under Notifications.

The notification bell ​

The bell shows a count of what you have not read. Click it for the inbox:

  • Tabs: All, Unread, Tickets, Alerts and Other.
  • Click a notification to open the ticket (or alert, or timesheet) it is about. It is marked read on the way.
  • Mark all as read clears the tab you are looking at, so clearing Tickets never hides an alert you have not seen yet.
  • Show older pages back through the last 90 days.

Notifications arrive live. Anything that happened while you were logged out is waiting in the bell when you come back, and marking something read in one browser tab clears it in your others and in the desktop app.

What you can be notified about ​

NotificationWho gets itDefault
Assigned to meThe technician a ticket is assigned toOn
Replies on my ticketsAssignee and watchers, when anyone else commentsOn
Ticket closedAssignee and watchersOn
Every new ticketAnyone who opts inOff (opt-in)
Critical alertsAnyone who opts in, when a critical alert is raisedOff (opt-in)
MentionsThe person @mentioned on a ticketOn
Chat repliesThe technician who started a chat, when the end user repliesOn
Timesheet decisionsThe timesheet's owner, on approval or rejectionOn

Your own actions never notify you: assigning yourself a ticket, or replying on one you watch, is not news.

Choosing what reaches you ​

My profile > Notifications is one grid: a row per notification, a column for In-app (the bell) and a column for Push (the mobile app). Switch each off or on independently. Two extra switches sit underneath:

  • Show pop-up toasts turns the brief pop-up on arrival off while still filing everything in the bell. Useful on a shared screen.
  • Send push notifications to my phone is the master switch for the mobile app. Quiet hours for push (working days and hours, in your organisation's timezone) are set in the mobile app under Settings > Notification preferences (see the mobile app guide); the bell has no quiet hours because an unread row waits quietly.

Notifications marked Opt-in (every new ticket, critical alerts) are off until you switch them on. They are the noisy ones.

Testing templates ​

In the template editor, Preview renders the template against a mock ticket so you can see what it looks like before saving.

If you want to test against a real ticket, Send test to me sends the rendered template to your own email address, populated with a recent ticket's data.

Don't test on a real client

The temptation: edit a template, "send to me" to check, edit a real ticket and post a public comment to check the real-world rendering. The comment goes to the client. Use the in-editor Preview, or send to yourself only.

Common patterns ​

"Auto-ack should look like our brand, not OpsMerge default" ​

Edit the System-badged auto-acknowledge template at PSA → Workflows → Email templates. Replace the default copy. Use your brand voice. Keep the variables that matter ({{.ticket_number}} in the subject anchor, {{.ticket_url}}, and {{.ticket_ref}} if you show a reference in the body).

"Different auto-ack per client" ​

Notification rules. Trigger = ticket created. Condition = client = X. Action = send specific template.

"Suppress all comment notifications for a specific client" ​

Either at the contact level (set "Don't email this contact on comments" on their record) or via a rule.

Common issues ​

Client says "you didn't reply" but you did. Check the email gateway Activity log — was the outbound delivered? If bounced, why? Since replies send from your own M365 mailbox, also check that mailbox's Sent Items and any NDR back to it — see Connected mailboxes.

Auto-ack didn't fire. RFC 3834 guards detect auto-reply chains and suppress. If the inbound itself was an auto-reply (out-of-office), the auto-ack is suppressed. This is correct behaviour, even though it occasionally surprises.

Variable shows literal {{.ticket_subject}} in the email. Template parsing failed. Either the template syntax is wrong (variables are flat — {{.ticket_subject}}, not {{.ticket.subject}}, and not Handlebars), or the variable doesn't exist in context. Use Preview in the editor to spot.

Notification went to the wrong person. Check the recipient logic — for client emails, it's the ticket's requester; for internal, the assignee. The requester is editable on the ticket, so if it's reassigned, subsequent {{.requester_email}} notifications follow the new requester. If you've set rules, the rules can override.

Email subject is missing the threading anchor. A common customisation regret: removing [#{{.ticket_number}}] from the subject. Without it, client replies don't thread back correctly because we parse that anchor from the subject when no Reply-To match exists. Keep the [#…] anchor in the subject — and note it carries the internal threading id, not the human {{.ticket_ref}}.

Next ​

  • Workflows — the full rule-engine reference, including all triggers, actions, conditions, and guards
  • Connected mailboxes — outbound mechanics
  • Tickets — where notifications attach

Lovingly Created in the UK
OpsMerge is a product of Brindleford Technologies Ltd, company number 16871436, registered in England and Wales.