Frontbacked Docs

Notification Channels

Let your site admins receive order updates, stock alerts, booking requests, and other important events by email or Telegram. Define the channels in FRL; Frontbacked gives each channel a place in Notifications where admins connect and verify recipients.

Define channels

version 2;

// New orders, cancellations, and payment updates.
notification orders as "Order updates";

// Products that need restocking.
notification inventory as "Inventory alerts";

Use a stable key such as orders to identify a channel. The as label appears in the admin dashboard. Consecutive // comments or a /* block comment */ immediately above the declaration become its description, just like rateLimit. A blank line separates unrelated comments. Write these descriptions for the site admin so they can choose the right recipients.

Labels and descriptions can change without disconnecting recipients. The key must follow FRL identifier rules, and each key can be declared only once. Notifications require version 2;. The system namespace is reserved: themes cannot declare system.messages, system.new_messages, or other system channel keys. The aliases New message and New messages are also reserved, ignoring capitalization and extra whitespace. Built-in channels carry a gold ★ System badge in the dashboard; theme declarations do not.

Send a notification

Call notification.send(channelKeys, message) in an after hook, payment event, or endpoint body. For endpoints with dedupe, place the call after dedupe.

post enquiries as "Enquiries" {
  schema {
    name: { type: "string", required: true }
    message: { type: "string", required: true }
  }
  allow create: true
  after create {
    notification.send(["orders"], {
      title: "A customer has contacted you",
      message: "Open your dashboard to review the new enquiry.",
      url: "/fb-admin/posts"
    });
  }
}

To reach multiple channels, pass an array such as ["orders", "inventory"]. A recipient connected to both channels receives one copy of that notification. Only active, verified recipients receive messages.

ArgumentRequirements
Channel keysAn array of 1–20 declared keys. Repeated keys are combined.
titleRequired text, up to 200 characters.
messageRequired text, up to 3,000 characters.
urlOptional path on the current site, starting with /, up to 1,000 characters. External URLs are not accepted.

The combined title, message, and URL may contain at most 3,700 characters. Message text is treated as plain text; you do not need to escape email HTML or Telegram formatting.

The method returns { ok: true, queued: true }. This means the notification is scheduled when the surrounding operation is accepted; it does not mean a recipient has already received it. With no active recipients, there is nothing to deliver.

Use declared helper functions to reuse notification messages. They inherit the calling phase: a helper called from an after hook may send notifications, but one called from a permission check or before hook may not. Place notification.send outside atomic blocks, after the related changes. A failed endpoint transaction does not deliver its queued notifications. Use endpoint dedupe for actions that may be repeated by the caller.

Connect recipients

An admin who can manage site administrators can open Notifications and select Add recipients on a channel. Search the site’s saved recipients, select one or more, and save. Verified admin email addresses also appear in the list and can be selected without another verification email. Paused recipients remain paused. Each site supports up to 100 saved recipients.

Choose Add new recipient inside the dialog to create someone new. The dialog stays open with their verification instructions available. Once verified, select the recipient and save to connect them to the channel. Channel controls stay locked until verification is complete. Removing someone from a channel keeps their other subscriptions; Delete recipient from site in the recipient’s management dialog removes them everywhere.

  • Email: the recipient receives a verification link, opens it, and confirms notification delivery. Opening the link alone does not activate delivery.
  • Telegram account: open the provided bot link and press Start.
  • Telegram group: add the bot and have a group administrator send the provided /verify@bot_username CODE command. The administrator sending the command must turn off Remain Anonymous in their group admin settings and send only the command, without the bot label or other text. They can restore anonymous mode after verification. The bot must be able to send messages and check the sender's administrator status; grant administrator access if Telegram prevents that check.
  • Telegram channel: add the bot as an administrator with permission to post messages, then publish the provided command in the channel itself. Posting in the linked discussion group does not verify the channel.

Verification links and codes expire after 30 minutes and can be used only once. An admin can request a replacement after one minute. A new verification request invalidates the previous code and pauses delivery until confirmation. Recipient verification applies only to that site. Adding the same email again is rejected; edit the existing recipient's channel assignments instead.

Recipients can be paused, assigned to different channels, or removed. Removal disconnects the recipient from every channel on the site. A removed channel retains its saved recipient assignments, but does not send notifications while absent from the selected theme version.

Delivery status

Recent deliveries show whether each notification is queued, sending, sent, failed, or skipped. Frontbacked retries temporary failures up to five delivery attempts. Permanent Telegram failures pause that recipient. Fix the connection before enabling it again.

