Repository navigation
Releases: petar-basic/chat-systems
Releases · petar-basic/chat-systems
Release list
Chat Systems 4.1.1
Upgrading from 4.1.0
- Set
VERSION=4.1.1, pull both images and restartapi,realtimeandfrontendtogether.
There is no migration and no new setting. The desktop app updates itself to 4.1.1: it finds the
release within six hours, or at its next start, and asks to restart.
Fixed
- Notifications from the desktop app pop up on Windows. They were sent under PowerShell's app id
instead of the app's own, which Windows does not show as the app's banner. - In the desktop app the sign-in page reads "Sign in to" the server's name and asks only for
your email and password, or SSO. It used to ask for the server's address again, which the
app already had, and offered to connect to a different server from inside this one's window. - In the desktop app, ⌘1 to ⌘9 (Ctrl on Windows) open the first nine workspaces on the rail, in
the rail's order. They used to switch between servers, so with two servers only ⌘1 and ⌘2 did
anything. The Workspaces menu lists the same entries, and each rail tooltip shows its
shortcut. - The desktop rail shows each workspace's uploaded icon instead of its initials. The rail
loaded the icon without the server's session, which the server refuses; the server's page now
draws it and hands it to the rail. - Joining or leaving a workspace shows up live. Someone who accepts an invite now sees the new
workspace in their other tabs and in the desktop rail without a reload, and the members who
stay see the member list change when someone joins or leaves. Before, only the person who
left was told. - A channel's member count and member list refresh when they change. The channel header loads
its members, pins and bookmarks in one request and kept that answer for five minutes, so
after the first half minute a refresh got the old list back.
Chat Systems 4.1.0
Upgrading from 4.0.2
- Set
VERSION=4.1.0, pull both images and restartapi,realtime,workerandfrontend
together. There is no migration and no new setting: SSO from the desktop app uses the SSO you
already have.
Added
-
A desktop app for macOS and Windows, attached to every release from this one on. It opens
any Chat Systems server, and several at once:- one rail with every workspace you are in on every server, the server's name in each tooltip;
- native notifications that open the message on a click, and the unread count on the Dock
and the tray; - closing the window keeps it running in the tray, and it can open at login;
- Sign in with SSO goes through the system browser and comes back to the app signed in;
- the rail and the title bar follow the page's light or dark theme;
- it updates itself from the latest release, and installs only updates signed with the
project's key.
It is not signed with an Apple or a Windows certificate yet, so each system warns the first
time you open it; desktop/README.md says how to open it. -
Leave workspace… in the workspace menu and on the desktop rail. An owner cannot leave, and
is told so. -
Setting up two-factor shows a QR code of the setup link, drawn in the browser, so a phone's
authenticator can scan it from a computer screen. -
The RUNBOOK explains authentik in front of an LDAP directory,
for signing in with directory accounts through SSO.
Fixed
- Being removed from a workspace or a private channel, or leaving one, takes you to another
workspace or channel at once, instead of leaving "Something went wrong" on the one you lost. - Someone in no workspace at all sees "You're not in a workspace yet" and how to create one or
be invited, instead of an empty page; an old link to a workspace they left opens the app. - The sign-in, invite and password-reset pages follow the light or dark theme you chose. They
were always dark until a workspace had been opened. - The background blur in a huddle loads the MediaPipe files that match its library (1.2.0)
instead of an older version's.
Chat Systems 4.0.2
Upgrading from 4.0.1
- Set
VERSION=4.0.2, pull both images and restart. Only the frontend changed, and there is no
migration.
Fixed
- A failed sign-in says why: a wrong password reads "Invalid email or password" and a wrong
second-factor code "That code did not match", instead of "Your session expired" for every
failure. The same goes for an invalid invite or reset link.
Added
- Forgot password? on the sign-in form. It opens the reset page with the email already filled
in; the emailed link works for an hour, and setting a new password signs out every device. The
reset pages match the sign-in page.
Chat Systems 4.0.1
Upgrading from 4.0.0
- Pull both images and restart
api,realtime,workerandfrontendtogether so all four
run 4.0.1; there is no migration.
Fixed
- Renaming a workspace shows the new name at once in the sidebar header, the tab title, the
checklist and the notifications menu, instead of after a reload. - Workspace settings → Apps waits for the connected apps before showing the directory, so the
list no longer jumps under the pointer while it loads. - Opening a thread puts the cursor in its reply box, so what you type next goes to the thread
instead of the channel. On a touch screen it waits for a tap, so the keyboard does not cover the
thread. - The @mention and :emoji: suggestions stay inside the window: near the right edge, as in a
thread's reply box, they open leftwards instead of running off screen. - A deleted message disappears at once, as it does after a reload. Only a message with
replies stays behind as "This message was deleted", so its thread can still be opened. - A workspace icon that fails to load shows the workspace's initials instead of a broken
image, in the workspace rail and in workspace settings. - Opening a workspace no longer flashes "No channels yet" while its channels are still
loading. - The getting-started checklist lays its steps out by its own width, so they no longer wrap
beside a side panel, and on a phone it starts folded to one line with "Show steps". - Creating a workspace opens it, instead of sending you back to the workspace you were in.
- A message that arrives while a channel is still loading its history shows up at once,
instead of only after the channel is opened again. - A custom emoji added or removed by someone else shows for everyone at once, instead of as
its:name:until a reload. - The emoji picker offers only the open workspace's custom emoji. After visiting another
workspace it used to keep offering the first one's.
Changed
- Typing
/at the start of a message lists the slash commands this workspace knows, with
what each one takes. An unknown command is no longer posted as a message: it is refused with
a note, and stays in the composer to fix. - Workspace settings → Apps keeps the setup of an app nobody has set up folded behind
"Set up", so five setup forms no longer fill the page. - Preferences, Workspace settings and Channel details keep one height whichever tab is open,
and their tabs stay in view while the section scrolls. A workspace setting that saves on its
own says "Saved" beside the field that changed. - "(edited)" sits at the end of the message text, and reactions sit above the "1 reply" link.
- Search marks the words that matched in each result, and a long channel name no longer
pushes the sender's name onto two lines. - The sidebar's People section says when you are the only one there, with Invite people for
admins. - The RUNBOOK's Huddle SFU (LiveKit) covers a Coolify host: fetching the compose file without
a checkout, theufwrule that lets the proxy reach LiveKit (without it,504after thirty
seconds), a DNS name that bypasses Cloudflare's proxy, and the Traefik file. How many people
one LiveKit holds explains the hundred-person bound and how to measure your own host.
Chat Systems 4.0.0
Upgrading from 3.7.0
- Set
SECRETS_KEYSbefore you upgrade:echo "k1:$(openssl rand -base64 32)", on the
apiand theworker. Both refuse to start without it. KeepJWT_SECRETunchanged for
this start: theapire-seals what 3.7.0 sealed with it (see the RUNBOOK upgrade note). - Set
JWT_SIGNING_KEYSandJWT_PUBLIC_KEYSbefore you upgrade (the commands are in
.env.exampleand the RUNBOOK): the private keys on theapiand theworker, the public
halves onrealtime. Upgrade all three together. Everybody is signed out once, because
the HS256 sessions 3.7.0 issued are refused. RemoveJWT_SECRETonce theapihas logged
that every stored secret is on aSECRETS_KEYSkey. - Migration 82 adds
users.manual_away; migration 83 adds a key id beside every sealed
secret; migration 84 addscommand_invocations; migration 85 addsusers.is_bot,
bot_appsandhooks.app_id; migration 86 adds the event settings tobot_apps,
app_deliveriesandapp_sockets; migration 87 addshuddle_sessions.livekit_room. - For WebSocket clients:
presence.batchandpresence.changedcarryawayas well as
onlineandoffline, andpresence.changednow also reaches the person it is about.
For API clients:PUT /users/me/presencewith{ "away": true }sets yourself away. - For WebSocket clients: a
command.responseframe carries a slash command's late answer to
whoever ran it. For slash-command apps: the payload hasrequest_idandresponse_url,
the request anX-Chat-Request-Idheader, and an empty 2xx body now means answering
later instead of an error. - For API clients:
MemberWithUserhasis_bot,Hookhasapp_id, and the routes a bot
token may call carry thebottag and security scheme in/api/openapi.json. - For API clients:
GET /workspaces/{id}/app-directorylists what is connected and
POST /workspaces/{id}/app-requestsasks the admins for an app (10 an hour per person). - If something other than the bundled nginx sits in front of
realtime, route/ws/appsto it
as you route/ws: socket-mode apps connect there. For WebSocket clients:channel.updated
is now in the replay log, and achannel.createdevent is published when a channel is made. - Nothing to do for the huddle SFU unless you want it: LiveKit is a separate, optional compose
file, and withoutLIVEKIT_URLevery huddle stays on the mesh as before (see Huddle SFU
(LiveKit) in the RUNBOOK). To turn it on, setLIVEKIT_URLonrealtimeas well as on the
api;HUDDLE_SFU_THRESHOLD(6) andHUDDLE_SFU_MAX_PARTICIPANTS(100) are optional.
For API clients:POST /huddles/{id}/sfu-token. For WebSocket clients:huddle.members
carries the huddle'stransport, andhuddle.transportsays a huddle moved to the SFU.
Added
- Away. You → Set yourself away (or
/away) shows you away to everyone, in every
workspace and on every device, until you set yourself active. Ten minutes without using the
app shows you away too, and the next keystroke shows you active. - Slash commands that take their time. A command's app may answer at once, or acknowledge
and answer up to five times in the next 30 minutes through aresponse_url, in the channel
or only to whoever ran it. An app that does not answer in three seconds is tried twice more
with the same request id, and the person sees taking a moment… instead of an error. - Apps with a bot user. An admin makes an app in Workspace settings → Apps with the
scopes it needs and gets a token for it. With that token the app posts, replies in threads,
reacts, uploads, reads history, opens DMs and looks people up through the same API the web
client uses, only in the channels it has been added to. Its messages carry an APP label,
what it changes is in the audit log under the app, and removing it revokes the token and
its slash commands. docs/bot-api.md is the guide, and
examples/echo-bot a bot in one file. - Events for apps, over HTTP or a socket. An app subscribes to messages, mentions,
reactions, people joining, and channels being made or archived, in the channels its bot is
in. Events are posted, signed, to a request URL that has answered a challenge, and retried
for an hour, after which the app shows as failing; or, in socket mode, an app-level token
opens sockets to the instance that share the app's events and its slash commands, so an app
behind a firewall needs no public URL. Delivery is at least once and in order per channel,
and survives a restart of the worker or the gateway. - An app directory. Workspace settings → Apps lists everything connected to the
workspace: connected apps, the workspace's own apps, webhooks, slash commands and workflows,
each with who added it and when, what it can do in plain words, the channels it touches and
whether it is working. Each has a page with Reinstall, Rotate token and Remove, and the
channel's Integrations section links to it. A new app gets its token, and a connected app is
set up, only after an admin agrees to what it may do, and giving an app another scope asks
again. Members see the directory read-only, without what touches channels they cannot see,
and can ask the admins for an app. - LiveKit beside the stack, for large huddles.
docker-compose.livekit.ymlruns a
LiveKit SFU next to the app, and the API signs a ten-minute token for one huddle's room
after the same check the realtime gateway runs on join. A huddle moves to it mid-call when
a join takes it past six people, and nobody's audio drops on the way: each browser keeps
the mesh playing until it hears everyone over LiveKit. On LiveKit a huddle holds up to 100.
Security
- Stored secrets have keys of their own. Connected apps' client secrets and tokens, TOTP
secrets and the setup token are sealed withSECRETS_KEYSinstead ofJWT_SECRET.
RotatingJWT_SECRETno longer breaks every connected app and second factor, and
SECRETS_KEYSrotates on its own: add a key, put it first, restart, and the API re-seals
everything, so nobody sets an app up again or reconnects. - Sessions are signed with Ed25519, and the realtime gateway can no longer sign one.
Tokens are EdDSA with akid; the API and the worker hold the private keys and the gateway
only the public halves, so a leaked gateway configuration mints nothing. HS256, unsigned
tokens and unknown key ids are refused. Signing keys rotate without signing anybody out:
add a key, promote it, retire the old one after the refresh-token lifetime.
Chat Systems 3.7.0
Upgrading from 3.6.0
- Pull both images and restart
api,realtime,workerandfrontendtogether; the API
runs migrations 80–81 on start, which addslack_channels.created_by_importand lowercase
every email address, so snapshot first. On its first start the worker moves workspace photos
into the object store'savatars/prefix and workspace icons intoicons/, outside file
retention (see the RUNBOOK upgrade notes); going back to 3.6.0 means restoring the snapshot. - Check for addresses that differ only in case. Migration 81 refuses mixed-case addresses
from then on. If two accounts differ only in case it stops before changing anything and names
them, and theapidoes not start until one is erased or given an address of its own; the
RUNBOOK says how. - Channels mapped by an earlier Slack import count as ones it merged into, so a re-run never
archives them. - Reactivating an account that has no password and no SSO link (an imported Slack leaver), from
the admin page or with SCIMactive: true, leaves itpendinginstead ofactive; invite
the person to let them in. - For API clients:
DELETE /admin/users/{id}/datareportsremoved.edits,reactions,
votes,comments,scheduledandfilesbesidemessages. Taking over a workflow
gives it a newwebhook_url, andPOST /workflows/{id}/rotatemakes one on demand; the
old URL answers 401 in both cases. - For API clients:
POST /conversations/{id}/readis gone; a conversation is read like a
channel,POST /channels/{id}/readwith the message read up to. Unread counts carry
last_read_atand a first message pagelast_read_before_at, the time of the read. - For API clients: a workspace photo is uploaded with
POST /workspaces/{id}/profile/avatar
and a workspace icon withPOST /workspaces/{id}/icon; either uploaded through
/files/uploadis an ordinary file and no longer readable by the workspace.
PATCH /hooks/{id}with{ "is_active": true }turns a stopped hook back on. - For API clients:
POST /workspaces/{id}/invitesanswersemail_status(sent,
not_configured,failed, ornullfor a link invite) instead ofemail_sent. Search hits
from/searchand/search/filescarrychannel_name. A reply to a deleted root with no
replies left answers 404 instead of 422.
Security
- SSO lets nobody around a suspension. An account already linked to the provider was
signed in without its status being checked, so a suspended or erased person got a session
through SSO. Erasing an account now also removes its SSO link. - A hard erase removes everything they wrote. A message others answered kept every earlier
version in its edit history, and their files, reactions, votes, list comments, scheduled
messages and the notifications quoting them stayed. All of it goes now, files with their
stored objects. - A hook stops when its creator loses the role. An outgoing webhook or slash command made
by an admin who is now a member kept sending channel traffic; it turns off, saying why. - A taken-over workflow gets a new URL. The old owner could still start it from the link
they knew. New URL in the workflow replaces it at any time. - A Slack import keeps out of private channels. A private Slack channel merged into a local
private channel of the same name, adding Slack's members to it and its history to theirs.
Private channels never merge now; a taken name becomes<name>-slack. - A re-import leaves a merged channel open. Running an import again, or Start again,
archived a local channel the first run had merged an archived Slack channel into. - An archived channel is read-only all the way. Editing, deleting and pinning a message,
voting in a poll, adding or removing members, bookmarks, renaming and starting a huddle still
changed an archived channel; every one answers 403 now, and the client hides them. - A guest calls only whom they could message. Starting a DM huddle checked only that the
other person was in the workspace, so a guest could ring a member they could not message, and
invite them into a huddle. Both follow the DM rule now.
Fixed
- An archived private channel can be found again. The sidebar leaves archived channels out
and Browse channels listed public ones only, so nobody could reach one to unarchive it. Browse
now lists those you are a member of, under the archived public ones. - A message that arrives while a channel opens is shown. The first page of a channel was
still loading when a new message came in over the socket, so the message was dropped until
the next reload. It now reloads the page instead. - Read state matches what you read. Mark all read could leave a channel's read position
on a reply kept in its thread, so opening it loaded the whole history looking for it. A
mention in a reply also sent to the channel stayed unread after reading the channel, and its
email went out. A reply notification under a deleted message opened nothing, a DM opened at
an old New line, and a keyword quoted in a forward alerted its owner. Each now behaves as
it does in a channel. - A failed send stays where you sent it. A reply from the Threads view that failed
vanished from its card, a failed message was lost on reload, a send the server took just before
the request failed showed twice, and scheduling dropped a file that had failed to upload. The
card shows the failed reply with Retry and Discard, failed messages survive a reload, a
delivered message never keeps a failed copy, and scheduling refuses a failed file as sending
does. - An address works in any case. An invite to
Ana@Firma.commade an account SSO could not
find asana@firma.com, so it refused or made a second one, and signing in with the password
needed the exact case. Addresses are stored lowercase now. - A workspace photo stays. It was a file of that workspace, so file retention deleted it with
old attachments. It has a place of its own now, shown to that workspace's members. - A stopped hook can be turned back on. One switched off because its creator left or lost
the channel could only be deleted and made again; Integrations has Turn on, and whoever
turns it on becomes its creator. - Push goes to the device you are using. A laptop shut mid-use counted as active for up to
two and a half minutes, holding back push to the phone; it now stops within about 30 seconds,
and leaving or hiding the page says so at once. The push badge counted notifications from
workspaces you had left, and a desktop notification from a second server opened nothing. The
badge now matches the app's, and the click opens the message on its server. - The survey's small things. A search hit from a public channel you are not in names its
channel. A thread whose deleted root lost its last reply shows no composer. An export's date
range covers edits, reactions, polls and votes, not only messages and files. An invite whose
email failed says so instead of claiming email is not set up. A card in Threads has
Also send to and scheduling, as the thread panel does. - Everyone sees the workspace icon, and it stays. It was an ordinary file with no message,
so only the admin who uploaded it could load it, file retention could delete it, and a
replaced one was never removed. It has a place of its own now, shown to the workspace's
members.
Chat Systems 3.6.0
Upgrading from 3.5.0
- Pull both images and restart
api,realtime,workerandfrontendtogether; the API
runs migrations 75–79 on start, which add thehuddle_invitestable,
hooks.disabled_reason, a thread target on scheduled messages, one pending mention email
per person and message, andslack_imports.heartbeat_at, so snapshot first. On its first
start the worker moves every account photo into the object store'savatars/prefix (see
the RUNBOOK upgrade note); 3.5.0 cannot read photos there, so going back means restoring
the snapshot. - Re-send pending email invites. An emailed invite link now names the invite it stands
for, and links sent before the upgrade do not: they answer Invalid or expired invite.
Revoke and re-send any email invite that has not been accepted yet. Shared invite links are
unaffected. - For WebSocket clients:
huddle.joinneeds onlyhuddle_id;channel_id,workspace_id
anddm_partner_idare ignored. - For API clients:
GET /messages/{id}/threadtakeslimitandcursorinstead of
offset, returns the newest replies first, and includes reactions. A deleted message with
replies is listed as a tombstone (deleted_atset, emptycontent). - For API clients:
copy_attachments_fromonPOST /channels/{id}/messagesis now
forwarded_from; it also recordsmetadata.forwarded_from. - For API clients: reading a channel no longer marks its threads' notifications read;
POST /threads/{id}/readdoes. A push'sbadge_countis the total across workspaces, and a
thread reply not sent to the channel no longer counts in the channel's unread counters. - For WebSocket clients: send
{ "type": "activity", "active": bool }when the person starts
or stops using the app. Push is held back only while a session says it is active, so a
client that never sends it gets push even with its socket open. Ahuddle.ringto somebody
who paused the workspace is no longer delivered. - For API clients:
POST /users/me/avatartakes a multipartfileand sets the account photo.
An account photo set withPATCH /users/meto a workspace file is no longer readable to the
workspace. - For API clients:
ImportRuncarriesretryable, and
POST /workspaces/{ws_id}/slack-imports/{import_id}/retryqueues a failed run again. An
import report countsguests,users_suspendedandchannels_archived. - Building the frontend image yourself: pass
--build-arg PREVIOUS_IMAGE=<the frontend image you run now>to keep its chunks for tabs opened before the upgrade, and
--build-arg APP_VERSION=<version>to name the build. A proxy in front of the frontend
should not cacheindex.htmlorversion.json; nginx now sendsno-cachefor both. - For API clients: posting, reacting, scheduling and incoming webhooks answer 403 on an
archived channel.POST /channels/{id}/unarchiveundoesDELETE /channels/{id}, both
publishchannel.updated(is_archived), and Browse channels lists archived channels
withis_archived. - For API clients:
POST /workspaces/{id}/invitesreturns the invite withinvite_urland
email_sent, andGET /workspaces/{id}/invites/{invite_id}/linkhands out a pending email
invite's link again. An emptySMTP_HOSTnow means no email: invites say so instead of
claiming they were sent.
Security
- A private channel's huddle is its members'. Joining a huddle is checked against the
huddle itself: its channel's members, the two people of a DM huddle, or someone invited
from inside it. Active huddles lists only channels you are in, and only someone in a
huddle can invite to it. - An email invite ends when the invite does. Revoking it, its expiry and its use limit now
stop the emailed link too, and the role it grants is the one the invite has today. - A private channel's member list is its members'.
GET /channels/{id}/membersfollows
the same access as reading the channel. - A suspended or removed person stops acting. Suspending or erasing an account turns off
every webhook, slash command and workflow that person set up, and removing someone from a
workspace turns off theirs there; activating the account again does not turn them back on.
Each scheduled message, workflow run and webhook also checks its author when it fires: a
suspended author's scheduled message fails withauthor_inactive, and a webhook whose
creator can no longer read its channel turns itself off and says why under Integrations. - A workflow whose builder left can be taken over. A workspace admin opens it under
Workflows and chooses Take over; it becomes theirs, stays off until they turn it on, and
the audit log records it. - A private Slack channel stays private. The Slack import merges a channel into an
existing one of the same name only when both are the same kind; otherwise it imports it as
<name>-slackand says so in the report.
Fixed
- Opening a message lands on it. From Activity, a desktop notification, a phone push or
search, a direct message opens its conversation, a thread reply opens its thread scrolled to
it, and a public channel you have not joined opens on the message with Join channel. Old
message links resolve the same way, and a message that is gone says so instead of opening
#general.GET /messages/{id}/locationsays where a message lives; push payloads and the
notificationframe carrythread_parent_id. - Search goes past twenty. Show more pages through message and file results.
- Threads keep up. A long thread reads back to its first reply with Show earlier
replies. Deleting a reply takes it off the count, and an open thread shows other people's
reactions, pins and deletions as they happen. A deleted parent with replies stays as This
message was deleted, so its thread stays together; retention removes a thread once its last
reply is past the period, and no reply ever appears in the channel on its own. Replies can
be sent to the channel too with Also send to #channel, and scheduled from the thread
composer. - Sending never loses work. A message or thread reply that fails to send keeps its text
and files, survives a refresh of the list, and offers Retry (with the same files) or
Discard (back into the composer). Files in the composer stay with their channel when you
switch away, and a file that failed to upload says why and must be retried or removed
before sending. A scheduled message that failed shows the reason with Send now and
Remove. Forwarding a message no longer notifies the people or the@channelin the
quote. - Unread, Activity and the badge agree. Reading a channel or DM clears its Activity rows,
reading a thread clears the thread's, and a message or mention that arrives in the channel
you are looking at is read at once instead of leaving a badge. A reply kept in its thread no
longer marks the channel unread. A mention from another workspace no longer lands in the
open one's sidebar, and the app icon always shows the total across workspaces, push
included. A channel with unread messages opens on the first of them under the New line,
also on a fresh load, with Jump to first unread while it is above the view; New
messages sits over the list again instead of under it. - Notifications arrive once, where they should. Email me what I missed goes out for a
mention or DM still unread five minutes later, whether or not a push was sent, never for one
you have read, once however often the event is redelivered, and with a link to the message
(or the workspace, for several). An open tab nobody is using no longer holds back push:
push waits only while a window is in front and in use. A paused workspace does not ring for
huddles, and the pause menu names the workspace it pauses. A webhook's creator is notified
of what their hook posts, under the bot's name. Preferences → Notifications has the
Desktop notifications while the app is open switch, and a desktop notification and a push
about the same channel replace each other instead of showing twice. - Waking up reconnects, and a deploy no longer breaks an open tab. The socket reconnects
as soon as the network comes back or the tab is shown again, instead of waiting out its
backoff, and a socket left half-open by sleep is replaced within two seconds. Switching to
a workspace you joined after connecting shows you online there at once. A gap too long to
replay now also refreshes unread counts, pins and the sidebar. After a deploy, an open tab
shows A new version is available with Reload, a lazy page or the emoji picker whose
chunk is gone reloads once onto the new build, and release images keep the previous
release's chunks. - An archived channel is closed. Nothing can be posted, reacted, scheduled or sent by a
webhook into it; its composer becomes an Archived bar, and workspace admins and the
channel's admins can Unarchive it there. Archiving and unarchiving post a line in the
channel and reach everyone viewing it at once. - An export without DMs has no DM files.
files.jsonlfollows the same DM choice and date
range as the messages. - A retention audit row counts its own workspace. Each workspace's Retention purge entry
used to carry the totals of every workspace purged before it in the same run. - Joining a channel you were looking at goes live. After Join channel on a channel opened
without being in it, new messages and changes arrived only after a reconnect. - Inviting works without email. Every invite shows its link to copy, and the form says
when email is not set up instead of Invite sent. Workspace settings → Members lists
pending invites with Copy invite link and Revoke. - SSO from an invite lands in the workspace. The invite page offers Continue with SSO,
and the invite is used on the way...
Chat Systems 3.5.0
Upgrading from 3.4.2
- Pull both images and restart
api,workerandfrontendtogether; the API runs
migrations 73–74 on start, so snapshot first. Migration 73 copies each live status into every workspace
the person is in (a custom emoji only where that workspace has it), then drops the status
columns fromusersand the unuseduser_preferencesandbookmarked_messagestables. - Migration 74 does the same for notifications: a running pause, the notification schedule
and the mention-email switch are copied into every workspace the person is in, and leave
users. Nobody loses a pause or a schedule. Both drop columns, so going back to 3.4.2
means restoring the snapshot. - For API clients:
PUT/DELETE /users/me/statusare now
PUT/DELETE /workspaces/{id}/profile/status, andUserPublicno longer has
status_emoji,status_textorstatus_expires_at. Members gainbio.
/notifications/dnd,/users/me/notification-scheduleand/notifications/emailare now
/workspaces/{id}/notifications/dnd,…/scheduleand…/email.
Added
- A profile of your own in each workspace. Name, photo, bio and status are set per
workspace in Edit profile; a status set in one workspace no longer shows in the others. A
name, photo or bio left empty shows the account's, edited in Preferences → Account. The
hover card shows the bio. API:GET/PATCH /workspaces/{id}/profile. - Notification settings of your own in each workspace. Pausing notifications (the You
menu, the Activity panel or/dnd), the notification schedule and Email me what I missed
apply to the workspace they were set in; the others keep notifying. Preferences →
Notifications names the workspace it changes.
Chat Systems 3.4.2
Upgrading from 3.4.1
- Pull both images and restart
api,workerandfrontendso all three run 3.4.2; there is no migration.
Fixed
- React with a custom emoji. The emoji picker has a Workspace category with the
workspace's own emoji, in the composer, on a message and for a workflow's reaction trigger.
A reaction used to be refused above eight characters, so:party-parrot:could not be one.
API:POST /messages/{id}/reactionstakes a:shortcode:the workspace has, and answers 422
for one it does not. - The status emoji comes from the picker, workspace emoji included, instead of a text box
that took any sixteen characters. A custom one shows as its image wherever the status does;
in a workspace without it, as its:shortcode:.
Chat Systems 3.4.1
Upgrading from 3.4.0
- Pull both images and restart
api,workerandfrontend; there is no migration.
Fixed
- Custom emoji show. Their image answered 404, because the download route only knew
uploaded files, so a custom emoji was a broken image everywhere: in Custom emoji, in
messages and in reactions. Anyone in the workspace can now load it, and a new one is stored
under its image type, so local storage serves it as an image. - Typing
:nameoffers the workspace's own emoji, first, above the standard ones;
choosing one inserts:name:.