Repository navigation
Releases
Releases · dinghy-chat/dinghy
Dinghy 0.33.1
Fixed
- The operator app's address follows the screen, so a reload or a copied link stays on it. Contacts, one contact, Visitors and Analytics have their own addresses, and the Inbox's address names the open conversation. Before, every screen but Settings was at
/, and a reload went back to the Inbox. Back leaves a view, and moving through conversations or contacts does not fill the history.
Image: ghcr.io/dinghy-chat/dinghy:0.33.1
Dinghy 0.33.0
Changed
- The operator app shows a skeleton in the shape of each screen while it loads, in place of the boat and "Loading...": the sidebar and the Inbox on start, the conversation, Contacts, Analytics, Visitors and the settings pages. It fades in only after 0.3 s, so a quick load shows nothing. While the Inbox's first list loads, it no longer says "Nothing is waiting for you."
Image: ghcr.io/dinghy-chat/dinghy:0.33.0
Dinghy 0.32.0
Changed
- A visitor's reply by email from an address other than their email now names that address: Replied by email from ada@example.org. API: messages with
via: "email"havefromAddress, the address or null, in place offromOtherAddress. Replies stored before this change read as from the visitor's email.
Image: ghcr.io/dinghy-chat/dinghy:0.32.0
Dinghy 0.31.1
Fixed
- 0.31.0 has no image, because a test of the two-step removal request raced on the release's runner. This release holds the same changes as 0.31.0.
Image: ghcr.io/dinghy-chat/dinghy:0.31.1
Dinghy 0.30.1
Fixed
- 0.30.0 has no image, because the release's upgrade check still sent images to the route that 0.29.0 renamed. This release holds the same changes as 0.30.0.
Image: ghcr.io/dinghy-chat/dinghy:0.30.1
Dinghy 0.29.0
Upgrading
- Behind your own reverse proxy, accept request bodies of at least 11 MB, such as
client_max_body_size 11m;in nginx, because a file in the chat can be 10 MB. The bundled Caddy needs no change. - To turn on replies by email behind your own reverse proxy, accept 26 MB on
/v1/inbound-email, such asclient_max_body_size 26m;in an nginxlocation = /v1/inbound-emailblock, because an email can be 25 MB. A smaller limit makes the forwarder reject large emails for good. Self-hosting has the block. - Existing workspaces keep visitors' files off, so no visitor starts sending files after the upgrade. Turn them on in Settings > Appearance with Visitors can send files.
IMAGES_ORIGINis nowUPLOADS_ORIGIN; the old name still works until the next release.- If you set
UPLOADS_ORIGINand your site has a Content Security Policy, allow that origin inconnect-srcas well asimg-src, because the chat fetches a file to save it. - API: the upload routes
POST /v1/widget/{key}/imagesandPOST .../conversations/{conversationId}/imagesare now.../uploads, with no alias, because they take files as well as images. - API: in a workspace's settings,
usage.imageBytesis nowusage.uploadBytes, anddeletion.imagesis nowdeletion.uploads, as both count files too. - API: a message's
imageandimageRemovedare now oneattachment, in every answer, stream event and webhook:{ type: "image", url, width, height },{ type: "file", url, name, size },{ type, removed: true }once Dinghy Cloud deleted it after 12 months, or null.kindstays as it was.
Added
- Saved replies: the team writes common answers once in Settings > Saved replies, and anyone inserts one by typing / in the reply or note box, then changes it before sending. Every member can add, change and delete them, up to 200 per workspace. MCP has
list_saved_replies, so a bot can answer in the team's words. API:GET .../saved-replies, andPOST,PATCHandDELETEwith a session. - Files in the chat: visitors and operators send a PDF, TXT, CSV, LOG, JSON, ZIP, Word, Excel, PowerPoint, OpenDocument text or spreadsheet, MP4 or MOV file of up to 10 MB beside images. The chat shows its name and size. A file only downloads and never opens in the page. Visitors can send files in Settings > Appearance is on for new workspaces and off for existing ones, and operators can always send files. Exports carry files. On Dinghy Cloud, files count toward the 1 GB of storage and go after 12 months, as images do. Dinghy does not scan files for viruses. API: the upload routes take the file's name as
filenamein the query and answerkind: "file"withattachment: { type: "file", url, name, size }, a conversation'slastMessagehas itskind, a contact's conversations havelastKind, and the widget setting isvisitorFiles. - Mentions in notes: type @ in a note to pick a teammate. Each member a note mentions gets an alert with its text, by push and by email as their alert settings say, and the conversation is unread for them. An edit alerts only the members it newly mentions. A pick mentions the member picked, even when two members share a name. API:
mentionson a note, and on MCP'sadd_note. - Business hours: Settings > Business hours sets a time zone and up to 3 ranges a day. Outside them the widget shows the away message and "We're back Monday at 9:00 AM" on the visitor's own clock, with the date when that is more than 6 days away, even when a member is online, and asks for an email: before the first message, or after it for a visitor who has chatted. Visitors can still write. The widget gets the hours with its appearance. API:
GETandPUT .../business-hours. - The widget speaks English, French and Spanish. Language in Settings > Appearance picks one, or Visitor's language, the first of the browser's languages that the widget speaks. New workspaces start with the visitor's language, and existing ones keep English.
data-localeandDinghy.configure({ locale })win over the setting. The chat loads French or Spanish as a small file of its own, so the loader carries no translation. The team's own texts stay as written. The visitor's reply emails, transcripts and chat page follow the widget's language, with dates in that language, and the visitor panel shows it. API: the widget settinglanguage, andlocalein the widget's context report and on a conversation'svisitor. - Visitors reply by email: with
INBOUND_EMAIL_DOMAINandINBOUND_EMAIL_SECRETset, each reply email and transcript has its own reply address, and the visitor's answer goes into that conversation, reopening it if closed, as their message. Dinghy keeps the text above the quote of its email, and up to 5 attachments with the chat's checks and limits. The team sees Replied by email under it, or Replied by email from another address. Automatic answers are dropped, and an address takes 20 emails an hour and lasts 90 days after its last use. Self-hosting has a Cloudflare Email Worker for it. Off by default. API: mail reaches the newPOST /v1/inbound-emailas raw MIME, signed with the secret, and such messages havevia: "email"andfromOtherAddress. - Two-step sign-in for operators. Profile turns it on with a QR code for an authenticator app and shows 10 single-use recovery codes once. It also shows how many are left, and makes a new set with a code from the app. Each new sign-in then asks for a 6-digit code after the email link, and Settings > Team shows who has it on. A server's admin turns it off for an operator who lost their authenticator app with
chat two-factor-reset <email>. With a mail server, the account gets an email when it is turned on or off, by the operator or the admin, when a recovery code is used, and when too many wrong codes lock it. API:/v1/operator/two-factor/setup,enable,check,recovery-codesanddisable, andtwoFactorandrecoveryCodesLeftin/v1/operator/me. - Removal of two-step sign-in for an operator who lost their authenticator app and their recovery codes. Lost your authenticator app and your recovery codes? on the code screen, within 15 minutes of an email link, asks to remove it after 72 hours, only when someone else can stop the request: another owner or admin of one of the account's workspaces, or another unexpired session that passed the check. The worker emails the account a cancel link, pushes to its devices and emails the owners and admins, and tries a failed send again. The 72 hours count from that warning, and the request never completes before it. It emails the account again 24 hours before the end. Every session that passed the check shows a banner with Cancel the request at once, and Settings > Team marks Removal requested. A correct code also cancels it. A cancel signs out the sessions that never passed the check, blocks new requests for 7 days and tells the account to secure its email. With nobody to stop it, the screen points to a manual review: Dinghy Cloud's address, or the server's admin. Owners and admins can also reset a lower-ranked teammate who is in no other workspace from Settings > Team. After a removal or a reset, the next sign-in asks to turn it on again. API:
POST /v1/operator/two-factor/removal,.../removal/cancel,/v1/account/two-factor-removal/cancelwith the link's token,.../two-factor/skip-promptandPOST .../members/{operatorId}/two-factor-reset,removalCompletesAtandasksTwoFactorAgaininme, andtwoFactor: "removal_requested"andcanResetTwoFactoron members. Ateam.changedevent now also makes the operator app readmeagain. - Recovery codes have 16 letters in 4 groups, 80 random bits in place of 50. Codes made before keep working.
- Labels: put colored labels on conversations, such as billing or bugs, with L or the tag button in a conversation. Anyone on the team adds one by typing its name, up to 100 per workspace, and owners and admins rename, recolor and delete them in Settings > Labels. The Inbox filter lists the conversations with one label, rows and the conversation header show them as pills, and Analytics counts the period's conversations by label. MCP has
list_labels,label_conversationandunlabel_conversation, and itslist_conversationstakes alabel. API:GET .../labels,PUTandDELETE .../conversations/{conversationId}/labels/{labelId}, which change one label at a time, and theconversation.labeledwebhook for each change, withlabel: { id, name, color }andaction,addedorremoved. - Bulk actions in the Inbox: choose conversations with the box on each row, X, Shift for a range, or a long press on a phone, and the box beside the count chooses every row. Then close, assign, label, mark read or, for owners and admins, delete them at once. Each changes as it would alone, with its own event and webhook, and a read-only or suspended workspace can still mark them read. API:
POST .../conversations/bulkfor up to 100 conversations, with a result for each.
Security
- With two-step sign-in on, a session that has not passed the check gets 401
two_factor_requiredeverywhere butme, the check and sign-out, including the event stream at each wake, an upload's end and OAuth consent. 5 wrong codes in 15 minutes end the session, and the check answers 503check_unavailablerather than skip that limit when Valkey does not answer. The TOTP secret is encrypted with a key derived fromAUTH_SECRET, and the recovery codes are stored as keyed hashes, so after a change ofAUTH_SECRETthe check and the turn-off answer 500two_factor_unreadableuntil the admin runschat two-factor-reset. API keys are not affected. API:too_many_attempts,check_unavailableandtwo_factor_unreadableon `/v1/operator/two-factor...
Dinghy 0.28.0
Changed
- The keyboard shortcuts list is easier to scan: a close button, keys that read G then I, and the switch for single keys in its own panel. Documentation in Help shows that it opens a new tab.
- In the sidebar, the Inbox and Visitors counts sit at the right edge. With the pointer on a view, its keys take the count's place.
Fixed
- A visitor signed in with
Dinghy.identify(async () => token)now gets a country and a time zone, and shows as known in Visitors. Before, the widget sent their beat without the token, so the contact had no country.
Image: ghcr.io/dinghy-chat/dinghy:0.28.0
Dinghy 0.27.0
Added
- Keyboard shortcuts in the operator app: ? lists them, / searches, G then I, C, V, A or S opens a view, J and K move through the Inbox, R and N write a reply or a note, E closes the conversation and opens the next one, A and I assign, . opens the … menu, and P shows the visitor's panel. Esc leaves the reply box. The app shows each key where it applies, and a switch in the list turns the single keys off for this browser.
- Help in the sidebar, with the documentation and the keyboard shortcuts.
Image: ghcr.io/dinghy-chat/dinghy:0.27.0
Dinghy 0.26.0
Changed
- With a mouse, Snooze in the … menu opens its choices beside the menu on hover. On a phone it still opens them in place.
Fixed
- The reply box keeps its height when you switch between Reply and Note, as Add note is now as tall as the send button.
Image: ghcr.io/dinghy-chat/dinghy:0.26.0
Dinghy 0.25.0
Changed
- The … menu has one Snooze item, which opens its choices in place, with a row to go back. The right arrow opens it and the left arrow goes back.
- A signed detail that links to a page ending in an ID, such as
organization: https://example.com/admin/organizations/org_8f2k1, shows the ID and still opens the page. Its copy button copies the ID. - The conversation's side panel no longer shows the last page, which Pages visited already lists. A click on the visitor's email copies it.
- Reply and Note above the reply box are a small switch with an icon each, and Note turns yellow when chosen.
Fixed
- In dark mode, menus, popovers and modals stand out from the page, on a lighter card with a pale edge over a darker backdrop.
Image: ghcr.io/dinghy-chat/dinghy:0.25.0