mirror of
https://github.com/stoatchat/stoatchat.git
synced 2026-07-14 05:26:59 +00:00
docs: initialise new docs with docusaurus (#460)
* docs: initialise new docs with docusaurus * chore: sign off Signed-off-by: izzy <me@insrt.uk> * chore: lock pnpm version in package.json Signed-off-by: izzy <me@insrt.uk> * ci: specify package json to load pnpm version from Signed-off-by: izzy <me@insrt.uk> * docs: update repo. lifecycle details Signed-off-by: izzy <me@insrt.uk> * docs: add external links to for-web, for-android chore: add default.nix to docs * docs: correct headings in contrib * ci: use cache dependency path * fix: docusaurus configuration --------- Signed-off-by: izzy <me@insrt.uk>
This commit is contained in:
37
.github/workflows/book.yml
vendored
37
.github/workflows/book.yml
vendored
@@ -1,37 +0,0 @@
|
||||
name: Build documentation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write # To push a branch
|
||||
pages: write # To push to a GitHub Pages site
|
||||
id-token: write # To update the deployment status
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install latest mdbook
|
||||
run: |
|
||||
tag=$(curl 'https://api.github.com/repos/rust-lang/mdbook/releases/latest' | jq -r '.tag_name')
|
||||
url="https://github.com/rust-lang/mdbook/releases/download/${tag}/mdbook-${tag}-x86_64-unknown-linux-gnu.tar.gz"
|
||||
mkdir mdbook
|
||||
curl -sSL $url | tar -xz --directory=./mdbook
|
||||
echo `pwd`/mdbook >> $GITHUB_PATH
|
||||
- name: Build Book
|
||||
run: |
|
||||
cd doc
|
||||
mdbook build
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v4
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: "doc/book"
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
29
.github/workflows/docs-test.yml
vendored
Normal file
29
.github/workflows/docs-test.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
name: Documentation (test)
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
test-deploy:
|
||||
name: Test deployment
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./docs
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
package_json_file: ./docs/package.json
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: lts/*
|
||||
cache: pnpm
|
||||
cache-dependency-path: ./docs/pnpm-lock.yaml
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
- name: Test build website
|
||||
run: pnpm run build
|
||||
54
.github/workflows/docs.yml
vendored
Normal file
54
.github/workflows/docs.yml
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
name: Documentation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build Docusaurus
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./docs
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
package_json_file: ./docs/package.json
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: lts/*
|
||||
cache: pnpm
|
||||
cache-dependency-path: ./docs/pnpm-lock.yaml
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
- name: Build website
|
||||
run: pnpm run build
|
||||
|
||||
- name: Upload Build Artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: build
|
||||
|
||||
deploy:
|
||||
name: Deploy to GitHub Pages
|
||||
needs: build
|
||||
|
||||
permissions:
|
||||
pages: write # to deploy to Pages
|
||||
id-token: write # to verify the deployment originates from an appropriate source
|
||||
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
1
doc/.gitignore
vendored
1
doc/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
book
|
||||
@@ -1,5 +0,0 @@
|
||||
[book]
|
||||
authors = []
|
||||
language = "en"
|
||||
src = "src"
|
||||
title = "Revolt Backend"
|
||||
@@ -1,8 +0,0 @@
|
||||
# Summary
|
||||
|
||||
- [Introduction](./hello.md)
|
||||
- [Project Structure]()
|
||||
- [Creating new API features](./new_features.md)
|
||||
- [Testing]()
|
||||
- [Writing a new database test]()
|
||||
- [Writing a new API test]()
|
||||
@@ -1,5 +0,0 @@
|
||||
# Revolt Backend
|
||||
|
||||
Welcome to the developer documentation for the Revolt backend.
|
||||
|
||||
This is very much incomplete and needs more work!
|
||||
20
docs/.gitignore
vendored
Normal file
20
docs/.gitignore
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
# Dependencies
|
||||
/node_modules
|
||||
|
||||
# Production
|
||||
/build
|
||||
|
||||
# Generated files
|
||||
.docusaurus
|
||||
.cache-loader
|
||||
|
||||
# Misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
41
docs/README.md
Normal file
41
docs/README.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Website
|
||||
|
||||
This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
yarn
|
||||
```
|
||||
|
||||
## Local Development
|
||||
|
||||
```bash
|
||||
yarn start
|
||||
```
|
||||
|
||||
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
|
||||
|
||||
## Build
|
||||
|
||||
```bash
|
||||
yarn build
|
||||
```
|
||||
|
||||
This command generates static content into the `build` directory and can be served using any static contents hosting service.
|
||||
|
||||
## Deployment
|
||||
|
||||
Using SSH:
|
||||
|
||||
```bash
|
||||
USE_SSH=true yarn deploy
|
||||
```
|
||||
|
||||
Not using SSH:
|
||||
|
||||
```bash
|
||||
GIT_USER=<Your GitHub username> yarn deploy
|
||||
```
|
||||
|
||||
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.
|
||||
11
docs/default.nix
Normal file
11
docs/default.nix
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
}:
|
||||
|
||||
with pkgs;
|
||||
pkgs.mkShell {
|
||||
buildInputs = [
|
||||
nodejs
|
||||
nodejs.pkgs.pnpm
|
||||
];
|
||||
}
|
||||
10
docs/docs/developers/api/_category_.json
Normal file
10
docs/docs/developers/api/_category_.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"label": "API",
|
||||
"position": 2,
|
||||
"link": {
|
||||
"type": "generated-index",
|
||||
"description": "Connecting and consuming the Stoat API"
|
||||
},
|
||||
"collapsed": false,
|
||||
"collapsible": true
|
||||
}
|
||||
15
docs/docs/developers/api/authentication.md
Normal file
15
docs/docs/developers/api/authentication.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Authentication
|
||||
|
||||
To authenticate with the API, you must first acquire a bot token or user token:
|
||||
|
||||
- **Bot:** create one from user settings in the client
|
||||
- **User:** copy one from client or authenticate through API
|
||||
|
||||
Then you may provide these through either:
|
||||
|
||||
| Type | Header |
|
||||
| :---: | :---------------: |
|
||||
| Bot | `X-Bot-Token` |
|
||||
| User | `X-Session-Token` |
|
||||
|
||||
When dealing with an authenticated route.
|
||||
1
docs/docs/developers/api/permission_hierarchy.svg
Normal file
1
docs/docs/developers/api/permission_hierarchy.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 74 KiB |
49
docs/docs/developers/api/permissions.mdx
Normal file
49
docs/docs/developers/api/permissions.mdx
Normal file
@@ -0,0 +1,49 @@
|
||||
# Permissions
|
||||
|
||||
Stoat's permission system works by sequentially applying allows then denies.
|
||||
|
||||
## Flow Chart
|
||||
|
||||
Below are the high-level steps taken to determine both server and channel permissions (click to view).
|
||||
|
||||
<a href="./permission hierarchy.svg" target="_blank">
|
||||
<img src="./permission_hierarchy.svg" style={{background: "white", padding: "1em", borderRadius: "1em"}} />
|
||||
</a>
|
||||
|
||||
If you are looking to implement permissions in a library, I highly recommend reading either the Stoat JavaScript SDK or the backend source code since all the routines are well commented and should be relatively easy to understand.
|
||||
|
||||
## Values
|
||||
|
||||
The following permissions are currently allocated:
|
||||
|
||||
| Name | Value | Bitwise | Description |
|
||||
| --------------------- | :-----------: | :-------: | ------------------------------------------------------- |
|
||||
| `ManageChannel` | `1` | `1 << 0` | Manage the channel or channels on the server |
|
||||
| `ManageServer` | `2` | `1 << 1` | Manage the server |
|
||||
| `ManagePermissions` | `4` | `1 << 2` | Manage permissions on servers or channels |
|
||||
| `ManageRole` | `8` | `1 << 3` | Manage roles on server |
|
||||
| `ManageCustomisation` | `16` | `1 << 4` | Manage emoji on servers |
|
||||
| `KickMembers` | `64` | `1 << 6` | Kick other members below their ranking |
|
||||
| `BanMembers` | `128` | `1 << 7` | Ban other members below their ranking |
|
||||
| `TimeoutMembers` | `256` | `1 << 8` | Timeout other members below their ranking |
|
||||
| `AssignRoles` | `512` | `1 << 9` | Assign roles to members below their ranking |
|
||||
| `ChangeNickname` | `1024` | `1 << 10` | Change own nickname |
|
||||
| `ManageNicknames` | `2048` | `1 << 11` | Change or remove other's nicknames below their ranking |
|
||||
| `ChangeAvatar` | `4096` | `1 << 12` | Change own avatar |
|
||||
| `RemoveAvatars` | `8192` | `1 << 13` | Remove other's avatars below their ranking |
|
||||
| `ViewChannel` | `1048576` | `1 << 20` | View a channel |
|
||||
| `ReadMessageHistory` | `2097152` | `1 << 21` | Read a channel's past message history |
|
||||
| `SendMessage` | `4194304` | `1 << 22` | Send a message in a channel |
|
||||
| `ManageMessages` | `8388608` | `1 << 23` | Delete messages in a channel |
|
||||
| `ManageWebhooks` | `16777216` | `1 << 24` | Manage webhook entries on a channel |
|
||||
| `InviteOthers` | `33554432` | `1 << 25` | Create invites to this channel |
|
||||
| `SendEmbeds` | `67108864` | `1 << 26` | Send embedded content in this channel |
|
||||
| `UploadFiles` | `134217728` | `1 << 27` | Send attachments and media in this channel |
|
||||
| `Masquerade` | `268435456` | `1 << 28` | Masquerade messages using custom nickname and avatar |
|
||||
| `React` | `536870912` | `1 << 29` | React to messages with emojis |
|
||||
| `Connect` | `1073741824` | `1 << 30` | Connect to a voice channel |
|
||||
| `Speak` | `2147483648` | `1 << 31` | Speak in a voice call |
|
||||
| `Video` | `4294967296` | `1 << 32` | Share video in a voice call |
|
||||
| `MuteMembers` | `8589934592` | `1 << 33` | Mute other members with lower ranking in a voice call |
|
||||
| `DeafenMembers` | `17179869184` | `1 << 34` | Deafen other members with lower ranking in a voice call |
|
||||
| `MoveMembers` | `34359738368` | `1 << 35` | Move members between voice channels |
|
||||
49
docs/docs/developers/api/ratelimits.md
Normal file
49
docs/docs/developers/api/ratelimits.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# Rate Limits
|
||||
|
||||
Stoat uses a fixed-window ratelimiting algorithm:
|
||||
|
||||
- You are given a set amount of calls per each named bucket.
|
||||
- Any calls past this limit will result in 429 errors.
|
||||
- Buckets are replenished after 10 seconds from initial request.
|
||||
|
||||
## Buckets
|
||||
|
||||
There are distinct buckets that you may be calling against, none of these affect each other and can be used up independently of one another.
|
||||
|
||||
| Method | Path | Limit |
|
||||
| -------: | --------------------------- | :---: |
|
||||
| | `/users` | 20 |
|
||||
| `PATCH` | `/users/:id` | 2 |
|
||||
| | `/users/:id/default_avatar` | 255 |
|
||||
| | `/bots` | 10 |
|
||||
| | `/channels` | 15 |
|
||||
| `POST` | `/channels/:id/messages` | 10 |
|
||||
| | `/servers` | 5 |
|
||||
| | `/auth` | 3 |
|
||||
| `DELETE` | `/auth` | 255 |
|
||||
| | `/safety` | 15 |
|
||||
| | `/safety/report` | 3 |
|
||||
| | `/swagger` | 100 |
|
||||
| | `/*` | 20 |
|
||||
|
||||
## Headers
|
||||
|
||||
There are multiple headers you can use to figure out when you can and cannot send requests, and to determine when you can next send a request.
|
||||
|
||||
| Header | Type | Description |
|
||||
| ------------------------- | :------: | ------------------------------------------------ |
|
||||
| `X-RateLimit-Limit` | `number` | Maximum number of calls allowed for this bucket. |
|
||||
| `X-RateLimit-Bucket` | `string` | Unique identifier for this bucket. |
|
||||
| `X-RateLimit-Remaining` | `number` | Remaining number of calls left for this bucket. |
|
||||
| `X-RateLimit-Reset-After` | `number` | Milliseconds left until calls are replenished. |
|
||||
|
||||
## Rate Limited Response
|
||||
|
||||
When you receive `429 Too Many Requests`, you will also receive a JSON body with the schema:
|
||||
|
||||
```typescript
|
||||
interface Response {
|
||||
// Milliseconds until calls are replenished
|
||||
retry_after: number;
|
||||
}
|
||||
```
|
||||
47
docs/docs/developers/api/uploading-files.md
Normal file
47
docs/docs/developers/api/uploading-files.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# Uploading Files
|
||||
|
||||
File uploads work by first sending a file to the server and then using the ID provided.
|
||||
|
||||
You can find out what kinds of files you can upload by visiting [the API documentation](https://cdn.stoatusercontent.com/scalar).
|
||||
|
||||
To upload a file, pick the desired tag then send a **POST** to `{endpoint}/{tag}` along with a `multipart/form-data` body with one field `file` that contains the file you wish to upload.
|
||||
|
||||
You must specify session/bot authentication token as with any other API route.
|
||||
|
||||
You will receive the following JSON response:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "0"
|
||||
}
|
||||
```
|
||||
|
||||
You can use the ID wherever a file is required in the API.
|
||||
|
||||
Code sample in JavaScript using Fetch API:
|
||||
|
||||
```js
|
||||
const body = new FormData();
|
||||
body.append("file", file);
|
||||
|
||||
const data = await fetch(`${endpoint}/${tag}`, {
|
||||
method: "POST",
|
||||
body,
|
||||
headers: {
|
||||
"X-Session-Token": "...", // or X-Bot-Token
|
||||
},
|
||||
}).then((res) => res.json());
|
||||
|
||||
// use data.id
|
||||
```
|
||||
|
||||
## Differences from old Autumn
|
||||
|
||||
If you are migrating from old Autumn, the following key points are important:
|
||||
|
||||
- There are only two paths that serve a unique image, the preview version of it (if available) and the original image.
|
||||
- You should not specify any query parameters under any circumstance, the preview route will serve the optimal size for the content type.
|
||||
- Preview routes for banners, emojis, backgrounds, and attachments will redirect to the original file where the file is not an image or the image is animated.
|
||||
- If you are currently using logic to replace the URL path to start/stop animations, you should use the following templates: (NB. this only applies to avatars and icons)
|
||||
- Non-animated file: `/{tag}/{file_id}`
|
||||
- Animated file: `/{tag}/{file_id}/{file_name}` or `/{tag}/{file_id}/original` (if name unavailable)
|
||||
23
docs/docs/developers/endpoints.md
Normal file
23
docs/docs/developers/endpoints.md
Normal file
@@ -0,0 +1,23 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# Endpoints
|
||||
|
||||
**We are moving stuff around currently following the rebrand, guidance will follow soon!**
|
||||
|
||||
You can connect to the API on the following URLs:
|
||||
|
||||
| URL | Release | Description |
|
||||
| ----------------------------- | :--------: | --------------------------- |
|
||||
| `https://api.revolt.chat` | Production | Primary API endpoint |
|
||||
| `https://app.revolt.chat/api` | Production | API endpoint for old client |
|
||||
| `https://revolt.chat/api` | Staging | API endpoint for new client |
|
||||
|
||||
You can connect to the events server on the following URLs:
|
||||
|
||||
| URL | Release | Description |
|
||||
| ------------------------------ | :--------: | ------------------------------ |
|
||||
| `wss://ws.revolt.chat` | Production | Primary events endpoint |
|
||||
| `wss://app.revolt.chat/events` | Production | Events endpoint for old client |
|
||||
| `wss://revolt.chat/events` | Staging | Events endpoint for new client |
|
||||
10
docs/docs/developers/events/_category_.json
Normal file
10
docs/docs/developers/events/_category_.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"label": "Events",
|
||||
"position": 2,
|
||||
"link": {
|
||||
"type": "generated-index",
|
||||
"description": "Connecting and using the Stoat gateway"
|
||||
},
|
||||
"collapsed": false,
|
||||
"collapsible": true
|
||||
}
|
||||
57
docs/docs/developers/events/establishing.md
Normal file
57
docs/docs/developers/events/establishing.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# Establishing a connection
|
||||
|
||||
To get started, you should have:
|
||||
|
||||
- A WebSocket URL, which is found from the API root.
|
||||
- A valid session or bot token.
|
||||
|
||||
You may authenticate in one of two ways:
|
||||
|
||||
- Include credentials in the connection URL, see [Query Parameters](#query-parameters).
|
||||
- Sending an [Authenticate](./protocol.md#authenticate) event to the server.
|
||||
|
||||
You should listen out for [Error](./protocol.md#error) events to find out if your credentials are incorrect or if something goes wrong here.
|
||||
|
||||
After authenticating, the server will respond with [Authenticated](./protocol.md#authenticated) then it will send a [Ready](./protocol.md#ready) event containing useful data.
|
||||
|
||||
The server will now start sending relevant events as they come in.
|
||||
|
||||
You should [Ping](./protocol.md#ping) the server every 10 to 30 seconds to prevent your connection being dropped.
|
||||
|
||||
Bots receive all events, normal users do not receive UserUpdate events fanned out through servers by default, [read more here](./protocol.md#subscribe).
|
||||
|
||||
## Query Parameters
|
||||
|
||||
The Bonfire service supports additional query parameters:
|
||||
|
||||
| Parameter | Description | Values | Required |
|
||||
| --------- | ----------------------------------------------------------------------- | -------------------------- | -------- |
|
||||
| `version` | Describes the protocol version in use. | `1` | No † |
|
||||
| `format` | In what format to send packets, default is JSON. | `json`, `msgpack` | No |
|
||||
| `token` | token for authenticating the connecting user. | Session or bot token | No |
|
||||
| `ready` | Fields to include in the `Ready` event payload, by default all are sent | [See Below](#ready-fields) | No |
|
||||
|
||||
† `version` may become compulsary in the future, please set it to `1` if you can.
|
||||
|
||||
### Ready Fields
|
||||
|
||||
The ready query parameter can be passed multiple times to specify multiple fields, supported fields are:
|
||||
|
||||
| Value | Description |
|
||||
| ----------------- | --------------------------------------------------------------------------------------------------------------- |
|
||||
| `users` | Includes all users you have a relation with. |
|
||||
| `servers` | Includes all servers you are in. |
|
||||
| `channels` | Includes all channels you have access to. |
|
||||
| `members` | Includes all members you have a relation with. |
|
||||
| `emojis` | Includes all emojis you have access to. |
|
||||
| `user_settings` | Specify which settings to pre-fetch, specify a setting by setting the value to `user_settings[<setting_name>]`. |
|
||||
| `channel_unreads` | Includes all channel unreads you have. |
|
||||
| `policy_changes` | Includes all new policy changes you should be aware of, this is not sent to bots. |
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
?ready=users&ready=servers&ready=user_settings[ordering]
|
||||
```
|
||||
|
||||
You may specify these in the connection URL: `wss://stoat.chat/events?version=1&format=json`.
|
||||
589
docs/docs/developers/events/protocol.md
Normal file
589
docs/docs/developers/events/protocol.md
Normal file
@@ -0,0 +1,589 @@
|
||||
# Events
|
||||
|
||||
This page documents various incoming and outgoing events.
|
||||
|
||||
**Help Wanted:** we should adopt [AsyncAPI](https://www.asyncapi.com) to properly document the protocol!
|
||||
|
||||
## Client to Server
|
||||
|
||||
### Authenticate
|
||||
|
||||
Authenticate with the server.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "Authenticate",
|
||||
"token": "{token}"
|
||||
}
|
||||
```
|
||||
|
||||
### BeginTyping
|
||||
|
||||
Tell other users that you have begun typing in a channel.
|
||||
|
||||
Must be in the specified channel or nothing will happen.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "BeginTyping",
|
||||
"channel": "{channel_id}"
|
||||
}
|
||||
```
|
||||
|
||||
### EndTyping
|
||||
|
||||
Tell other users that you have stopped typing in a channel.
|
||||
|
||||
Must be in the specified channel or nothing will happen.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "EndTyping",
|
||||
"channel": "{channel_id}"
|
||||
}
|
||||
```
|
||||
|
||||
### Ping
|
||||
|
||||
Ping the server, you can specify a timestamp that you'll receive back.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "Ping",
|
||||
"data": 0
|
||||
}
|
||||
```
|
||||
|
||||
### Subscribe
|
||||
|
||||
Subscribe to a server's UserUpdate events.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "Subscribe",
|
||||
"server_id": "{server_id}"
|
||||
}
|
||||
```
|
||||
|
||||
Implementation notes:
|
||||
|
||||
- Subscriptions automatically expire within 15 minutes.
|
||||
- A client may have up to 5 active subscriptions.
|
||||
- This has no effect on bot sessions.
|
||||
- This event should only be sent **iff** app/client is in focus.
|
||||
- You should aim to send this event at most every 10 minutes per server.
|
||||
|
||||
## Server to Client
|
||||
|
||||
### Error
|
||||
|
||||
An error occurred which meant you couldn't authenticate.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "Error",
|
||||
"error": "{error_id}"
|
||||
}
|
||||
```
|
||||
|
||||
The `{error_id}` can be one of the following:
|
||||
|
||||
- `LabelMe`: uncategorised error
|
||||
- `InternalError`: the server ran into an issue
|
||||
- `InvalidSession`: authentication details are incorrect
|
||||
- `OnboardingNotFinished`: user has not chosen a username
|
||||
- `AlreadyAuthenticated`: this connection is already authenticated
|
||||
|
||||
### Authenticated
|
||||
|
||||
The server has authenticated your connection and you will shortly start receiving data.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "Authenticated"
|
||||
}
|
||||
```
|
||||
|
||||
### Logged Out
|
||||
|
||||
The current user session has been invalidated or the bot token has been reset.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "Logout"
|
||||
}
|
||||
```
|
||||
|
||||
Your connection will be closed shortly after.
|
||||
|
||||
### Bulk
|
||||
|
||||
Several events have been sent, process each item of `v` as its own event.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "Bulk",
|
||||
"v": [...]
|
||||
}
|
||||
```
|
||||
|
||||
### Pong
|
||||
|
||||
Ping response from the server.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "Pong",
|
||||
"data": 0
|
||||
}
|
||||
```
|
||||
|
||||
### Ready
|
||||
|
||||
Data for use by client, data structures match the API specification.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "Ready",
|
||||
"users"?: [{..}],
|
||||
"servers"?: [{..}],
|
||||
"channels"?: [{..}],
|
||||
"members"?: [{..}],
|
||||
"emojis"?: [{..}],
|
||||
"user_settings"?: [{..}],
|
||||
"channel_unreads"?: [{..}],
|
||||
"policy_changes"?: [{..}],
|
||||
}
|
||||
```
|
||||
|
||||
### Message
|
||||
|
||||
Message received, the event object has the same schema as the Message object in the API with the addition of an event type.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "Message",
|
||||
[..]
|
||||
}
|
||||
```
|
||||
|
||||
### MessageUpdate
|
||||
|
||||
Message edited or otherwise updated.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "MessageUpdate",
|
||||
"id": "{message_id}",
|
||||
"channel": "{channel_id}",
|
||||
"data": {..}
|
||||
}
|
||||
```
|
||||
|
||||
- `data` field contains a partial Message object.
|
||||
|
||||
### MessageAppend
|
||||
|
||||
Message has data being appended to it.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "MessageAppend",
|
||||
"id": "{message_id}",
|
||||
"channel": "{channel_id}",
|
||||
"append": {
|
||||
"embeds"?: [...]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### MessageDelete
|
||||
|
||||
Message has been deleted.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "MessageDelete",
|
||||
"id": "{message_id}",
|
||||
"channel": "{channel_id}"
|
||||
}
|
||||
```
|
||||
|
||||
### MessageReact
|
||||
|
||||
A reaction has been added to a message.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "MessageReact",
|
||||
"id": "{message_id}",
|
||||
"channel_id": "{channel_id}",
|
||||
"user_id": "{user_id}",
|
||||
"emoji_id": "{emoji_id}"
|
||||
}
|
||||
```
|
||||
|
||||
### MessageUnreact
|
||||
|
||||
A reaction has been removed from a message.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "MessageUnreact",
|
||||
"id": "{message_id}",
|
||||
"channel_id": "{channel_id}",
|
||||
"user_id": "{user_id}",
|
||||
"emoji_id": "{emoji_id}"
|
||||
}
|
||||
```
|
||||
|
||||
### MessageRemoveReaction
|
||||
|
||||
A certain reaction has been removed from the message.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "MessageRemoveReaction",
|
||||
"id": "{message_id}",
|
||||
"channel_id": "{channel_id}",
|
||||
"emoji_id": "{emoji_id}"
|
||||
}
|
||||
```
|
||||
|
||||
### ChannelCreate
|
||||
|
||||
Channel created, the event object has the same schema as the Channel object in the API with the addition of an event type.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "ChannelCreate",
|
||||
[..]
|
||||
}
|
||||
```
|
||||
|
||||
### ChannelUpdate
|
||||
|
||||
Channel details updated.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "ChannelUpdate",
|
||||
"id": "{channel_id}",
|
||||
"data": {..},
|
||||
"clear": ["{field}", ...]
|
||||
}
|
||||
```
|
||||
|
||||
- `data` field contains a partial Channel object.
|
||||
- `{field}` is a field to remove, one of:
|
||||
- `Icon`
|
||||
- `Description`
|
||||
|
||||
### ChannelDelete
|
||||
|
||||
Channel has been deleted.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "ChannelDelete",
|
||||
"id": "{channel_id}"
|
||||
}
|
||||
```
|
||||
|
||||
### ChannelGroupJoin
|
||||
|
||||
A user has joined the group.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "ChannelGroupJoin",
|
||||
"id": "{channel_id}",
|
||||
"user": "{user_id}"
|
||||
}
|
||||
```
|
||||
|
||||
### ChannelGroupLeave
|
||||
|
||||
A user has left the group.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "ChannelGroupLeave",
|
||||
"id": "{channel_id}",
|
||||
"user": "{user_id}"
|
||||
}
|
||||
```
|
||||
|
||||
### ChannelStartTyping
|
||||
|
||||
A user has started typing in this channel.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "ChannelStartTyping",
|
||||
"id": "{channel_id}",
|
||||
"user": "{user_id}"
|
||||
}
|
||||
```
|
||||
|
||||
### ChannelStopTyping
|
||||
|
||||
A user has stopped typing in this channel.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "ChannelStopTyping",
|
||||
"id": "{channel_id}",
|
||||
"user": "{user_id}"
|
||||
}
|
||||
```
|
||||
|
||||
### ChannelAck
|
||||
|
||||
You have acknowledged new messages in this channel up to this message ID.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "ChannelAck",
|
||||
"id": "{channel_id}",
|
||||
"user": "{user_id}",
|
||||
"message_id": "{message_id}"
|
||||
}
|
||||
```
|
||||
|
||||
### ServerCreate
|
||||
|
||||
Server created, the event object has the same schema as the SERVER object in the API with the addition of an event type.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "ServerCreate",
|
||||
[..]
|
||||
}
|
||||
```
|
||||
|
||||
### ServerUpdate
|
||||
|
||||
Server details updated.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "ServerUpdate",
|
||||
"id": "{server_id}",
|
||||
"data": {..},
|
||||
"clear": ["{field}", ...]
|
||||
}
|
||||
```
|
||||
|
||||
- `data` field contains a partial Server object.
|
||||
- `{field}` is a field to remove, one of:
|
||||
- `Icon`
|
||||
- `Banner`
|
||||
- `Description`
|
||||
|
||||
### ServerDelete
|
||||
|
||||
Server has been deleted.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "ServerDelete",
|
||||
"id": "{server_id}"
|
||||
}
|
||||
```
|
||||
|
||||
### ServerMemberUpdate
|
||||
|
||||
Server member details updated.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "ServerMemberUpdate",
|
||||
"id": {
|
||||
"server": "{server_id}",
|
||||
"user": "{user_id}"
|
||||
},
|
||||
"data": {..},
|
||||
"clear": ["{field}", ...]
|
||||
}
|
||||
```
|
||||
|
||||
- `data` field contains a partial Server Member object.
|
||||
- `{field}` is a field to remove, one of:
|
||||
- `Nickname`
|
||||
- `Avatar`
|
||||
|
||||
### ServerMemberJoin
|
||||
|
||||
A user has joined the server.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "ServerMemberJoin",
|
||||
"id": "{server_id}",
|
||||
"user": "{user_id}",
|
||||
"member": {..}
|
||||
}
|
||||
```
|
||||
|
||||
- `member` field contains a Member object.
|
||||
|
||||
### ServerMemberLeave
|
||||
|
||||
A user has left the server.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "ServerMemberLeave",
|
||||
"id": "{server_id}",
|
||||
"user": "{user_id}"
|
||||
}
|
||||
```
|
||||
|
||||
### ServerRoleUpdate
|
||||
|
||||
Server role has been updated or created.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "ServerRoleUpdate",
|
||||
"id": "{server_id}",
|
||||
"role_id": "{role_id}",
|
||||
"data": {..},
|
||||
"clear": ["{field}", ...]
|
||||
}
|
||||
```
|
||||
|
||||
- `data` field contains a partial Server Role object.
|
||||
- `clear` is a field to remove, one of:
|
||||
- `Colour`
|
||||
|
||||
### ServerRoleDelete
|
||||
|
||||
Server role has been deleted.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "ServerRoleDelete",
|
||||
"id": "{server_id}",
|
||||
"role_id": "{role_id}"
|
||||
}
|
||||
```
|
||||
|
||||
### UserUpdate
|
||||
|
||||
User has been updated.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "UserUpdate",
|
||||
"id": "{user_id}",
|
||||
"data": {..},
|
||||
"clear": ["{field}", ...]
|
||||
}
|
||||
```
|
||||
|
||||
- `data` field contains a partial User object.
|
||||
- `clear` is a field to remove, one of:
|
||||
- `ProfileContent`
|
||||
- `ProfileBackground`
|
||||
- `StatusText`
|
||||
- `Avatar`
|
||||
- `DisplayName`
|
||||
|
||||
### UserRelationship
|
||||
|
||||
Your relationship with another user has changed.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "UserRelationship",
|
||||
"id": "{your_user_id}",
|
||||
"user": "{..}",
|
||||
"status": "{status}"
|
||||
}
|
||||
```
|
||||
|
||||
- `user` field contains a User object.
|
||||
- `status` field matches Relationship Status in API.
|
||||
|
||||
### UserPlatformWipe
|
||||
|
||||
User has been platform banned or deleted their account.
|
||||
|
||||
Clients should remove the following associated data:
|
||||
|
||||
- Messages
|
||||
- DM Channels
|
||||
- Relationships
|
||||
- Server Memberships
|
||||
|
||||
User flags are specified to explain why a wipe is occurring though not all reasons will necessarily ever appear.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "UserPlatformWipe",
|
||||
"user_id": "{user_id}",
|
||||
"flags": "{user_flags}"
|
||||
}
|
||||
```
|
||||
|
||||
### EmojiCreate
|
||||
|
||||
Emoji created, the event object has the same schema as the Emoji object in the API with the addition of an event type.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "EmojiCreate",
|
||||
[..]
|
||||
}
|
||||
```
|
||||
|
||||
### EmojiDelete
|
||||
|
||||
Emoji has been deleted.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "EmojiDelete",
|
||||
"id": "{emoji_id}"
|
||||
}
|
||||
```
|
||||
|
||||
### Auth
|
||||
|
||||
Forwarded events from [Authifier](https://github.com/authifier/authifier), currently only session deletion events are forwarded.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "Auth",
|
||||
"event_type": "{event_type}",
|
||||
[..]
|
||||
}
|
||||
```
|
||||
|
||||
Event type may be defined as one of the following with the additional properties:
|
||||
|
||||
#### DeleteSession
|
||||
|
||||
A session has been deleted.
|
||||
|
||||
```json
|
||||
{
|
||||
"event_type": "DeleteSession",
|
||||
"user_id": "{user_id}",
|
||||
"session_id": "{session_id}"
|
||||
}
|
||||
```
|
||||
|
||||
#### DeleteAllSessions
|
||||
|
||||
All sessions for this account have been deleted, optionally excluding a given ID.
|
||||
|
||||
```json
|
||||
{
|
||||
"event_type": "DeleteAllSessions",
|
||||
"user_id": "{user_id}",
|
||||
"exclude_session_id": "{session_id}"
|
||||
}
|
||||
```
|
||||
147
docs/docs/developers/legacy-plugin-api.md
Normal file
147
docs/docs/developers/legacy-plugin-api.md
Normal file
@@ -0,0 +1,147 @@
|
||||
# Plugin API
|
||||
|
||||
:::danger
|
||||
This page documents the old Revite Plugin API (manifest v1), it will be replaced in the new client.
|
||||
:::
|
||||
|
||||
:::warning
|
||||
The Plugin API is very powerful. **Tread carefully.**
|
||||
|
||||
**Zero guarantees or sandboxes are provided.** Your code is run as-is.
|
||||
:::
|
||||
|
||||
This document details the very experimental plugin API available in [Revite](https://github.com/revoltchat/revite).
|
||||
|
||||
This is more or less a proof of concept but can be used to achieve some simple client modifications.
|
||||
|
||||
## Plugin Manifest
|
||||
|
||||
Below is the specification for revision 1 of the plugin API. The `format` parameter is not currently enforced but you should set it to `1` to avoid future breakage.
|
||||
|
||||
````typescript
|
||||
type Plugin = {
|
||||
/**
|
||||
* Plugin Format Revision
|
||||
*/
|
||||
format: 1;
|
||||
|
||||
/**
|
||||
* Semver Version String
|
||||
*
|
||||
* This is the version of the plugin.
|
||||
*/
|
||||
version: string;
|
||||
|
||||
/**
|
||||
* Plugin Namespace
|
||||
*
|
||||
* This will usually be the author's name.
|
||||
*/
|
||||
namespace: string;
|
||||
|
||||
/**
|
||||
* Plugin Id
|
||||
*
|
||||
* This should be a valid URL slug, e.g. cool-plugin.
|
||||
*/
|
||||
id: string;
|
||||
|
||||
/**
|
||||
* Entrypoint
|
||||
*
|
||||
* Valid Javascript code. It must be a function which returns a object.
|
||||
*
|
||||
* ```typescript
|
||||
* function (state: State) {
|
||||
* return {
|
||||
* onUnload: () => {}
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
entrypoint: string;
|
||||
|
||||
/**
|
||||
* Whether this plugin is enabled.
|
||||
*
|
||||
* @default true
|
||||
*/
|
||||
enabled?: boolean;
|
||||
};
|
||||
````
|
||||
|
||||
An example plugin:
|
||||
|
||||
```javascript
|
||||
{
|
||||
format: 1,
|
||||
version: "0.0.1",
|
||||
namespace: "insert",
|
||||
id: "my-plugin",
|
||||
entrypoint: `(state) => {
|
||||
console.log('[my-plugin] Plugin init!');
|
||||
return {
|
||||
onUnload: () => console.log('[my-plugin] bye!')
|
||||
}
|
||||
}`
|
||||
}
|
||||
```
|
||||
|
||||
## Using the Plugin API
|
||||
|
||||
To begin, you can load plugins using the global plugin manager at `state.plugins`.
|
||||
|
||||
Open the developer console and run:
|
||||
|
||||
```javascript
|
||||
state.plugins.load({ ... });
|
||||
// ...where [...] is your plugin manifest as described above.
|
||||
```
|
||||
|
||||
## Plugin API
|
||||
|
||||
A plugin's entrypoint is required to return an object which is referred to as the **instance**:
|
||||
|
||||
```typescript
|
||||
interface Instance {
|
||||
onUnload?: () => void;
|
||||
}
|
||||
```
|
||||
|
||||
The Plugin API (`state.plugins`) exposes the following methods:
|
||||
|
||||
```typescript
|
||||
interface PluginAPI {
|
||||
/**
|
||||
* Add a plugin
|
||||
* @param plugin Plugin Manifest
|
||||
*/
|
||||
add(plugin: Plugin);
|
||||
|
||||
/**
|
||||
* Remove a plugin
|
||||
* @param namespace Plugin Namespace
|
||||
* @param id Plugin Id
|
||||
*/
|
||||
remove(namespace: string, id: string);
|
||||
|
||||
/**
|
||||
* Load a plugin
|
||||
* @param namespace Plugin Namespace
|
||||
* @param id Plugin Id
|
||||
*/
|
||||
load(namespace: string, id: string);
|
||||
|
||||
/**
|
||||
* Unload a plugin
|
||||
* @param namespace Plugin Namespace
|
||||
* @param id Plugin Id
|
||||
*/
|
||||
unload(namespace: string, id: string);
|
||||
|
||||
/**
|
||||
* Reset everything
|
||||
*/
|
||||
reset();
|
||||
}
|
||||
```
|
||||
8
docs/docs/developers/libraries.md
Normal file
8
docs/docs/developers/libraries.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# Libraries
|
||||
|
||||
The following libraries are provided by the Stoat team:
|
||||
|
||||
- [Javascript SDK](https://github.com/stoatchat/javascript-client-sdk)
|
||||
- [Python SDK](https://github.com/stoatchat/python-client-sdk)
|
||||
|
||||
You can find a host of [community created libraries here](https://github.com/stoatchat/awesome-stoat#-api-libraries).
|
||||
22
docs/docs/developers/stoat-migration-guide.md
Normal file
22
docs/docs/developers/stoat-migration-guide.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# Stoat Migration Guide
|
||||
|
||||
:::warning
|
||||
|
||||
This is not yet finished.
|
||||
|
||||
:::
|
||||
|
||||
## Endpoint changes
|
||||
|
||||
| Service | Old URL | New URL |
|
||||
| ---------- | ----------------------------------- | --------------------------------------- |
|
||||
| **API** | `https://api.revolt.chat` | `https://stoat.chat/api` |
|
||||
| | `https://app.revolt.chat/api` | `https://stoat.chat/api` |
|
||||
| | `https://revolt.chat/api` | No equivalent |
|
||||
| **Events** | `wss://ws.revolt.chat` | `wss://stoat.chat/events` |
|
||||
| | `wss://app.revolt.chat/events` | `wss://stoat.chat/events` |
|
||||
| | `wss://revolt.chat/events` | No equivalent |
|
||||
| **Files** | `https://autumn.revolt.chat` | `https://cdn.stoatusercontent.com` |
|
||||
| | `https://cdn.revoltusercontent.com` | `https://cdn.stoatusercontent.com` |
|
||||
| **Proxy** | `https://jan.revolt.chat` | `https://external.stoatusercontent.com` |
|
||||
| **Voice** | `https://vortex.revolt.chat` | Superseded by Voice Chats v2 |
|
||||
10
docs/docs/developing/backend/_category_.json
Normal file
10
docs/docs/developing/backend/_category_.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"label": "Backend",
|
||||
"position": 10,
|
||||
"link": {
|
||||
"type": "generated-index",
|
||||
"description": "Building the Stoat software"
|
||||
},
|
||||
"collapsed": false,
|
||||
"collapsible": true
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
# New API features
|
||||
# Adding new API features
|
||||
|
||||
New API features must be documented where appropriate, this document aims to cover everywhere you need to update for new features.
|
||||
|
||||
45
docs/docs/developing/contrib.md
Normal file
45
docs/docs/developing/contrib.md
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# Contribution Guide
|
||||
|
||||
This is the contribution guide for developers wanting to help out with Stoat.
|
||||
|
||||
## Repository Lifecycle
|
||||
|
||||
### Making Commits
|
||||
|
||||
- Sign-off your commits ([Git flag](https://git-scm.com/docs/git-commit#Documentation/git-commit.txt---signoff)), [read here about DCO obligations](https://developercertificate.org/).
|
||||
- Sign commits where possible, [learn more about that here](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits).
|
||||
- Prefer to use [Conventional Commit style](https://www.conventionalcommits.org/en/v1.0.0-beta.2/).
|
||||
- If present, e.g. `prettier`, `cargo fmt`, use the formatter.
|
||||
- Try to keep each PR bound to a single feature or change, multiple bug fixes may be fine in some cases.
|
||||
This is to avoid your PR getting stuck due to parts of it having conflicts or other issues.
|
||||
|
||||
### Merging Pull Requests
|
||||
|
||||
All PR titles must use use [Conventional Commit style](https://www.conventionalcommits.org/en/v1.0.0-beta.2/) and will be squash merged!
|
||||
|
||||
## What can I help with?
|
||||
|
||||
Stuff is currently being moved around, for the mean time, come ask in the development server: https://stt.gg/API
|
||||
|
||||
Also typically `help wanted` labels are available on repo issues!
|
||||
|
||||
<!-- The main project board can serve as a helpful starting point:
|
||||
|
||||
1. If you are new to the code base or are looking for issues we really need help with, look at ["What can I help with?"](https://github.com/orgs/projects/3/views/11)
|
||||
2. Issue Board ["Free Issues"](https://github.com/orgs/projects/3/views/1): issues that anyone can pick up and are generally free to work on
|
||||
3. Issue Board ["Todo"](https://github.com/orgs/projects/3/views/1): these are issues that are probably fine to pick up, but please ask first since a lot of these tend to be complicated and potentially already planned
|
||||
4. Working on new issues and fixes: ideally you should run new features by us, most fixes are probably going to be alright though, we wouldn't want to reject any PRs that we don't deem suitable after work has already been done. If it's a fix, make sure to make an issue for it first, if it's a new feature, it may be better suited in [Feature Suggestions](https://github.com/discussions/categories/feature-suggestions)
|
||||
|
||||
Any issues marked with "Future Work" or with a milestone greater than the current milestone are out of bounds and should not be worked on since it's likely that the team already has a plan in place, any work you may do may conflict with prior ideas, and your work may potentially be rejected if it does fit the criteria exactly. In general, these issues are just postponed to reduce long term technical debt, i.e. allow current issues to be handled. -->
|
||||
|
||||
## Project Guidance
|
||||
|
||||
Please read the additional relevant guidance on:
|
||||
|
||||
- [Developing for Backend](https://github.com/stoatchat/backend?tab=readme-ov-file#development-guide) (contrib guide TBA)
|
||||
- [Contributing to Frontend](https://stoatchat.github.io/for-web/contribution-guide.html)
|
||||
- [Contributing to Android](https://stoatchat.github.io/for-android/contributing/guidelines/)
|
||||
109
docs/docs/faq.md
Normal file
109
docs/docs/faq.md
Normal file
@@ -0,0 +1,109 @@
|
||||
---
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
# 📖 Frequently Asked Questions
|
||||
|
||||
This page includes several frequently asked questions and explanations.
|
||||
|
||||
All of these answers are written from the perspective of the project owner.
|
||||
|
||||
**Last Update:** 10th May 2024
|
||||
|
||||
<details>
|
||||
<summary>Why another project?</summary>
|
||||
|
||||
I think this is best explained with a bit of history:
|
||||
- Stoat (formerly Revolt) started as a passion project
|
||||
- It grew way beyond any of our expectations
|
||||
- We might as well keep going since there is an interest in this space
|
||||
|
||||
Beyond that:
|
||||
- Stoat has been a great learning experience, including development, management, and running the infrastructure for a large project. Stoat has also taught me a lot about different concepts and programming languages, and really, that's how developers learn. We make cool projects to try to better how we work, it doesn't matter if someone has done it before as long as you can attempt to do the same. Reinventing the wheel is part of the process.
|
||||
- At the time, there was also a relative void of competition in this specific genre of chat platforms. There were Guilded, Discord, and Matrix but these are all either closed-source or cater to a different audience.
|
||||
|
||||
PS. I've had a few people say, 'why not just contribute to X?', the answer is quite simple, I just didn't know about any of these projects (i.e. Matrix).
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>How are we funded?</summary>
|
||||
|
||||
Stoat is entirely funded through donations, we have amassed a significant amount of money from donations alone. (financial transparency reports coming soon :tm:)
|
||||
|
||||
The month-to-month income of Stoat covers our operational costs and leaves enough spare to cover yearly expenses and the occassional one-time expense, such as for additional hardware.
|
||||
|
||||
We have monetisation plans lined up for the future, however it is not our intention to paywall existing features, instead where possible we intend to pass down costs such as for file storage or voice bandwidth.
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>'X' feature when?</summary>
|
||||
|
||||
Please take a look at [our roadmap on GitHub](https://op.stoatinternal.com/projects/all-of-revolt/gantt?query_id=53).
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Does Stoat have federation?</summary>
|
||||
|
||||
As of right now, Stoat does not feature any federation and **it is not in our feature roadmap**.
|
||||
|
||||
However, this does not necessarily mean federation is off the table, possible avenues are:
|
||||
- Implement our own federation protocol
|
||||
- Implement a promising up and coming federation protocol, polyproto
|
||||
- Implement the Matrix protocol (unlikely, obtuse and unstable)
|
||||
- Implement the XMPP protocol (battle-tested and stable)
|
||||
|
||||
Any federation that is implemented MUST exercise caution in:
|
||||
- Preventing spam and abuse: moderators should be able to block malicious actors
|
||||
- Protecting user data: users should be able to redact all of their information and messages
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>What can I do with Stoat and how do I self-host?</summary>
|
||||
|
||||
In general:
|
||||
- The Stoat branding is used to represent the platform, stoat.chat.
|
||||
- You may use the branding as-is to promote the platform and your community on the platform.
|
||||
- You should not use the branding in order to appear as if you are associated with the Stoat team.
|
||||
- Please make explicit distinctions between Stoat (the platform, "stoat.chat") and the Stoat software.
|
||||
- The Stoat software is provided unbranded and only associated by name.
|
||||
|
||||
If you have any concerns or questions, please liase with us at [contact@stoat.chat](mailto:contact@stoat.chat).
|
||||
|
||||
As a third-party platform:
|
||||
- You **must** provide correct attribution in line with our software licenses:
|
||||
|
||||
If you are using official images (GitHub Packages / Docker Hub), attribution is included.
|
||||
If you are modifying the software and using it in production, you must publish the changes to the source publicly in line with AGPLv3. (In addition to providing attribution back to the original project.)
|
||||
- You are **solely responsible** for whatever happens on your third party instance, we provide no warranty or liability for what happens on 3rd party instances.
|
||||
- You **must not** appear to associate with Stoat / stoat.chat unless if granted explicit written permission. In regards to custom clients, provide a warning of any potential risks or clear it with us.
|
||||
- You **may not** use any of the Stoat branding or brand assets to advertise or promote your third party instance.
|
||||
|
||||
You can self-host Stoat by:
|
||||
- Using [Docker Compose and our recommended guide](https://github.com/stoatchat/self-hosted).
|
||||
- Building individual components yourself from the [source code](https://github.com/stoatchat).
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Can you verify my server/bot?</summary>
|
||||
|
||||
Currently, you can only apply to verify servers given that you have a valid reason to believe verification is necessary for your community. Verification is intended to provide protection for server owners from copy cats and to provide authenticity to users as such we are not just giving it out to anyone because that would defeat the purpose.
|
||||
|
||||
However if you would like to get a server verified, you should satisfy one of the following criteria:
|
||||
|
||||
- Official community for a well-established open source project
|
||||
- Official community for any other well-established product, service, or person
|
||||
- Large and active distinct pre-existing community
|
||||
|
||||
Distinct means the community is unique and well-known (& has an active presence) off platform. This means we are not currently verifying generic servers that centre around a topic unless if it meets one of the first two criteria. Though in special circumstances, well known on platform communities may also be considered.
|
||||
|
||||
Server verification also comes with a vanity invite, so please have one ready if you want to apply. To apply, drop an email at [contact@stoat.chat](mailto:contact@stoat.chat).
|
||||
|
||||
We also periodically prune verification from servers that have fallen into disrepair and / or otherwise are no longer active.
|
||||
</details>
|
||||
|
||||
For questions about the Stoat platform, you may want to go to our knowledge base:
|
||||
|
||||
- [What badges can I get?](https://support.stoat.chat/kb/account/badges)
|
||||
- [How old do I have to be to use Stoat?](https://support.stoat.chat/kb/safety/minimum-age-guidelines)
|
||||
- [Are there any restrictions on servers being on Discover?](https://support.stoat.chat/kb/safety/discover-guidelines)
|
||||
- [(... and more)](https://support.stoat.chat)
|
||||
30
docs/docs/help.md
Normal file
30
docs/docs/help.md
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# 💖 Helping Stoat!
|
||||
|
||||
You can contribute to Stoat in a variety of ways:
|
||||
|
||||
### 1. Feedback
|
||||
|
||||
The easiest, but most important, way to contribute to Stoat is to voice your opinion and give us feedback.
|
||||
We want to hear what you think and appreciate and await your feature suggestions, bug reports and general opinions on everything Stoat has to offer.
|
||||
|
||||
Typically, you can open issues on the relevant [GitHub repositories](https://github.com/stoatchat).
|
||||
|
||||
<!-- Within the Stoat app, you can navigate to the [**feedback tab**](https://app.revolt.chat/settings/feedback), or you can open an issue on the relevant [GitHub repo](https://github.com/revoltchat). -->
|
||||
|
||||
### 2. Translate
|
||||
|
||||
Stoat is used by users all around the world; as such, it's more accessible if the user interface is available in a variety of languages.
|
||||
You can contribute translations through [**Weblate**](https://translate.stoat.chat/engage/revolt/).
|
||||
|
||||
### 3. Donate
|
||||
|
||||
Stoat is not backed by a big company, is not currently monetised (for example, via a subscription service) and does not serve you advertisements; as such, Stoat currently relies entirely on donations.
|
||||
You can learn more about donating [here](https://wiki.revolt.chat/notes/project/financial-support/) - if you want to make a larger donation, please consult me first.
|
||||
|
||||
### 4. Join the project
|
||||
|
||||
We are a small team and always appreciate more help! [Check out roles we're looking for here!](https://outline.stoatinternal.com/s/454dd0eb-44b5-41f7-b1d1-b6accec577a0)
|
||||
17
docs/docs/index.md
Normal file
17
docs/docs/index.md
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# 🤗 Introduction
|
||||
|
||||
Welcome to Stoat's developer documentation. Everything you need to contribute to Stoat, build apps or bots, or to learn more about the project can be found here.
|
||||
|
||||
Learn more about:
|
||||
|
||||
- [Contributing as a developer](./developing/contrib)
|
||||
- [Other ways to help out](./help)
|
||||
|
||||
You may also be interested in the:
|
||||
|
||||
- [Frontend Book](https://stoatchat.github.io/for-web)
|
||||
- [Android Book](https://stoatchat.github.io/for-android)
|
||||
182
docs/docusaurus.config.ts
Normal file
182
docs/docusaurus.config.ts
Normal file
@@ -0,0 +1,182 @@
|
||||
import { themes as prismThemes } from 'prism-react-renderer';
|
||||
import type { Config } from '@docusaurus/types';
|
||||
import type * as Preset from '@docusaurus/preset-classic';
|
||||
import type { ScalarOptions } from '@scalar/docusaurus';
|
||||
|
||||
const config: Config = {
|
||||
title: 'Stoat Developers',
|
||||
tagline: 'Developer documentation for Stoat',
|
||||
favicon: 'https://stoat.chat/favicon.svg',
|
||||
|
||||
future: {
|
||||
v4: true,
|
||||
},
|
||||
|
||||
url: 'https://developers.stoat.chat',
|
||||
baseUrl: '/',
|
||||
|
||||
organizationName: 'stoatchat',
|
||||
projectName: 'stoatchat',
|
||||
|
||||
onBrokenLinks: 'throw',
|
||||
|
||||
i18n: {
|
||||
defaultLocale: 'en',
|
||||
locales: ['en'],
|
||||
},
|
||||
|
||||
presets: [
|
||||
[
|
||||
'classic',
|
||||
{
|
||||
docs: {
|
||||
routeBasePath: '/',
|
||||
sidebarPath: './sidebars.ts',
|
||||
editUrl:
|
||||
'https://github.com/stoatchat/stoatchat/tree/main/docs/',
|
||||
},
|
||||
} satisfies Preset.Options,
|
||||
],
|
||||
],
|
||||
|
||||
plugins: [
|
||||
[
|
||||
'@scalar/docusaurus',
|
||||
{
|
||||
label: 'API Reference',
|
||||
route: '/api-reference',
|
||||
showNavLink: true,
|
||||
configuration: {
|
||||
url: 'https://stoat.chat/api/openapi.json',
|
||||
},
|
||||
} as ScalarOptions,
|
||||
],
|
||||
[
|
||||
'@docusaurus/plugin-client-redirects',
|
||||
{
|
||||
fromExtensions: ['html', 'htm'],
|
||||
redirects: [
|
||||
// legacy docs website (stoatchat/developer-wiki)
|
||||
{
|
||||
from: '/developers/api/reference.html',
|
||||
to: '/api-reference',
|
||||
},
|
||||
{
|
||||
from: '/contrib.html',
|
||||
to: '/developing/contrib',
|
||||
},
|
||||
{
|
||||
from: '/contrib',
|
||||
to: '/developing/contrib',
|
||||
},
|
||||
],
|
||||
}
|
||||
],
|
||||
],
|
||||
|
||||
themeConfig: {
|
||||
// image: 'img/docusaurus-social-card.jpg',
|
||||
colorMode: {
|
||||
respectPrefersColorScheme: true,
|
||||
},
|
||||
navbar: {
|
||||
title: 'Stoat Developers',
|
||||
logo: {
|
||||
alt: 'Stoat',
|
||||
src: 'https://stoat.chat/favicon.svg',
|
||||
},
|
||||
items: [
|
||||
{
|
||||
type: 'doc',
|
||||
docId: 'index',
|
||||
label: 'Docs'
|
||||
},
|
||||
{
|
||||
href: 'https://github.com/stoatchat',
|
||||
label: 'GitHub',
|
||||
position: 'right',
|
||||
},
|
||||
],
|
||||
},
|
||||
footer: {
|
||||
style: 'dark',
|
||||
links: [
|
||||
{
|
||||
title: 'Developers',
|
||||
items: [
|
||||
{
|
||||
label: 'Source Code',
|
||||
href: 'https://github.com/stoatchat'
|
||||
},
|
||||
{
|
||||
label: 'Help Translate',
|
||||
href: 'https://translate.stoat.chat'
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Team',
|
||||
items: [
|
||||
{
|
||||
label: 'About',
|
||||
href: 'https://stoat.chat/about'
|
||||
},
|
||||
{
|
||||
label: 'Blog and Changelogs',
|
||||
href: 'https://stoat.chat/updates'
|
||||
},
|
||||
{
|
||||
label: 'Contact',
|
||||
href: 'https://support.stoat.chat'
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Stoat on Socials',
|
||||
items: [
|
||||
{
|
||||
label: 'Bluesky',
|
||||
href: 'https://bsky.app/profile/stoat.chat'
|
||||
},
|
||||
{
|
||||
label: 'Reddit',
|
||||
href: 'https://reddit.com/r/stoatchat'
|
||||
},
|
||||
{
|
||||
label: 'Stoat Server',
|
||||
href: 'https://stt.gg/Testers'
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Legal',
|
||||
items: [
|
||||
{
|
||||
label: 'Community Guidelines',
|
||||
href: 'https://stoat.chat/legal/community-guidelines'
|
||||
},
|
||||
{
|
||||
label: 'Terms of Service',
|
||||
href: 'https://stoat.chat/legal/terms'
|
||||
},
|
||||
{
|
||||
label: 'Privacy Policy',
|
||||
href: 'https://stoat.chat/legal/privacy'
|
||||
},
|
||||
{
|
||||
label: 'Imprint',
|
||||
href: 'https://stoat.chat/legal/imprint'
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
copyright: `© Revolt Platforms Ltd, ${new Date().getFullYear()}`,
|
||||
},
|
||||
prism: {
|
||||
theme: prismThemes.github,
|
||||
darkTheme: prismThemes.dracula,
|
||||
},
|
||||
} satisfies Preset.ThemeConfig,
|
||||
};
|
||||
|
||||
export default config;
|
||||
18000
docs/package-lock.json
generated
Normal file
18000
docs/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
50
docs/package.json
Normal file
50
docs/package.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"name": "docs",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"docusaurus": "docusaurus",
|
||||
"start": "docusaurus start",
|
||||
"build": "docusaurus build",
|
||||
"swizzle": "docusaurus swizzle",
|
||||
"deploy": "docusaurus deploy",
|
||||
"clear": "docusaurus clear",
|
||||
"serve": "docusaurus serve",
|
||||
"write-translations": "docusaurus write-translations",
|
||||
"write-heading-ids": "docusaurus write-heading-ids",
|
||||
"typecheck": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.9.2",
|
||||
"@docusaurus/plugin-client-redirects": "^3.9.2",
|
||||
"@docusaurus/preset-classic": "3.9.2",
|
||||
"@mdx-js/react": "^3.0.0",
|
||||
"@scalar/docusaurus": "^0.7.21",
|
||||
"clsx": "^2.0.0",
|
||||
"prism-react-renderer": "^2.3.0",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/module-type-aliases": "3.9.2",
|
||||
"@docusaurus/tsconfig": "3.9.2",
|
||||
"@docusaurus/types": "3.9.2",
|
||||
"typescript": "~5.6.2"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.5%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 3 chrome version",
|
||||
"last 3 firefox version",
|
||||
"last 5 safari version"
|
||||
]
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0"
|
||||
},
|
||||
"packageManager": "pnpm@10.22.0+sha512.bf049efe995b28f527fd2b41ae0474ce29186f7edcb3bf545087bd61fbbebb2bf75362d1307fda09c2d288e1e499787ac12d4fcb617a974718a6051f2eee741c"
|
||||
}
|
||||
11448
docs/pnpm-lock.yaml
generated
Normal file
11448
docs/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
5
docs/pnpm-workspace.yaml
Normal file
5
docs/pnpm-workspace.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
ignoredBuiltDependencies:
|
||||
- core-js-pure
|
||||
|
||||
onlyBuiltDependencies:
|
||||
- core-js
|
||||
49
docs/sidebars.ts
Normal file
49
docs/sidebars.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import type { SidebarsConfig } from '@docusaurus/plugin-content-docs';
|
||||
|
||||
const sidebars: SidebarsConfig = {
|
||||
docsSidebar: [
|
||||
'index',
|
||||
'help',
|
||||
'faq',
|
||||
{
|
||||
type: 'category',
|
||||
label: "Developers",
|
||||
link: {
|
||||
type: "generated-index",
|
||||
description: "Building with Stoat"
|
||||
},
|
||||
items: [
|
||||
{
|
||||
type: 'autogenerated',
|
||||
dirName: 'developers',
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: "Developing Stoat",
|
||||
link: {
|
||||
type: "generated-index",
|
||||
description: "Building Stoat"
|
||||
},
|
||||
items: [
|
||||
{
|
||||
type: 'autogenerated',
|
||||
dirName: 'developing',
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
label: "for Web",
|
||||
href: "https://stoatchat.github.io/for-web"
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
label: "for Android",
|
||||
href: "https://stoatchat.github.io/for-android"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
};
|
||||
|
||||
export default sidebars;
|
||||
0
docs/static/.nojekyll
vendored
Normal file
0
docs/static/.nojekyll
vendored
Normal file
0
docs/static/img/.gitkeep
vendored
Normal file
0
docs/static/img/.gitkeep
vendored
Normal file
8
docs/tsconfig.json
Normal file
8
docs/tsconfig.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
// This file is not used in compilation. It is here just for a nice editor experience.
|
||||
"extends": "@docusaurus/tsconfig",
|
||||
"compilerOptions": {
|
||||
"baseUrl": "."
|
||||
},
|
||||
"exclude": [".docusaurus", "build"]
|
||||
}
|
||||
Reference in New Issue
Block a user