Introduction
Fossil’s developer chatroom feature provides an ephemeral discussion venue for insiders. Design goals include:
Simple but functional → Fossil chat is designed to provide a convenient real-time communication mechanism for geographically dispersed developers. Fossil chat is not intended as a replacement or competitor for IRC, Slack, Discord, Telegram, Google Hangouts, etc.
Low administration → You can activate the chatroom in seconds without having to mess with configuration files or install new software. In an existing server setup, simply enable the C capability for users whom you want to give access to the chatroom.
Ephemeral → Chat messages do not sync to peer repositories, and they are automatically deleted after a configurable delay (default: 7 days). Individual messages or the entire conversation can be deleted at any time without impacting any other part of the system.
Fossil chat is designed for use by insiders - people with check-in privileges or higher. It is not intended as a general-purpose gathering place for random passers-by on the internet. Fossil chat seeks to provide a communication venue for discussion that does not become part of the permanent record for the project. For persistent and durable discussion, use the Forum. Because the conversation is intended to be ephemeral, the chat messages are local to a single repository. Chat content does not sync.
Setup
A Fossil repository must be functioning as a server in order for chat to work. To activate chat, simply add the C capability to every user who is authorized to participate. Anyone who can read chat can also post to chat.
Setup ("s") and Admin ("a") users always have access to chat, without needing the "C" capability. A common configuration is to add the "C" capability to "Developer" so that any individual user who has the "v" capability will also have access to chat.
There are also some settings under /Admin/Chat that control the behavior of chat, though the default settings are reasonable so in most cases those settings can be ignored. The settings control things like the amount of time that chat messages are retained before being purged from the repository database.
Usage
For users with appropriate permissions, simply browse to the /chat to start up a chat session. The default skin includes a "Chat" entry on the menu bar on wide screens for people with chat privilege. There is also a "Chat" option on the Sitemap page, which means that chat will appear as an option under the hamburger menu for many skins.
Chat messages are subject to Fossil's full range of Markdown processing. Because chat messages are stored as-is when they arrive from a client, this change applies retroactively to messages stored by previous fossil versions.
Files may be sent via chat using the file selection element at the bottom of the page. If the desktop environment system supports it, files may be dragged and dropped onto that element. Files are not automatically sent - selection of a file can be cancelled using the Cancel button which appears only when a file is selected. When the Send button is pressed, any pending text is submitted along with the selected file. Image files sent this way will, by default, appear inline in messages, but each user may toggle that via the settings popup menu, such that images instead appear as downloadable links. Non-image files always appear in messages as download links.
Deletion of Messages
Any user may locally delete a given message by clicking on the "tab" at the top of the message and clicking the button which appears. Such deletions are local-only, and the messages will reappear if the page is reloaded. The user who posted a given message, or any Admin users, may additionally choose to globally delete a message from the chat record, which deletes it not only from their own browser but also propagates the removal to all connected clients the next time they poll for new messages.
Customizing New-message Notification Sounds
By default, the list of new-message notification sounds is limited to
a few built in to the fossil binary. In addition, any
unversioned files named alert-sounds/*.{mp3,wav,ogg}
will be included in that list. To switch sounds, tap the "settings"
button.
Who's Online?
Because the chat app has to be able to work over transient CGI-based connections, as opposed to a stable socket connection to the server, real-time tracking of "who's online" is not feasible. Chat offers an optional feature, toggleable in the settings, which can list users who have posted messages in the client's current list of loaded messages. This is not the same thing as tracking who's online, but it gives an overview of which users have been active most recently, noting that "lurkers" (people who post no messages) will not show up in that list, nor does the chat infrastructure have a way to track and present those. That list can be used to filter messages on a specific user by tapping on that user's name, tapping a second time to remove the filter.
The fossil chat
Command
Type fossil chat from within any open check-out to bring up a chatroom for the project that is in that checkout. The new chat window will attempt to connect to the default sync target for that check-out (the server whose URL is shown by the fossil remote command).
Chat Messages From Robots
The fossil chat send can be used by project-specific robots to send notifications to the chatroom. For example, on the SQLite project (for which the Fossil chatroom feature, and indeed all of Fossil, was invented) there are long-running fuzz servers that sometimes run across obscure problems. Whenever this happens, a message is sent to the SQLite developers chatroom alerting them to the problem.
The recommended way to allow robots to send chat messages is to create a new user on the server for each robot. Give each such robot account the "C" privilege only. That means that the robot user account will be able to send chat messages, but not do anything else. Then, in the program or script that runs the robot, when it wants to send a chat message, have it run a command like this:
fossil chat send --remote https://robot:PASSWORD@project.org/fossil \
--message 'MESSAGE TEXT' --file file-to-attach.txt
Substitute the appropriate project URL, robot account name and password, message text and file attachment, of course.
Chat Messages For Timeline Events
If the chat-timeline-user setting is not an empty string, then any change to the repository that would normally result in a new timeline entry is announced in the chatroom. The announcement appears to come from a user whose name is given by the chat-timeline-user setting.
This mechanism is similar to email notification except that the notification is sent via chat instead of via email.
Implementation Details
You do not need to understand how Fossil chat works in order to use it. But many developers prefer to know how their tools work. This section is provided for the benefit of those curious developers.
The /chat webpage downloads a small amount of HTML and a small amount of javascript to run the chat session. The javascript uses XMLHttpRequest (XHR) to download chat content, post new content, or delete historical messages. The following web interfaces are used by the XHR:
/chat-poll → Downloads chat content as JSON. Chat messages are numbered sequentially. The client tells the server the largest chat message it currently holds, and the server sends back subsequent messages. If there are no subsequent messages, the /chat-poll page blocks until new messages are available.
/chat-send → Sends a new chat message to the server.
/chat-delete → Deletes a chat message.
Fossil chat uses the venerable "hanging GET" or "long polling" technique to receive asynchronous notification of new messages. This is done because long polling works well with CGI and SCGI, which are the usual mechanisms for setting up a Fossil server. More advanced notification techniques such as Server-sent events and especially WebSockets might seem more appropriate for a chat system, but those technologies are not compatible with CGI.
Downloading of posted files and images uses a separate, non-XHR interface:
- /chat-download → Fetches the file content associated with a post (one file per post, maximum). In the UI, this is accessed via links to uploaded files and via inlined image tags.
Chat messages are stored on the server-side in the CHAT table of the repository.
CREATE TABLE repository.chat(
msgid INTEGER PRIMARY KEY AUTOINCREMENT,
mtime JULIANDAY, -- Time for this entry - Julianday Zulu
lmtime TEXT, -- Client YYYY-MM-DDZHH:MM:SS when message originally sent
xfrom TEXT, -- Login of the sender
xmsg TEXT, -- Raw, unformatted text of the message
fname TEXT, -- Filename of the uploaded file, or NULL
fmime TEXT, -- MIMEType of the upload file, or NULL
mdel INT, -- msgid of another message to delete
file BLOB -- Text of the uploaded file, or NULL
);
The CHAT table is not cross-linked with any other tables in the repository schema. An administrator can "DROP TABLE chat;" at any time, without harm (apart from deleting all chat history, of course). The CHAT table is dropped when running fossil scrub --verily.
On the server-side, message text is stored exactly as entered by the
users. The /chat-poll page queries the CHAT table and constructs a
JSON reply described in the /chat-poll
documentation. The message text is translated
into HTML before being converted to JSON so that the text can be
safely added to the display using assignment to innerHTML
. Though
innerHTML
assignment is generally considered unsafe, it is only so
with untrusted content from untrusted sources. The chat content goes
through sanitization steps which eliminate any potential security
vulnerabilities of assigning that content to innerHTML
.