💾 Archived View for blakes.dev › hdoc › 4A6xCFoqTxK_D4VkQKntvA.gmi captured on 2024-12-17 at 09:19:04. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2024-05-10)

-=-=-=-=-=-=-

Common Community Client API

Source (manually imported from Hedgedoc)

This is a brief draft of what a common, standards-based client-server API for community chat-like apps could look like. The intent is to allow a variety of clients and a variety of servers, all with different intents, separately implementing a common-denominator API for client apps to use.

Authentication

Clients MUST be authenticated to use all non-GET endpoints, and any GET endpoints marked for authentication. This is handled by the server, but clients should expect to use OAuth2 against the server to ask for chat rights.

Well-Known Endpoints

GET /.well-known/cccapi-host.json

Should respond with a static file, modeled after the following:

json
{
    "base_url": "https://example.com/_community_clients_/",
    "display_name": "Example Community",
    "authorize": "https://example.com/oauth2/authorize"
}

Endpoints

GET /topics

Lists public topics, or topics that the authenticated user has access to. Topics are roughly equivalent to channels.

This does NOT correspond with the topics a user is listening to. This should be remembered in the client.

Response example (application/json):

json
{
    "topicId": {
        "name": "Topic name",
        "description": "The topic description to show in a list."
    },
    "topicId2": {
        "name": "Topic 2 title",
        "description": "Topic 2 tagline or summary"
    },
    "emptyTopic": {}
}

Response example (text/csv):

csv
topicId,Topic name,Topic description
topicId2,Topic 2 name,Topic 2 description
emptyTopic,,

GET /topic/:id/messages

Lists the messages in a room.

Response example (multipart/mixed):

http
200 OK
Content-Type: multipart/mixed; boundary="-Boundary-c29dab8"
X-Earliest-Message-ID: <EarliestMessageID>
X-Latest-Message-ID: <LatestMessageID>

---Boundary-c29dab8
Content-Type: text/markdown; variant=CommonMark
From: Display Name <somekindofid@example.com>
From-Avatar-URL: https://example.com/avatar.png
Date: Wed, 24 May 2023 18:13:33 +0000
Message-ID: <EarliestMessageID>

This is the earliest message.
---Boundary-c29dab8
Content-Type: text/markdown; variant=GFM
From: Display Name <somekindofid@example.com>
Date: Wed, 24 May 2023 18:14:18 +0000
Message-ID: <MessageID2>

I could write a table here but I won't.
---Boundary-c29dab8
Content-Type: text/plain
From: Display Name <somekindofid@example.com>
Date: Wed, 24 May 2023 18:15:23 +0000
Message-ID: <LatestMessageID>

This is the last message. It's plain text.
---Boundary-c29dab8--

Response example (application/json):

json
{
    "latest": "LatestMessageID",
    "earliest": "EarliestMessageID",
    "messages": [
        {
            "type": "text/markdown; variant=CommonMark",
            "from": {
                "name": "Display Name",
                "id": "somekindofid@example.com"
            },
            "timestamp": 1684966413000,
            "content": "This is the earliest message.",
        },
        {
            "type": "text/markdown; variant=GFM",
            "from": {
                "name": "Display Name",
                "id": "somekindofid@example.com"
            },
            "timestamp": 1684966458000,
            "content": "I could write a table here but I won't."
        },
        {
            "type": "text/plain",
            "from": {
                "name": "Display Name",
                "id": "somekindofid@example.com"
            },
            "timestamp": 1684966523000,
            "content": "This is the last message. It's plain text."
        }
    ]
}