You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/content/docs/developers/chats.mdx
+78Lines changed: 78 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -14,6 +14,12 @@ This document explains how Ecency's chat experience works and how other Hive app
14
14
-**Hive identity**: Users authenticate with their Hive account (access/refresh tokens). The bootstrap API validates those tokens before issuing a Mattermost PAT so the chat identity is bound to the Hive username.
15
15
-**Community mapping**: Hive communities map to public Mattermost channels named after the community id (e.g., `hive-123`). The bootstrap flow can auto-join users to channels for the communities they subscribe to.
16
16
17
+
### Realtime transport
18
+
19
+
-**Websocket proxy**: `/api/mattermost/websocket` is a passthrough to Mattermost's websocket upgraded connection. It upgrades on the edge runtime, forwards all frames bi-directionally, and injects the authentication challenge upstream using the `mm_pat` cookie created during bootstrap.
20
+
-**Auth flow**: Clients do **not** need to send the PAT manually; the proxy pulls it from the cookie, opens the upstream websocket derived from `MATTERMOST_BASE_URL`, and immediately sends Mattermost's `authentication_challenge` action with the PAT.
21
+
-**Error handling**: Missing cookies receive `401 Unauthorized`; invalid upgrades respond with `400`; upstream issues (e.g., Mattermost unreachable) respond with `502`.
22
+
17
23
## Using Ecency-hosted chat endpoints
18
24
19
25
Other Hive apps can call Ecency's `/api/mattermost/*` routes directly - **no Mattermost infrastructure required**. Key points:
@@ -32,6 +38,78 @@ Other Hive apps can call Ecency's `/api/mattermost/*` routes directly - **no Mat
32
38
3.**Call chat endpoints with the cookie**: Subsequent requests to `https://ecency.com/api/mattermost/*` automatically include the PAT cookie when `credentials: "include"` is set, enabling channel lists, posting, reactions, searches, and direct messages.
33
39
4.**Link back to your UI**: Use returned `channelId` or search endpoints to deep-link into chat surfaces within your app (e.g., from profiles or community pages).
34
40
41
+
### Realtime websocket usage
42
+
43
+
Use the websocket proxy to stream reactions, typing events, and post updates without exposing PATs to the browser:
44
+
45
+
```ts
46
+
// Requires the mm_pat cookie set by the bootstrap call above; same-origin
47
+
// requests automatically include it and allow the edge function to auth upstream.
// Handle new post payloads and update your UI accordingly.
61
+
}
62
+
});
63
+
64
+
socket.addEventListener("close", () => {
65
+
// Implement your own reconnection strategy as needed.
66
+
});
67
+
```
68
+
69
+
**Notes**:
70
+
71
+
- No token needs to be provided in the websocket URL or headers; the proxy pulls it from `mm_pat` and runs the `authentication_challenge` upstream for you.
72
+
- If the PAT cookie is missing or expired, the request returns `401` before upgrading. Re-run the bootstrap route to refresh it.
73
+
- The websocket endpoint is same-origin, so use `wss://<your-ecency-host>/api/mattermost/websocket` for staging or production as appropriate.
74
+
75
+
#### What websocket events look like
76
+
77
+
Mattermost emits typed events over the websocket. Each frame is a JSON object with an `event` name, a `data` payload, and per-event metadata (full schema in the [Mattermost websocket reference](https://developers.mattermost.com/api-documentation/#/#websocket-events)). Some of the most useful events for in-app chat surfaces:
78
+
79
+
-**`posted`**: A new post or reply was created. The payload includes the `post` object (stringified JSON), `channel_display_name`, and `team_id`. Parse the `post` field to get message text, attachments, and `root_id` (thread parent).
80
+
-**`post_edited`**: A user updated an existing message. Merge the `post` JSON with your existing message state.
81
+
-**`post_deleted`**: A message was deleted. The `data` includes `post` and `channel_display_name`; rely on `post.id` to remove it from the UI.
82
+
-**`reaction_added` / `reaction_removed`**: Reaction toggles with `user_id`, `emoji_name`, `post_id`, and `channel_id`.
83
+
-**`typing`**: Indicates a user is typing in a channel. Includes `user_id`, `channel_id`, and `parent_id` for thread typing.
84
+
-**`user_updated`**: Profile or status changes that may affect avatars or presence indicators.
85
+
-**`hello`**: Sent once after authentication; contains server connection info and session id. Useful to confirm the connection succeeded.
86
+
87
+
Example `posted` event payload structure (fields trimmed for brevity):
-`data.post` is a JSON string; parse it before use. The `message` and `root_id` fields are where you decide whether to update the main channel timeline or a thread.
110
+
-`broadcast` hints which channel or team should receive the update; you can use it to filter events if you maintain multiple channel tabs.
111
+
- Some events (e.g., `typing`) do not include a `post` body. Handle them separately from message mutations.
112
+
35
113
### How Ecency access tokens are issued
36
114
37
115
Ecency always mints the same JWT `accessToken`/`refreshToken` pair regardless of the login provider. Hivesigner users obtain them via the OAuth callback, while other methods (Keychain, HiveAuth, or manual posting-key sign-in) go through the Ecency auth API, which returns the tokens after verifying a signed login challenge tied to the Hive posting authority.
0 commit comments