|
bcfdc1a…
|
drh
|
1 |
# Fossil Chat |
|
bcfdc1a…
|
drh
|
2 |
|
|
bcfdc1a…
|
drh
|
3 |
## Introduction |
|
bcfdc1a…
|
drh
|
4 |
|
|
ad47a44…
|
wyoung
|
5 |
Fossil’s developer chatroom feature provides an |
|
e525317…
|
drh
|
6 |
ephemeral discussion venue for insiders. Design goals include: |
|
e525317…
|
drh
|
7 |
|
|
6c1ac83…
|
stephan
|
8 |
* **Simple but functional** → |
|
6c1ac83…
|
stephan
|
9 |
Fossil chat is designed to provide a convenient real-time |
|
6c1ac83…
|
stephan
|
10 |
communication mechanism for geographically dispersed developers. |
|
6c1ac83…
|
stephan
|
11 |
Fossil chat is *not* intended as a replacement or competitor for |
|
6c1ac83…
|
stephan
|
12 |
IRC, Slack, Discord, Telegram, Google Hangouts, etc. |
|
e525317…
|
drh
|
13 |
|
|
e525317…
|
drh
|
14 |
* **Low administration** → |
|
5d3ba8a…
|
drh
|
15 |
You can activate the chatroom in seconds without having to |
|
5d3ba8a…
|
drh
|
16 |
mess with configuration files or install new software. |
|
5d3ba8a…
|
drh
|
17 |
In an existing [server setup](./server/), |
|
5d3ba8a…
|
drh
|
18 |
simply enable the [C capability](/setup_ucap_list) for users |
|
bcfdc1a…
|
drh
|
19 |
whom you want to give access to the chatroom. |
|
bcfdc1a…
|
drh
|
20 |
|
|
bcfdc1a…
|
drh
|
21 |
* **Ephemeral** → |
|
9428699…
|
andygoth
|
22 |
Chat messages do not sync to peer repositories, and they are |
|
bcfdc1a…
|
drh
|
23 |
automatically deleted after a configurable delay (default: 7 days). |
|
5d3ba8a…
|
drh
|
24 |
Individual messages or the entire conversation |
|
5d3ba8a…
|
drh
|
25 |
can be deleted at any time without impacting any other part |
|
e525317…
|
drh
|
26 |
of the system. |
|
bcfdc1a…
|
drh
|
27 |
|
|
bcfdc1a…
|
drh
|
28 |
Fossil chat is designed for use by insiders - people with check-in |
|
e525317…
|
drh
|
29 |
privileges or higher. It is not intended as a general-purpose gathering |
|
e525317…
|
drh
|
30 |
place for random passers-by on the internet. |
|
1008541…
|
stephan
|
31 |
Fossil chat seeks to provide a communication venue for discussion |
|
e525317…
|
drh
|
32 |
that does *not* become part of the permanent record for the project. |
|
9428699…
|
andygoth
|
33 |
For persistent and durable discussion, use the [Forum](./forum.wiki). |
|
e525317…
|
drh
|
34 |
Because the conversation is intended to be ephemeral, the chat messages |
|
e525317…
|
drh
|
35 |
are local to a single repository. Chat content does not sync. |
|
e525317…
|
drh
|
36 |
|
|
bcfdc1a…
|
drh
|
37 |
|
|
bcfdc1a…
|
drh
|
38 |
## Setup |
|
bcfdc1a…
|
drh
|
39 |
|
|
e525317…
|
drh
|
40 |
A Fossil repository must be functioning as a [server](./server/) in order |
|
e525317…
|
drh
|
41 |
for chat to work. |
|
e525317…
|
drh
|
42 |
To activate chat, simply add the [C capability](/setup_ucap_list) |
|
bcfdc1a…
|
drh
|
43 |
to every user who is authorized to participate. Anyone who can read chat |
|
bcfdc1a…
|
drh
|
44 |
can also post to chat. |
|
bcfdc1a…
|
drh
|
45 |
|
|
bcfdc1a…
|
drh
|
46 |
Setup ("s") and Admin ("a") users always have access to chat, without needing |
|
bcfdc1a…
|
drh
|
47 |
the "C" capability. A common configuration is to add the "C" capability |
|
bcfdc1a…
|
drh
|
48 |
to "Developer" so that any individual user who has the "v" capability will |
|
bcfdc1a…
|
drh
|
49 |
also have access to chat. |
|
bcfdc1a…
|
drh
|
50 |
|
|
bcfdc1a…
|
drh
|
51 |
There are also some settings under /Admin/Chat that control the |
|
bcfdc1a…
|
drh
|
52 |
behavior of chat, though the default settings are reasonable so in most |
|
bcfdc1a…
|
drh
|
53 |
cases those settings can be ignored. The settings control things like |
|
bcfdc1a…
|
drh
|
54 |
the amount of time that chat messages are retained before being purged |
|
bcfdc1a…
|
drh
|
55 |
from the repository database. |
|
bcfdc1a…
|
drh
|
56 |
|
|
6c1ac83…
|
stephan
|
57 |
## <a id="usage"></a>Usage |
|
bcfdc1a…
|
drh
|
58 |
|
|
9428699…
|
andygoth
|
59 |
For users with appropriate permissions, simply browse to the |
|
c64f28d…
|
drh
|
60 |
[/chat](/help/www/chat) to start up a chat session. The default |
|
bcfdc1a…
|
drh
|
61 |
skin includes a "Chat" entry on the menu bar on wide screens for |
|
bcfdc1a…
|
drh
|
62 |
people with chat privilege. There is also a "Chat" option on |
|
9428699…
|
andygoth
|
63 |
the [Sitemap page](/sitemap), which means that chat will appear |
|
e525317…
|
drh
|
64 |
as an option under the hamburger menu for many [skins](./customskin.md). |
|
e525317…
|
drh
|
65 |
|
|
ad47a44…
|
wyoung
|
66 |
Chat messages are subject to [Fossil's |
|
ad47a44…
|
wyoung
|
67 |
full range of Markdown processing](/md_rules). Because chat messages are |
|
6c1ac83…
|
stephan
|
68 |
stored as-is when they arrive from a client, this change applies |
|
6c1ac83…
|
stephan
|
69 |
retroactively to messages stored by previous fossil versions. |
|
a6177fd…
|
stephan
|
70 |
|
|
a6177fd…
|
stephan
|
71 |
Files may be sent via chat using the file selection element at the |
|
a6177fd…
|
stephan
|
72 |
bottom of the page. If the desktop environment system supports it, |
|
a6177fd…
|
stephan
|
73 |
files may be dragged and dropped onto that element. Files are not |
|
a6177fd…
|
stephan
|
74 |
automatically sent - selection of a file can be cancelled using the |
|
a6177fd…
|
stephan
|
75 |
Cancel button which appears only when a file is selected. When the |
|
a6177fd…
|
stephan
|
76 |
Send button is pressed, any pending text is submitted along with the |
|
a6177fd…
|
stephan
|
77 |
selected file. Image files sent this way will, by default, appear |
|
9428699…
|
andygoth
|
78 |
inline in messages, but each user may toggle that via the settings |
|
a6177fd…
|
stephan
|
79 |
popup menu, such that images instead appear as downloadable links. |
|
a6177fd…
|
stephan
|
80 |
Non-image files always appear in messages as download links. |
|
a6177fd…
|
stephan
|
81 |
|
|
a6177fd…
|
stephan
|
82 |
### Deletion of Messages |
|
8a1ba49…
|
wyoung
|
83 |
|
|
8a1ba49…
|
wyoung
|
84 |
<div class="sidebar">Message deletion is itself a type of message, which |
|
8a1ba49…
|
wyoung
|
85 |
is why deletions count towards updates in the recent activity list. (It |
|
8a1ba49…
|
wyoung
|
86 |
is counted for the person who performed the deletion, not the author of |
|
8a1ba49…
|
wyoung
|
87 |
the deleted comment.) That can potentially lead to odd corner cases |
|
8a1ba49…
|
wyoung
|
88 |
where a user shows up in the list but has no messages which are |
|
8a1ba49…
|
wyoung
|
89 |
currently visible because they were deleted, or an admin user who has |
|
8a1ba49…
|
wyoung
|
90 |
not posted anything but deleted a message. That is a known minor |
|
8a1ba49…
|
wyoung
|
91 |
cosmetic-only bug with a resolution of "will not fix."</div> |
|
9c77715…
|
stephan
|
92 |
|
|
a6177fd…
|
stephan
|
93 |
Any user may *locally* delete a given message by clicking on the "tab" |
|
a6177fd…
|
stephan
|
94 |
at the top of the message and clicking the button which appears. Such |
|
9428699…
|
andygoth
|
95 |
deletions are local-only, and the messages will reappear if the page |
|
a0d3f53…
|
stephan
|
96 |
is reloaded. The user who posted a given message, or any Admin users, |
|
a0d3f53…
|
stephan
|
97 |
may additionally choose to globally delete a message from the chat |
|
a0d3f53…
|
stephan
|
98 |
record, which deletes it not only from their own browser but also |
|
a0d3f53…
|
stephan
|
99 |
propagates the removal to all connected clients the next time they |
|
a0d3f53…
|
stephan
|
100 |
poll for new messages. |
|
a0d3f53…
|
stephan
|
101 |
|
|
9c77715…
|
stephan
|
102 |
### <a id='notifications'></a>Customizing New-message Notification Sounds |
|
9c77715…
|
stephan
|
103 |
|
|
9c77715…
|
stephan
|
104 |
By default, the list of new-message notification sounds is limited to |
|
9c77715…
|
stephan
|
105 |
a few built in to the fossil binary. In addition, any |
|
9c77715…
|
stephan
|
106 |
[unversioned files](./unvers.wiki) named `alert-sounds/*.{mp3,wav,ogg}` |
|
9c77715…
|
stephan
|
107 |
will be included in that list. To switch sounds, tap the "settings" |
|
9c77715…
|
stephan
|
108 |
button. |
|
9c77715…
|
stephan
|
109 |
|
|
ce0d61b…
|
stephan
|
110 |
### <a id='connection'></a> Who's Online? |
|
ce0d61b…
|
stephan
|
111 |
|
|
ce0d61b…
|
stephan
|
112 |
Because the chat app has to be able to work over transient CGI-based |
|
ce0d61b…
|
stephan
|
113 |
connections, as opposed to a stable socket connection to the server, |
|
ad47a44…
|
wyoung
|
114 |
real-time tracking of "who's online" is not feasible. |
|
ad47a44…
|
wyoung
|
115 |
Chat offers an optional feature, toggleable in the settings, |
|
ce0d61b…
|
stephan
|
116 |
which can list users who have posted messages in the client's current |
|
ce0d61b…
|
stephan
|
117 |
list of loaded messages. This is not the same thing as tracking who's |
|
ce0d61b…
|
stephan
|
118 |
online, but it gives an overview of which users have been active most |
|
ce0d61b…
|
stephan
|
119 |
recently, noting that "lurkers" (people who post no messages) will not |
|
ce0d61b…
|
stephan
|
120 |
show up in that list, nor does the chat infrastructure have a way to |
|
ce0d61b…
|
stephan
|
121 |
track and present those. That list can be used to filter messages on a |
|
ce0d61b…
|
stephan
|
122 |
specific user by tapping on that user's name, tapping a second time to |
|
ce0d61b…
|
stephan
|
123 |
remove the filter. |
|
ce0d61b…
|
stephan
|
124 |
|
|
bd7f272…
|
danield
|
125 |
### <a id="cli"></a> The `fossil chat` Command |
|
bd7f272…
|
danield
|
126 |
|
|
c64f28d…
|
drh
|
127 |
Type [fossil chat](/help/chat) from within any open check-out |
|
bd7f272…
|
danield
|
128 |
to bring up a chatroom for the project that is in that checkout. |
|
bd7f272…
|
danield
|
129 |
The new chat window will attempt to connect to the default sync |
|
bd7f272…
|
danield
|
130 |
target for that check-out (the server whose URL is shown by the |
|
c64f28d…
|
drh
|
131 |
[fossil remote](/help/remote) command). |
|
bd7f272…
|
danield
|
132 |
|
|
bd7f272…
|
danield
|
133 |
### <a id="robots"></a> Chat Messages From Robots |
|
bd7f272…
|
danield
|
134 |
|
|
c64f28d…
|
drh
|
135 |
The [fossil chat send](/help/chat) can be used by project-specific |
|
bd7f272…
|
danield
|
136 |
robots to send notifications to the chatroom. For example, on the |
|
bd7f272…
|
danield
|
137 |
[SQLite project](https://sqlite.org/) (for which the Fossil chatroom |
|
bd7f272…
|
danield
|
138 |
feature, and indeed all of Fossil, was invented) there are long-running |
|
bd7f272…
|
danield
|
139 |
fuzz servers that sometimes run across obscure problems. Whenever this |
|
841c78d…
|
stephan
|
140 |
happens, a message is sent to the SQLite developers chatroom alerting |
|
bd7f272…
|
danield
|
141 |
them to the problem. |
|
bd7f272…
|
danield
|
142 |
|
|
bd7f272…
|
danield
|
143 |
The recommended way to allow robots to send chat messages is to create |
|
bd7f272…
|
danield
|
144 |
a new user on the server for each robot. Give each such robot account |
|
bd7f272…
|
danield
|
145 |
the "C" privilege only. That means that the robot user account will be |
|
bd7f272…
|
danield
|
146 |
able to send chat messages, but not do anything else. Then, in the |
|
bd7f272…
|
danield
|
147 |
program or script that runs the robot, when it wants to send a chat |
|
bd7f272…
|
danield
|
148 |
message, have it run a command like this: |
|
bd7f272…
|
danield
|
149 |
|
|
d6dff8d…
|
wyoung
|
150 |
~~~~ |
|
bd7f272…
|
danield
|
151 |
fossil chat send --remote https://robot:[email protected]/fossil \ |
|
bd7f272…
|
danield
|
152 |
--message 'MESSAGE TEXT' --file file-to-attach.txt |
|
bd7f272…
|
danield
|
153 |
~~~~ |
|
bd7f272…
|
danield
|
154 |
|
|
bd7f272…
|
danield
|
155 |
Substitute the appropriate project URL, robot account |
|
bd7f272…
|
danield
|
156 |
name and password, message text and file attachment, of course. |
|
bd7f272…
|
danield
|
157 |
|
|
24c71df…
|
drh
|
158 |
### <a id="chat-robot"></a> Chat Messages For Timeline Events |
|
24c71df…
|
drh
|
159 |
|
|
c64f28d…
|
drh
|
160 |
If the [chat-timeline-user setting](/help/chat-timeline-user) is not an |
|
24c71df…
|
drh
|
161 |
empty string, then any change to the repository that would normally result |
|
24c71df…
|
drh
|
162 |
in a new timeline entry is announced in the chatroom. The announcement |
|
24c71df…
|
drh
|
163 |
appears to come from a user whose name is given by the chat-timeline-user |
|
24c71df…
|
drh
|
164 |
setting. |
|
24c71df…
|
drh
|
165 |
|
|
24c71df…
|
drh
|
166 |
This mechanism is similar to [email notification](./alerts.md) except that |
|
24c71df…
|
drh
|
167 |
the notification is sent via chat instead of via email. |
|
24c71df…
|
drh
|
168 |
|
|
da1c351…
|
stephan
|
169 |
## Quirks |
|
da1c351…
|
stephan
|
170 |
|
|
da1c351…
|
stephan
|
171 |
- There is no message-editing capability. This is by design and |
|
da1c351…
|
stephan
|
172 |
desire of `/chat`'s developers. |
|
da1c351…
|
stephan
|
173 |
|
|
da1c351…
|
stephan
|
174 |
- When `/chat` has problems connecting to the message poller (see |
|
da1c351…
|
stephan
|
175 |
the next section) it will provide a subtle visual indicator of the |
|
da1c351…
|
stephan
|
176 |
connection problem - a dotted line along the top of the input |
|
da1c351…
|
stephan
|
177 |
field. If the connection recovers within a short time, that |
|
da1c351…
|
stephan
|
178 |
indicator will go away, otherwise it will pop up a loud message |
|
da1c351…
|
stephan
|
179 |
signifying that the connection to the poller is down and how long |
|
da1c351…
|
stephan
|
180 |
it will wait to retry (progressively longer, up to some |
|
da1c351…
|
stephan
|
181 |
maximum). `/chat` will recover automatically when the server is |
|
da1c351…
|
stephan
|
182 |
reachable. Trying to send messages while the poller connection is |
|
da1c351…
|
stephan
|
183 |
down is permitted, and the poller will attempt to recover |
|
da1c351…
|
stephan
|
184 |
immediately if sending of a message succeeds. That applies to any |
|
da1c351…
|
stephan
|
185 |
operations which send traffic, e.g. if the per-message "toggle |
|
da1c351…
|
stephan
|
186 |
text mode" button is activated or a message is globally deleted. |
|
24c71df…
|
drh
|
187 |
|
|
bcfdc1a…
|
drh
|
188 |
## Implementation Details |
|
bcfdc1a…
|
drh
|
189 |
|
|
e525317…
|
drh
|
190 |
*You do not need to understand how Fossil chat works in order to use it. |
|
e525317…
|
drh
|
191 |
But many developers prefer to know how their tools work. |
|
e525317…
|
drh
|
192 |
This section is provided for the benefit of those curious developers.* |
|
e525317…
|
drh
|
193 |
|
|
c64f28d…
|
drh
|
194 |
The [/chat](/help/www/chat) webpage downloads a small amount of HTML |
|
1008541…
|
stephan
|
195 |
and a small amount of javascript to run the chat session. The |
|
1008541…
|
stephan
|
196 |
javascript uses XMLHttpRequest (XHR) to download chat content, post |
|
1008541…
|
stephan
|
197 |
new content, or delete historical messages. The following web |
|
1008541…
|
stephan
|
198 |
interfaces are used by the XHR: |
|
1008541…
|
stephan
|
199 |
|
|
bd7f272…
|
danield
|
200 |
* [/chat-poll](/help?name=/chat-poll) → |
|
9428699…
|
andygoth
|
201 |
Downloads chat content as JSON. |
|
9428699…
|
andygoth
|
202 |
Chat messages are numbered sequentially. |
|
7924b4a…
|
brickviking
|
203 |
The client tells the server the latest chat message ID it currently |
|
9428699…
|
andygoth
|
204 |
holds, and the server sends back subsequent messages. If there |
|
bcfdc1a…
|
drh
|
205 |
are no subsequent messages, the /chat-poll page blocks until new |
|
bcfdc1a…
|
drh
|
206 |
messages are available. |
|
bcfdc1a…
|
drh
|
207 |
|
|
bd7f272…
|
danield
|
208 |
* [/chat-send](/help?name=/chat-send) → |
|
bcfdc1a…
|
drh
|
209 |
Sends a new chat message to the server. |
|
bcfdc1a…
|
drh
|
210 |
|
|
bd7f272…
|
danield
|
211 |
* [/chat-delete](/help?name=/chat-delete) → |
|
9428699…
|
andygoth
|
212 |
Deletes a chat message. |
|
bcfdc1a…
|
drh
|
213 |
|
|
e525317…
|
drh
|
214 |
Fossil chat uses the venerable "hanging GET" or |
|
bcfdc1a…
|
drh
|
215 |
"[long polling](wikipedia:/wiki/Push_technology#Long_polling)" |
|
efd79f8…
|
drh
|
216 |
technique to receive asynchronous notification of new messages. |
|
e525317…
|
drh
|
217 |
This is done because long polling works well with CGI and SCGI, |
|
e525317…
|
drh
|
218 |
which are the usual mechanisms for setting up a Fossil server. |
|
e525317…
|
drh
|
219 |
More advanced notification techniques such as |
|
bcfdc1a…
|
drh
|
220 |
[Server-sent events](wikipedia:/wiki/Server-sent_events) and especially |
|
bcfdc1a…
|
drh
|
221 |
[WebSockets](wikipedia:/wiki/WebSocket) might seem more appropriate for |
|
e525317…
|
drh
|
222 |
a chat system, but those technologies are not compatible with CGI. |
|
e525317…
|
drh
|
223 |
|
|
1008541…
|
stephan
|
224 |
Downloading of posted files and images uses a separate, non-XHR interface: |
|
1008541…
|
stephan
|
225 |
|
|
bd7f272…
|
danield
|
226 |
* [/chat-download](/help?name=/chat-download) → |
|
1008541…
|
stephan
|
227 |
Fetches the file content associated with a post (one file per |
|
1008541…
|
stephan
|
228 |
post, maximum). In the UI, this is accessed via links to uploaded |
|
1008541…
|
stephan
|
229 |
files and via inlined image tags. |
|
1008541…
|
stephan
|
230 |
|
|
bcfdc1a…
|
drh
|
231 |
Chat messages are stored on the server-side in the CHAT table of |
|
bcfdc1a…
|
drh
|
232 |
the repository. |
|
bcfdc1a…
|
drh
|
233 |
|
|
d6dff8d…
|
wyoung
|
234 |
~~~ |
|
bd7f272…
|
danield
|
235 |
CREATE TABLE repository.chat( |
|
bd7f272…
|
danield
|
236 |
msgid INTEGER PRIMARY KEY AUTOINCREMENT, |
|
bd7f272…
|
danield
|
237 |
mtime JULIANDAY, -- Time for this entry - Julianday Zulu |
|
bd7f272…
|
danield
|
238 |
lmtime TEXT, -- Client YYYY-MM-DDZHH:MM:SS when message originally sent |
|
bd7f272…
|
danield
|
239 |
xfrom TEXT, -- Login of the sender |
|
bd7f272…
|
danield
|
240 |
xmsg TEXT, -- Raw, unformatted text of the message |
|
bd7f272…
|
danield
|
241 |
fname TEXT, -- Filename of the uploaded file, or NULL |
|
bd7f272…
|
danield
|
242 |
fmime TEXT, -- MIMEType of the upload file, or NULL |
|
bd7f272…
|
danield
|
243 |
mdel INT, -- msgid of another message to delete |
|
bd7f272…
|
danield
|
244 |
file BLOB -- Text of the uploaded file, or NULL |
|
bd7f272…
|
danield
|
245 |
); |
|
bcfdc1a…
|
drh
|
246 |
~~~ |
|
bcfdc1a…
|
drh
|
247 |
|
|
bcfdc1a…
|
drh
|
248 |
The CHAT table is not cross-linked with any other tables in the repository |
|
92d74f8…
|
stephan
|
249 |
schema. An administrator can "DROP TABLE chat;" at any time, without |
|
bcfdc1a…
|
drh
|
250 |
harm (apart from deleting all chat history, of course). The CHAT table |
|
c64f28d…
|
drh
|
251 |
is dropped when running [fossil scrub --verily](/help/scrub). |
|
bcfdc1a…
|
drh
|
252 |
|
|
bcfdc1a…
|
drh
|
253 |
On the server-side, message text is stored exactly as entered by the |
|
1008541…
|
stephan
|
254 |
users. The /chat-poll page queries the CHAT table and constructs a |
|
1008541…
|
stephan
|
255 |
JSON reply described in the [/chat-poll |
|
c64f28d…
|
drh
|
256 |
documentation](/help/www/chat-poll). The message text is translated |
|
9428699…
|
andygoth
|
257 |
into HTML before being converted to JSON so that the text can be |
|
1008541…
|
stephan
|
258 |
safely added to the display using assignment to `innerHTML`. Though |
|
1008541…
|
stephan
|
259 |
`innerHTML` assignment is generally considered unsafe, it is only so |
|
1008541…
|
stephan
|
260 |
with untrusted content from untrusted sources. The chat content goes |
|
9428699…
|
andygoth
|
261 |
through sanitization steps which eliminate any potential security |
|
1008541…
|
stephan
|
262 |
vulnerabilities of assigning that content to `innerHTML`. |