Before delivery, Frontbacked checks that the recipient is still active and connected to at least one of the targeted channels that is still defined. Otherwise the notification is skipped. Each separate call is a separate notification unless you opt into batching. Delivery is at least once: a rare interruption after a service accepts a message can cause a duplicate when Frontbacked retries.

Local development

When using frontbacked-server, Notifications includes a Telegram connection form. Create a separate bot with BotFather, enter its token, and save. A bot already using a webhook is rejected, preventing interference with another installation. The token is encrypted locally and is never returned to the browser after saving.

Keep the server running for Telegram verification and delivery. It checks every five seconds. By default, local email appears in the local mailbox, including verification links and delivered notifications. Under Notifications → Notification settings → Email delivery, choose SMTP to send all local-server emails through your own mail connection, including account verification and password resets. Enter the host, port, security mode, username/password if required, and sender address. Saving checks the connection without sending a message. Credentials are saved encrypted, and a blank password keeps the saved password only when the connection and username are unchanged. SMTP delivery does not create mailbox copies or fall back to the simulator on failure. Choose Local mailbox (simulator) to switch back. Verification links use the server’s address, so recipients need access to that address. Hosted sites use the shared Frontbacked bot and do not show the bot-token form.

New-message alerts

Every site includes a built-in New messages channel, even when its theme declares no notification channels. Connect recipients to receive a grouped alert for new messages that need a reply. By default, the first new message starts a ten-second window; further messages join that window without extending it. At delivery, the alert uses the current site-wide unread count. If the messages have been read or an admin is actively viewing Messages, the external alert is suppressed. Admin replies do not generate alerts.

An admin counts as available to reply while Messages is open in a visible admin tab. Merely having another dashboard page open does not suppress alerts. A hidden tab marks that session away; a disconnected session expires after one minute. Another visible Messages tab keeps the team available. Alerts link to Messages without including private message contents. The channel key is system.messages, reserved for the built-in messaging feature.

Find recipients and verification steps

Notifications has three tabs. Settings contains your channels and connection settings, with a separate Delivery history page in the Notifications menu. Active recipients lists every verified recipient, including paused recipients and recipients with no channel subscriptions. Pending recipients lists recipients waiting for verification, with a View verification steps action that works after closing the dialog or reloading the page.

Adding a new recipient opens a dedicated view inside the dialog. Finish creation or choose Back to recipients to return to the picker.

Telegram verification instructions retain the same code until it expires or you explicitly generate a replacement. Existing codes created before this behaviour may need a one-time replacement. Email instructions explain how to confirm using the recipient's email; the admin cannot open the recipient's ownership-verification link from this page.

Unverified recipients disappear when their 30-minute verification window expires. Their saved subscriptions are removed automatically, and you can add them again. Verified and paused recipients are retained.

Search delivery history

Open Notifications → Delivery history to see delivered notifications, newest delivery first. Use Next and Previous to browse without page-number limits. Choose another status to troubleshoot queued, failed, or skipped notifications; those views sort by the time the notification was queued.

Filter by channel key, recipient type, or an exact email address, Telegram chat ID, or recorded Telegram username. Telegram usernames are optional and can change; the chat ID is the more reliable identifier for accounts, groups, and channels. Delivery records preserve the destination details available when queued, including after a recipient is removed. Older records can show unavailable details where the original recipient had already been removed.

Group related notifications

Use batch in your notification payload to combine a burst of related events:

notification.send(["orders"], {
  title: "{{count}} new paid orders",
  message: `Latest payment: ${$payment.id}. Review the order and arrange delivery.`,
  url: "/fb-admin/payments",
  batch: {
    key: "paid-orders",
    delaySeconds: 10
  }
});

The first event starts a fixed window. Events for the same site, channel set, and key join that window. Later events do not extend the deadline. The latest event supplies the title, message, and link. Use {{count}} anywhere in the title or message to insert the number of collected events when delivery begins. {{count}} is the number of events in this window, not the number of unprocessed orders. Use different keys for different intents, such as new orders and cancelled orders.

Choose a delay from 1 to 300 seconds and a key up to 120 characters. Messages may contain up to 3,000 characters. Omit batch when a notification should be sent without a collection window. Delivery timing may be slightly later during retries or high load. Recipients and channel availability are checked when delivery begins.

Browser unread counts and dashboard updates remain immediate. Background browser popups combine new messages over two seconds and use the newest unread total; returning to the tab before that deadline cancels the popup. Email and Telegram use the site’s configurable new-message window described above.

Configure the system message window

In Notifications → Notification settings → Settings → New messages, admins can turn Group messages before sending on or off. With grouping on, choose a whole number from 1 to 300 seconds; new sites start at 10 seconds. With grouping off, each new visitor message is queued without a collection window. Delivery still runs asynchronously and can take a little longer during retries; local development checks queued work every five seconds.

