security.manage). Every change is written to the organization’s event log, with who
made it and which fields changed. A secret’s value never goes into the log.
Kinds
Telegram
Telegram messages are posted by your own bot:- Create a bot: send
/newbotto @BotFather and copy the token it gives you. - Add the bot to the group. For a channel, add it as an administrator, because only an administrator can post there.
- Send any message in that chat. Then open
https://api.telegram.org/bot<token>/getUpdatesand copychat.id. A group’s id starts with-100. A public channel can also be given as@name.
Slack
A Slack channel connects in one of two ways. Choose it with Connect with in the channel’s form. Bot token — messages are posted by your own Slack app, and files are attached:- Create a Slack app in your workspace. Under OAuth & Permissions, add the bot scopes
chat:writeandfiles:write. - Install the app to the workspace and copy its Bot User OAuth Token. It starts with
xoxb-. - Invite the app to the channel: type
/invite @your-appin the channel. - Copy the channel id. It is at the bottom of the channel’s details and looks like
C0123456789.
https://hooks.slack.com/. Files go as
download links in the text.
Slack allows about one message per second to a channel. Citadel spaces messages to the same channel
to stay under this limit.
Mattermost
A Mattermost channel also connects with a bot token or an incoming webhook. Bot token — messages are posted by a bot account on your server, and files are attached:- Create a bot account (Integrations → Bot Accounts) and copy its access token.
- Add the bot to the team and to the channel.
- Copy the channel id: in the channel, open View Info. The id is at the bottom.
- Enter the address your team opens Mattermost at, such as
https://chat.example.com.
Bot tokens and webhook URLs
Bot tokens and webhook URLs are stored encrypted. Once you save one, the console shows only its last four characters. To change it, type the new one in. A blank field keeps the saved value. When you switch a channel to the other way of connecting, the saved token or URL of the old way is deleted.Addresses Citadel calls
Citadel calls a server or webhook URL you enter only if it is safe to reach from the internet:- The URL starts with
https://and has no user name or password in it. - Its host resolves to public internet addresses only. A host that points to a private network, the local machine, a link-local or cloud metadata address, or another reserved address is refused.
- Citadel connects to the address it checked, and never follows a redirect. A server that answers with a redirect fails the delivery.
Message format
Messages are written in a small subset of Markdown. Each channel renders it in its own format:
Anything else appears as you typed it. Citadel escapes text for each channel, so a message can
never inject markup into an email or a chat. Text in a message never mentions anyone:
@channel,
@here, @all or @name in the text does not notify people in Slack or Mattermost. Words that
people chose to be notified about in their own Slack or Mattermost settings still notify them.
Files and download links
When a channel cannot take a file — it is too large, or the channel is an incoming webhook, which carries text only — the message carries a download link instead. The link opens that one file and nothing else. It works without signing in to the console and expires after 7 days. The message shows the expiry date. Anyone who has the link can download the file until then, so share it only as you would share the file. The link opens a short page that downloads the file, so the browser needs JavaScript. The secret part of the link comes after#: the browser keeps it and sends it to the console only in the
body of the download request. It never appears in an address that a server, a proxy or a link
preview records.
In workflows
One workflow step posts to notification channels: Send a notification. It names channels from your organization’s settings. It never holds a bot token, a chat id or a webhook URL itself. To send a report, the step attaches it: see Sending a report.Send a notification
The step saves its result as
notification:
status is the one at the moment the step ran, usually
pending.
Values in a message
In a title or a message,{name} puts in a value of the run. It can be something an earlier step
saved, such as {movement.amount}, {wallet.reference} or {report.period}. These values are in
every run:
A value is shown exactly as it is. A character such as
* or [ in a value never turns into
formatting, in any channel. To use a value as a link, write it as the link’s target:
[Open the run]({run.url}). This works when the value is a plain http or https URL; otherwise
the link shows as text. A missing value puts in nothing.
Sending a report
Generate a report only builds the report. To send it, put a Send a notification step after it and pick the report in Attach reports. On the report step, Add “Send a notification” after it adds that step with the report attached and a message that names the report and its period. The report step saves the report asreport, or under the name in Save the report as, with
id, title, period and format. The message and the title can use these values, such as
{report.title} and {report.period}.
The deliveries wait while the report is being built. If the report cannot be built, they fail as
not sent. A failed delivery is retried from the delivery log; the report is not
built again. For the workflow to act on a failed delivery, set Then to Wait until every
channel has it and continue on the failed path.
Publishing and the run page
A workflow publishes only if every channel its steps name exists in your organization’s settings. Steps built before notification channels — the Send to Telegram step, or a chat id or webhook URL typed into a step — no longer publish or run. Choose channels in Send a notification, then publish the workflow again. A Generate a report step that still has its own channels, title or message, from when a report step could send the report itself, no longer publishes or runs either. On that step, Move to a “Send a notification” step moves them to a new step after it, with the report attached. Then publish the workflow again. On a run’s page, a step that posted a message lists each channel’s delivery. Delivery log opens the log of that run, where a failed delivery can be retried.Delivery
A message gets one delivery for each channel it goes to. A worker restart or a repeated request never sends the same message to a channel twice. The delivery log shows each one:
A delivery is tried up to 6 times: at once, then after 15 s, 1 min, 5 min, 30 min and 1 h. When a
channel answers too many requests, Citadel waits as long as the channel asks. That wait does not
use up an attempt. A delivery stops waiting after 24 hours.
A delivery fails without further attempts when:
Retry in the log sends a failed delivery again with a fresh schedule. The log can show the
deliveries of one channel, or those of one workflow run.