Changes apply to new windows. A window already waiting keeps its original deadline. Switching grouping off does not cancel a waiting alert. The unread count and whether an admin is viewing Messages are checked at dispatch for both grouped and ungrouped alerts. A count of zero or an admin actively viewing Messages suppresses the external alert. Turning grouping off does not disconnect recipients or disable this channel. To stop delivery, remove its recipients or pause them.

You do not declare or call system.messages in your theme. Frontbacked sends these notifications automatically for visitor messages. Configure recipients and timing in the dashboard; custom FRL channels choose their own batch options when calling notification.send.

Browser alerts

Admins can enable browser alerts from the dashboard navbar or Messages. Dashboard home and Messages also show an invitation: “Enable browser alerts so you know when someone messages your site.” If your browser already allows notifications and you have no saved alert preference, alerts are enabled automatically when the dashboard loads. An explicit pause is preserved, and the navbar control stays available. Choose Enable alerts to open the browser permission prompt. On Dashboard home, the invitation stays visible until alerts are enabled, including when alerts are paused or browser permissions are blocked. On Messages, Not now dismisses the invitation for this site in this browser, and paused alerts do not show the invitation again. The navbar control remains available. Blocked permissions show guidance for changing browser settings. Allow notifications in both the browser and operating-system settings. Alerts work while the dashboard is open on any page and its tab is hidden; the tab’s unread count updates immediately. Browser popups use a separate fixed two-second window regardless of the email/Telegram setting. Returning to the tab before that window ends cancels the popup.

Browser popups and email/Telegram alerts use New site message · Your site name, using the name saved in Site Settings (name). Older app-name fields are used only when that name is absent. Without a configured name, the title is New site message. Its body uses the latest site-wide unread count, for example: You have 4 unread messages from your site. Open Messages to read it and reply. Clicking opens the relevant conversation in fb-admin Messages, reusing an open admin tab when possible. An already displayed popup can reopen Messages after the original tab closes in browsers that support persistent notifications. New browser alerts require an open dashboard; closing every dashboard tab stops receiving new browser alerts. Email and Telegram delivery is independent of the browser.

Choose batching by intent

SituationSuggested approachResult
A single urgent stock alertOmit batchQueue each call without a collection window.
A burst of paid ordersSame channels and batch.key, 10-second delayOne summary with the event count and latest order details.
Paid orders versus cancellationsDifferent batch.key valuesSeparate summaries even if recipients overlap.
Different channel setsSeparate batches automatically["orders"] and ["orders", "inventory"] do not combine.
Visitor messagesBuilt-in New messages settingsCurrent unread total, suppressed if the team is reading Messages.

For example, three paid-order events at seconds 0, 3, and 8 with a ten-second delay produce one notification at approximately second 10. The count is 3, and the latest payment details come from the event at second 8. An event after dispatch starts a new window. This count describes events collected in that window; it is not a database count of all orders still awaiting fulfilment. Fetch the business totals you need in your FRL flow and include them in message when that distinction matters.

batch contains key and delaySeconds. The key must be nonempty text of at most 120 characters. Delay must be an integer from 1 to 300; omit batch for immediate queuing. There is no separate summary field to compose: put the complete wording in title and message.

Every literal {{count}} in the title and message is replaced at dispatch, including repeated occurrences. Without batching it resolves to 1. It does not expand inside the URL or batch key. FRL expressions such as ${$payment.id} resolve for each event; the latest event's resulting text is retained until dispatch. If count expansion would exceed the title, message, or combined text limits, the rendered text is shortened to fit.

The system New messages channel uses the current unread-message count, not the number of events collected in the window. Custom theme-channel batching remains controlled by the theme developer; only the built-in New messages timing has an admin setting.

Older published themes using batch.summary remain supported for compatibility: their summary is treated as a prefix to the message. New themes should use {{count}} directly in the title and message.

Declaration keys follow the FRL naming rules, including the reserved system namespace.

Notification link domains

A notification's url stays a site-relative path. On hosted sites, Frontbacked turns it into an HTTPS link using the verified custom domain or generated subdomain used by the triggering request, provided that host belongs to the same site. Visiting your generated subdomain therefore keeps notification links on that subdomain.

Background notifications, including the built-in New messages alerts, prefer a verified custom domain. Without one, links use the generated subdomain. Internal service hosts, unverified domains, and domains belonging to another site are never used. If several custom domains are verified, background links use the oldest configured verified domain, with a stable tie-breaker. These rules also apply to notification-recipient verification links. Local development continues using the local server address.