L'API REST
Tot el que fan les aplicacions d'Antimatter passa per la mateixa API HTTP, de manera que els vostres scripts també ho poden fer. Aquesta pàgina explica com autenticar-se, els recursos que utilitzareu més, com són les respostes i els errors, i com seguir els esdeveniments en directe mitjançant WebSocket.
Bases
- URL base:
https://chat.example.com/api/v4. Tots els punts d'accés següents són relatius a aquesta URL. - Format: JSON a l'entrada i a la sortida, excepte les pujades de fitxers (multipart). Envieu
Content-Type: application/json. - Identificadors: cada objecte té un
idde 26 caràcters. Els temps són mil·lisegons des de l'època Unix (create_at,update_at,delete_at; 0 significa «no suprimit»). - Les comunitats són equips: l'API els anomena
teams, amb unteam_id. - Tu mateix/a: en qualsevol ruta que accepti un
user_id,mefa referència a l’usuari iniciat, com enGET /users/me.
La llista completa de punts d'accés es troba al codi del servidor: les rutes es declaren a server/channels/api4/*.go i els tipus a server/public/model. La descripció OpenAPI de la carpeta api/v4/source del repositori cobreix els punts d'accés heretats de Mattermost i algunes addicions d'Antimatter: moure fils, connexions de models, agents, normes de la comunitat, mode de concentració i accions de missatges. La resta només es troben al codi.
Autenticació
Totes les peticions, excepte l'inici de sessió i alguns punts d'accés públics, requereixen un token a la capçalera Authorization:
curl -H "Authorization: Bearer $TOKEN" https://chat.example.com/api/v4/users/me
S'accepten tres tipus de token: tokens d'accés personals, tokens de sessió i tokens d'accés OAuth. També s'accepta Authorization: Token …. Els tokens a la cadena de consulta (?access_token=) només s'accepten per a tokens d'accés OAuth.
Tokens d'accés personals (recomanats per a scripts)
Un token d'accés personal actua com a vosaltres, no caduca llevat que li assigneu una data de caducitat, i es pot revocar en qualsevol moment. Els tokens d'accés personals estan desactivats per defecte:
- Un administrador del sistema habilita Habilita els tokens d’accés personals a Consola del sistema › Integracions › Gestió d'integracions (
ServiceSettings.EnableUserAccessTokens,AM_SERVICESETTINGS_ENABLEUSERACCESSTOKENS). - Per a cada persona que pugui crear fitxes d'accés, un administrador del sistema obre Consola del sistema › Gestió d'usuaris › Usuaris, tria Gestiona els rols al menú de la persona i marca Permet que aquest compte generi fitxes d'accés personals. Els administradors del sistema sempre poden crear-les.
- La persona obre el seu avatar a la part superior dreta i després Perfil i configuració › Seguretat. Sota Tokens d'accés personals, descriu per a què servirà el token i tria Crea un token. El token es mostra només una vegada: copia’l.
Mitjançant l'API: POST /users/{user_id}/tokens amb {"description": "backup script", "expires_at": 0} (expires_at en mil·lisegons; 0 si no n'hi ha). El camp token de la resposta és el secret; el seu id és el que s'usa per revocar-lo (POST /users/tokens/revoke amb {"token_id": "…"}). Des de la línia d'ordres: amctl token generate <user> <description>.
Un administrador del sistema pot establir un límit de durada per als tokens mitjançant Durada màxima dels tokens d’accés personals (dies) a la mateixa pàgina de la Consola del sistema.
Fitxes de sessió
Iniciar sessió amb una contrasenya retorna una fitxa de sessió a la capçalera de resposta Token, el mateix tipus de sessió que utilitzen les aplicacions:
curl -i -X POST https://chat.example.com/api/v4/users/login \
-H 'Content-Type: application/json' \
-d '{"login_id": "maya", "password": "…"}'
Afegeix "token": "123456" per a un compte amb autenticació multifactor. Les sessions expiren segons els paràmetres de sessió del servidor, i el punt d'entrada d'inici de sessió té un límit de freqüència (5 sol·licituds per segon). POST /users/logout finalitza la sessió.
X-CSRF-Token per a qualsevol cosa que no sigui GET; una fitxa a la capçalera Authorization no necessita capçalera CSRF.Aplicacions OAuth 2.0
Per permetre que les persones iniciïn sessió a la vostra aplicació amb el seu compte d'Antimatter, registreu una aplicació OAuth 2.0. Antimatter serà llavors el proveïdor OAuth:
- Habilita el proveïdor de serveis OAuth 2.0 ha d’estar activat (Consola del sistema › Integracions › Gestió d'integracions,
ServiceSettings.EnableOAuthServiceProvider, activat per defecte). - Una persona amb permís per gestionar aplicacions OAuth (administradors del sistema per defecte) obre Integracions › Aplicacions OAuth 2.0 (menú de la comunitat › Configuració de l’equip › Integracions) i afegeix l'aplicació amb les seves URL de devolució de trucada. Obté un identificador de client i un secret de client.
- La vostra aplicació envia les persones a
https://chat.example.com/oauth/authorizeambresponse_type=code,client_id,redirect_uriistate. Es suporta PKCE ambcode_challenge_method=S256. - Intercanvia el codi a
POST https://chat.example.com/oauth/access_token(grant_type=authorization_code, i desprésrefresh_tokenper renovar-lo) i crida la API ambAuthorization: Bearer <access token>.
Les persones veuen les aplicacions que han autoritzat a Perfil i configuració › Seguretat › Aplicacions que has autoritzat.
Recursos principals
| Què | Punts finals |
|---|---|
| Vosaltres i altres persones | GET /users/me, GET /users/{user_id}, GET /users/username/{username}, POST /users/ids (una llista d'ID), POST /users/search, GET /users?in_team=…&in_channel=… |
| Comunitats | GET /users/me/teams, GET /teams/{team_id}, GET /teams/name/{name}, PUT /teams/{team_id}/patch, GET /teams/{team_id}/members, POST /teams/{team_id}/members |
| Canals | GET /users/me/teams/{team_id}/channels, GET /teams/name/{team}/channels/name/{channel}, POST /channels, POST /channels/direct (dos ID d'usuari), POST /channels/group, POST /channels/{channel_id}/members |
| Missatges (publicacions) | POST /posts, GET /posts/{post_id}, PUT /posts/{post_id}/patch, DELETE /posts/{post_id}, GET /channels/{channel_id}/posts, GET /posts/{post_id}/thread, POST /teams/{team_id}/posts/search |
| Reaccions | POST /reactions amb {"user_id", "post_id", "emoji_name"}, DELETE /users/{user_id}/posts/{post_id}/reactions/{emoji_name} |
| Fitxers | POST /files (multipart: channel_id i files), i després poseu els ID retornats a file_ids del missatge; GET /files/{file_id} |
| Preferències | GET /users/me/preferences, PUT /users/me/preferences |
| Integracions | /hooks/incoming, /hooks/outgoing, /commands, /bots, /oauth/apps (vegeu les pàgines següents) |
| Servidor | GET /system/ping (estat de salut, no cal token), GET /config/client?format=old (la configuració que veuen els clients) |
Publicar un missatge
curl -X POST https://chat.example.com/api/v4/posts \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"channel_id": "'$CHANNEL_ID'", "message": "Backup finished: **42 GB** in 3 min"}'
Els missatges són Markdown. Afegiu "root_id" (el primer missatge d'un fil) per respondre en un fil, "file_ids" per als fitxers i "props" per als adjunts i altres elements addicionals (vegeu Adjunts).
Trobar l'ID d'un canal
curl -H "Authorization: Bearer $TOKEN" \
https://chat.example.com/api/v4/teams/name/lumen-labs/channels/name/ops-alerts
Els noms són els del vincle del canal: /lumen-labs/channels/ops-alerts.
Paginació
Els punts finals de llistes accepten page (des de 0) i per_page (60 per defecte, com a màxim 200). Seguiu demanant la pàgina següent fins que una pàgina torni més curta que per_page.
Els missatges d'un canal (GET /channels/{channel_id}/posts) també accepten since (un temps: tot el que ha canviat des d'aleshores), o before i after (un ID de publicació). Torna com una llista de publicacions: {"order": [IDs, newest first], "posts": {ID: post}, "next_post_id", "prev_post_id"}.
Errors
Els errors utilitzen els codis d'estat HTTP habituals (400 entrada incorrecta, 401 no autenticat, 403 no permès, 404 no trobat, 501 funció desactivada) i un cos JSON:
{
"id": "api.context.permissions.app_error",
"message": "You do not have the appropriate permissions.",
"detailed_error": "",
"request_id": "jz8zm5nunpbt8f3gpqsz5dq6so",
"status_code": 403
}
Utilitzeu id al vostre codi: message es tradueix a la llengua de l'usuari. detailed_error queda buit, llevat que el servidor s'executi en mode de desenvolupament (ServiceSettings.EnableDeveloper). Citeu request_id a l'administrador del servidor: es troba als registres.
Límits de freqüència
La limitació de freqüència està desactivada per defecte. Quan un administrador del sistema l’activa (Consola del sistema › Entorn › Limitació de freqüència), cada client rep 10 sol·licituds per segon amb pics de 100 per defecte, comptades per adreça IP o per usuari. Les respostes inclouen X-RateLimit-Limit, X-RateLimit-Remaining i X-RateLimit-Reset; si es supera el límit, el servidor respon 429 amb una capçalera Retry-After en segons. Alguns punts d’accés, com ara l’inici de sessió, tenen el seu propi límit independentment de la configuració.
Escriveu scripts que esperin i tornin a provar en cas de 429, i eviteu la sondeja: seguiu el WebSocket en lloc d'això.
El flux d'esdeveniments del WebSocket
Connecteu-vos a wss://chat.example.com/api/v4/websocket. Autentiqueu-vos amb la capçalera Authorization: Bearer a la petició de connexió, o bé enviant això com a primer missatge:
{"seq": 1, "action": "authentication_challenge", "data": {"token": "…"}}
El servidor envia un esdeveniment hello i, a continuació, un esdeveniment per a tot el que esteu autoritzats a veure:
{
"event": "posted",
"data": {"channel_id": "…", "channel_type": "O", "post": "{\"id\":\"…\",\"message\":\"Hello\",…}"},
"broadcast": {"channel_id": "…", "team_id": "", "user_id": "", "omit_users": null},
"seq": 4
}
Ateneu-vos que data.post és el missatge com a cadena JSON. Esdeveniments habituals: posted, post_edited, post_deleted, reaction_added, reaction_removed, typing, status_change, user_added, direct_added. Les aplicacions envien els seus propis esdeveniments, anomenats custom_<app id>_<event>.
També podeu enviar accions, cadascuna amb un seq creixent: user_typing amb {"channel_id", "parent_id"}, o get_statuses. Reconnecteu-vos quan la connexió es trenqui i recupereu el que heu perdut amb since (vegeu Paginació).
Antimatter afegeix aquests esdeveniments: agent_activity_changed i agent_post_stream (vegeu Agents), ai_tools_changed (vegeu Agents), community_rules_updated i community_rules_accepted (vegeu Regles de la comunitat), focus_ended (vegeu Mode de concentració), community_attributes_updated, member_timeouts_updated, post_put_on_top, post_removed_from_top, server_categories_updated, channel_overrides_updated i category_overrides_updated. Un nou inici de sessió al vostre propi compte envia session_created a les altres sessions (session_id, create_at, platform, os, browser, mobile; mai un token), i gestionar-ne l'avís envia session_revoked o session_acknowledged (session_id) a totes.
Biblioteques de client
- Vés:
model.Client4aserver/public/model(importagithub.com/mattermost/mattermost/server/public/model).model.NewAPIv4Client(url), desprésclient.SetToken(token);model.NewWebSocketClient4(wsURL, token)segueix els esdeveniments. La còpia d’Antimatter afegeix mètodes per als seus propis punts d’accés, com araUpdateMessageRequest,PutPostOnTopiExportChannel. - TypeScript: la classe
Client4de@mattermost/client, awebapp/platform/client, amb els seus tipus awebapp/platform/types. La còpia al repositori d'Antimatter inclou els punts d'accés d'Antimatter; el paquet publicat a npm per Mattermost no els inclou.
package main
import (
"context"
"log"
"github.com/mattermost/mattermost/server/public/model"
)
func main() {
client := model.NewAPIv4Client("https://chat.example.com")
client.SetToken("…")
post, _, err := client.CreatePost(context.Background(), &model.Post{
ChannelId: "…",
Message: "Hello from Go",
})
if err != nil {
log.Fatal(err)
}
log.Println("posted", post.Id)
}
Què afegeix Antimatter a la API
Aquests punts d'accés i camps no existeixen en un servidor de Mattermost. Tots ells requereixen una sessió.
| Punt d'accés | Què fa |
|---|---|
GET /teams/{team_id}/user_attributes/fieldsPOST mateix camíPATCH, DELETE …/fields/{field_id} | Atributs de la comunitat: els camps del perfil que els administradors d'una comunitat defineixen per als seus membres (màxim 20). Els membres els poden llegir; els administradors de la comunitat els creen i els modifiquen. |
GET /teams/{team_id}/members/{user_id}/user_attributesPATCH mateix camíPOST /teams/{team_id}/user_attributes/values/search | Els valors dels atributs d'un membre, com a {field_id: value}. Els membres estableixen els propis (excepte els gestionats pels administradors); els administradors estableixen els de qualsevol persona. La cerca rep {"user_ids": [...]} (màxim 200). |
GET /teams/{team_id}/timeoutsPUT /teams/{team_id}/members/{user_id}/timeoutGET /teams/{team_id}/members/{user_id}/moderation | Temps d'espera: {"until": time, "reason": "…"} impedeix a algú publicar, reaccionar i penjar fitxers a la comunitat fins a aquest moment (màxim 28 dies); "until": 0 el revoca. La vista de moderació mostra quan es van unir i quants missatges han publicat recentment. |
GET /channels/{channel_id}/on_topPUT, DELETE /posts/{post_id}/on_top | Missatges fixats a la part superior d'un canal (màxim 10). {"duration": ms}, com a màxim 30 dies; 0 els manté fins que es suprimeixin. Qualsevol persona que pugui llegir el canal els pot veure. Per fixar un missatge o treure'l de la part superior cal tenir permís per publicar al canal i, en un canal d'una comunitat, ser administrador del canal o de la comunitat, o tenir-hi Gestiona els missatges (delete_others_posts). En un missatge directe o de grup, els membres poden fer-ho. Es rebutja en canals arxivats. |
GET, PUT /teams/{team_id}/rulesPOST /teams/{team_id}/rules/acceptGET /teams/{team_id}/rules/stats | Normes de la comunitat: vegeu Normes de la comunitat. |
GET, POST, DELETE /users/me/focusGET /users/me/focus/summary?since=&until=POST /users/me/focus/summary/read | Mode de concentració: vegeu Mode de concentració. |
POST /channels/{channel_id}/message_request | Actua sobre la teva pròpia sol·licitud de missatge: {"action": "accept"}, "dismiss" o "request" per tornar a posar una conversa entre les sol·licituds. Retorna el teu membre del canal. |
GET, PUT /channels/{channel_id}/overridesGET /channels/{channel_id}/overrides/effectiveGET, PUT /channels/{channel_id}/role_access | Què pot fer un rol o una persona en un canal, i quins rols veuen un canal restringit per rol. |
GET, PUT /teams/{team_id}/server_categoriesGET, PUT …/server_categories/overrides | Les categories de canals compartides de la comunitat, i les substitucions que s'apliquen a tots els canals d'una categoria. |
GET /groups/{group_id}/team_rolePUT …/team_role/permissions | Els permisos que atorga un rol de la comunitat. |
POST /teams/{team_id}/autolinks/preview | Prova les regles d'enllaços automàtics de la comunitat en un text. |
POST /channels/{channel_id}/export?format=csv&since=&until= | Descarrega els missatges d'un canal en format CSV (fins a 50.000), per a les persones que poden llegir el canal. |
GET /posts/{post_id}/speech | El missatge llegit en veu alta, en format d'àudio, quan s'ha configurat la conversió de text a veu. |
POST /posts/{post_id}/move_to_channel | Mou un fil a un altre canal de la mateixa comunitat: consulta Mou un fil. |
GET, POST /ai/connectionsGET, PATCH, DELETE /ai/connections/{connection_id}GET /ai/connections/usable | Connexions de models, els proveïdors d'IA que utilitzen les funcions i les aplicacions d'IA del servidor: consulta Connexions de models. |
GET, POST /ai/agentsGET, PATCH, DELETE /ai/agents/{agent_id}POST /ai/agents/{agent_id}/tasksGET /ai/agents/conversations | Agents d'IA, la seva activitat i les tasques i converses del xat d'IA: vegeu Agents. |
GET /ai/agents/{agent_id}/toolsGET /ai/agents/tools/cataloguePOST /ai/tools/calls/{call_id}/confirm, /declineGET, POST /ai/mcp_serversGET, PATCH, DELETE /ai/mcp_servers/{server_id}POST, DELETE /ai/mcp_servers/{server_id}/oauth | Les eines d'un agent, el catàleg d'eines que pot utilitzar, confirmar o rebutjar una crida d'eina pendent, i els servidors MCP disponibles per als agents: vegeu IA. |
GET /channels/{channel_id}/message_actionsPOST /posts/{post_id}/message_actions/{hook_id}GET, POST /hooks/outgoing/{hook_id}/icon | Accions de missatges: webhooks sortints que les persones executen des del menú del missatge. Consulta Accions de missatges. |
POST /users/me/sessions/acknowledge | Descarta l'avís de nou inici de sessió d'una de les vostres pròpies sessions: {"session_id"}. Només l'usuari amb sessió iniciada pot fer aquesta crida, i només per a les seves pròpies sessions. |
PUT /channels/{channel_id}/type | Canvia el preset d'un canal o la seva configuració: vegeu Tipus de canal. |
GET /channels/{channel_id}/topicsPATCH /posts/{post_id}/topic | Els temes d'un fòrum, i acceptar una resposta o establir l'estat d'un tema: vegeu Tipus de canal. |
Nous camps
- Comunitats (
TeamiPUT /teams/{team_id}/patch):all_channels_membership(tothom forma part de tots els canals que pot veure),default_channel_id(on van a parar els nouvinguts),welcome_channel_id(on van els missatges d'entrada i sortida; buit si no n'hi ha cap),kind(communityoworkplace, mostrats a la interfície com Guild i Workspace: un gremi també activaall_channels_membership; les comunitats noves reben el valor deTeamSettings.DefaultCommunityKinddel servidor,community/Guild per defecte),member_list_view(com agrupa la llista de membres els membres:choice, per defecte, permet que cada membre triï;rolesoteamsho fixa),hide_role_colors,require_team_badges,name_display(com mostra la comunitat les persones: buit per al valor predeterminat del servidor),onboardingiautolinks(tots dos cadenes JSON). - El canal per defecte d'una nova comunitat és
general(General), notown-square. La actualització a la 0.9.0 canvia el nom detown-squarede cada comunitat ageneral, mantenint-ne l'ID, llevat que la comunitat ja tingui un canalgeneral. Els noms antics continuen funcionant:GET /teams/{team_id}/channels/name/town-square,GET /teams/name/{team}/channels/name/town-squarei elchanneld'un webhook entrant donen el canal per defecte de la comunitat quan cap canal té aquest nom. Utilitzeudefault_channel_id, o el nomgeneral, en el codi nou. - Enllaços de canals: els enllaços
#channel-nameenllacen un canal, com fan els~channel-name. La propietatchannel_mentionsde la publicació llista els canals enllaçats de qualsevol manera; un#wordque no correspon a cap canal es manté com a hashtag. La interfície web i l'aplicació mòbil d'Antimatter escriuen#name. - Els canals arxivats encara accepten nous membres (
POST /channels/{channel_id}/members), que poden llegir-ne l'historial. Ningú no pot publicar-hi, reaccionar-hi, fixar-hi res, posar-hi un missatge a la part superior, canviar-ne el nom ni modificar-hi els rols dels membres. - Respostes en línia: una publicació amb
"props": {"reply_to": "<post id>"}cita aquest missatge del mateix canal. Afegeix"reply_to_mention": falseper no notificar-ne l'autor. El servidor omplemetadata.reply_toamb una descripció breu del missatge citat. - Alertes de contingut:
"props": {"spoiler": true}amaga el text i els fitxers d'una publicació fins que el lector decideixi veure'ls. - Ignorar i bloquejar són preferències: categoria
user_block, anomenada segons el ID de l'altra persona, amb el valorignoreoblock. Si un missatge directe espera com a sol·licitud, es troba alnotify_props.dm_requestdel teu membre del canal (pending,acceptedodismissed). - Els adjunts de missatge poden portar
stagesi unchart: consulta Targetes. - Canals (
Channel): elspropsde cada canal de comunitat sempre portenam_type(text,voiceoforum),am_mode,am_root_posts(membersomoderators) iam_preset(l'ID del preset corresponent, o buit per a configuracions personalitzades), i, per als fòrums,am_forum_view(topicsoimageboard). Una càrrega útil senseam_typesignifica que no s'ha omplert, mai que el canal sigui de text. Els missatges directes i de grup no porten cap d'aquests camps. Vegeu Tipus de canal.
Tipus de canal
Un canal de comunitat és text, voice o forum (el seu tipus, fixat quan es crea), en un dels modes del seu tipus, amb configuracions al damunt. Un preset és un conjunt amb nom d'un mode i configuracions que un client ofereix com una sola opció; els presets no s'emmagatzemen, així que el preset d'un canal (am_preset) es deriva de les seves configuracions, i llegeix "" quan no coincideixen amb cap preset ("Personalitzat").
| ID del preset | Tipus | Mode | root_posts | view |
|---|---|---|---|---|
text_chat | text | chat | members | – |
text_announcement | text | chat | moderators | – |
voice_talk | voice | talk | members | – |
voice_stage | voice | stage | members | – |
forum_agora | forum | discussion | members | topics |
forum_qa | forum | qa | members | topics |
forum_ideas | forum | ideas | members | topics |
forum_announcement | forum | discussion | moderators | topics |
forum_imageboard | forum | discussion | members | imageboard |
Creació i canvi del tipus d'un canal
POST /channels llegeix props.am_preset (que s'expandeix primer) i, a sobre, les propietats individuals props.am_type, am_mode, am_root_posts i am_forum_view; qualsevol altra propietat am_ es descarta. Es rebutja la creació d'un canal de veu si l'aplicació Canals de veu no està activa (400 api.channel.type.voice_unavailable.app_error); també es rebutja la creació d'un missatge directe o de grup amb propietats de tipus (api.channel.type.direct.app_error).
curl -X POST https://chat.example.com/api/v4/channels \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"team_id": "'$TEAM_ID'", "name": "help-desk", "display_name": "Help desk", "type": "O",
"props": {"am_preset": "forum_qa"}}'
PUT /channels/{channel_id}/type canvia el predefinit o la configuració d'un canal existent: {"preset"?, "mode"?, "root_posts"?, "view"?}, amb el predefinit expandit primer, com en la creació. Cal tenir el permís manage_public_channel_properties o manage_private_channel_properties al canal (esdeveniment d'auditoria updateChannelType), i respon amb el canal completat. Es rebutja un cos que indiqui un altre type (api.channel.type.fixed.app_error): el tipus en si mai no canvia. Altres errors: api.channel.type.invalid.app_error (un valor desconegut, un mode que no correspon al tipus del canal o una vista en un canal que no és de fòrum).
La importació i l'exportació massives (amctl import bulk) inclouen els mateixos quatre camps a la línia d'un canal: am_type, am_mode, am_root_posts, am_forum_view. Una línia de canal sense aquests camps s'importa com un canal de xat de text normal, com abans dels tipus de canal.
Qui inicia converses o obre temes
Publicar un missatge arrel (a diferència d'una resposta) requereix el permís create_root_post, que a l'editor de substitucions apareix com Iniciar converses (text, veu) o Obri temes (fòrums). Cap rol el té per defecte: abans de les substitucions, el té tothom que pot publicar quan root_posts és members, i només els moderadors del canal (administradors del sistema, administradors de la comunitat, administradors del canal i qualsevol persona amb Gestiona els missatges allà) quan és moderators. Una substitució de rol o de persona sobre create_root_post s'aplica a sobre, com qualsevol altre permís. Una resposta (amb root_id definit) només requereix el dret ordinari a publicar.
Un missatge d'arrel que no compleix aquest requisit rep un 403: app.post.root_posts.moderators_only.app_error quan root_posts és moderators i l'autor no és moderador del canal, o app.post.root_posts.denied.app_error per a un rebuig explícit. Això es comprova per a l'API REST, els bots, els webhooks entrants i sortints (al creador del webhook) i les respostes de les comandes amb barra; els missatges d'apps (l'API de plugins) i les còpies d'un fil mogut no es comproven (allà es comprova la persona que mou el fil). La importació massiva també l'omet.
Els fòrums només accepten temes
En un fòrum, un missatge d'arrel necessita props.am_thread_title (el títol del seu tema), sense espais en blanc al principi o al final, d'1 a 100 caràcters, de qualsevol origen, incloses les apps i els fils moguts: si falta, rep 400 app.post.forum.title_required.app_error; si és massa llarg, app.post.forum.title_too_long.app_error. Les respostes no necessiten títol, i qualsevol títol enviat en una resposta es descarta. Editar l'arrel d'un tema sense títol, o amb un de buit, manté el seu títol existent; un de no buit el canvia. Moure un fil a un fòrum (més avall) també necessita un títol, de la sol·licitud o del propi fil.
La resposta acceptada d'un tema de Q&A (am_accepted_answer, l'ID d'una resposta) i l'estat d'un tema d'Idees (am_topic_status, amb am_topic_status_by i am_topic_status_at) només s'escriuen mitjançant PATCH /posts/{post_id}/topic; qualsevol d'aquests tres camps enviat en la creació, actualització o parcheig, per un client o una app, es descarta i es manté el valor emmagatzemat.
Llista els temes d'un fòrum
GET /channels/{channel_id}/topics?sort=votes&per_page=25
Cal tenir el permís per llegir el canal. Paràmetres de consulta:
sort:activity(predeterminat),newest,votes,unanswered(només Q&A) ostatus(només Idees).answered(true/false, Q&A) istatus(un deopen,planned,in_progress,done,declined, Idees): filtra per aquests. Utilitzar qualsevol d'ells fora del seu mode dona400.mine=true: només els temes que has iniciat.following=true: només els que segueixes.q: coincideix amb el títol o el text del primer missatge, fins a 200 caràcters.before: elnext_cursorde la pàgina anterior.per_page: 25 per defecte, 100 com a màxim.replies: de 0 a 5 de les últimes respostes de cada tema, per a una vista de tauler d'imatges.
Resposta: {"topics": [{"post", "reply_count", "last_reply_at", "participant_ids", "votes", "accepted_answer_id", "status", "on_top", "replies": [post, …]}], "next_cursor"}. Els vots són les reaccions 👍 (+1 i thumbsup comptades conjuntament), menys l'autor del tema; accepted_answer_id només s'indica als fòrums de preguntes i respostes, status només als fòrums d'idees. Els temes fixats al canal apareixen primer.
Accepta una resposta o estableix l'estat d'un tema
curl -X PATCH https://chat.example.com/api/v4/posts/$POST_ID/topic \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"accepted_answer_id": "'$REPLY_ID'"}'
post_id ha de ser la publicació arrel d'un tema de fòrum; si no, 400 app.topic.not_a_topic.app_error. accepted_answer_id (l'ID d'una resposta, o "" per desfer-ho) requereix un fòrum de preguntes i respostes; status requereix un fòrum d'idees; si s'utilitza en el mode incorrecte, 400 app.topic.mode.app_error.
- Acceptar una resposta: només ho pot fer qui ha fet la pregunta (mentre pugui publicar-hi) o un moderador del canal; si no,
403 app.topic.accept.not_allowed.app_error. La resposta ha de ser una resposta activa i no del sistema d'aquell tema; si no,400 app.topic.accept.not_a_reply.app_error. Si s'elimina la resposta acceptada, es desfa l'acceptació. - Establir un estat: només els moderadors del canal, si no,
403 app.topic.status.not_allowed.app_error; un valor desconegut provoca400 app.topic.status.invalid.app_error.
Cada canvi publica una resposta del sistema al tema (informant-ne els seguidors) i respon amb la publicació arrel del tema, tal com queda ara. En un fòrum d'idees, votar un tema també fa que el segueixis.
Mou un fil
POST /posts/{post_id}/move_to_channel mou un fil, el seu primer missatge i totes les seves respostes, a un altre canal de la mateixa comunitat. post_id pot ser el primer missatge o qualsevol resposta.
curl -X POST https://chat.example.com/api/v4/posts/$POST_ID/move_to_channel \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"channel_id": "'$TARGET_CHANNEL_ID'", "flatten": false}'
channel_id(obligatori): el canal on es mou el fil.flatten(per defectefalse):truefa que les respostes siguin missatges del canal de destinació en lloc d'un fil. La funció Converteix-lo en un canal de Fusion l'utilitza. Es rebutja si la destinació és un fòrum (400 app.post.move_thread.forum_flatten.app_error): les seves respostes es convertiren en temes sense títol.title: el títol del tema, quan la destinació és un fòrum. Si no s'indica, es manté el títol del fil, si en té; si no n'hi ha cap,400 app.post.move_thread.forum_title_required.app_error. S'ignora si la destinació no és un fòrum.
Els missatges mantenen els seus autors, hores, reaccions i fitxers. Les seves còpies porten la propietat silent_notification, de manera que no notifiquen ningú. Els missatges originals s'eliminen. La resposta és el primer missatge mogut, amb el seu nou ID.
Qui pot moure un fil
- Heu de poder llegir el fil i publicar al canal de destinació.
- Els administradors del canal, els administradors de la comunitat, les persones amb Gestiona els missatges (
delete_others_posts) al canal i els administradors del sistema poden moure qualsevol fil. - L'autor del fil el pot moure quan tots dos canals són públics, o quan tots els missatges del fil són seus. En cas contrari, la resposta és
403amb l'IDapi.post.move_thread.private_needs_moderator.app_error. - Ambdós canals han de pertànyer a la mateixa comunitat (no missatges directes ni de grup), ser diferents i no estar arxivats. No es poden moure missatges de sistema ni missatges que s'eliminen en llegir-los.
- Un fil amb més de
WranglerSettings.MoveThreadMaxCountmissatges (100 per defecte; 0 per sense límit) es rebutja.
El punter i la nota
El moviment deixa dos missatges de sistema de tipus system_wrangler: un punter al canal d'origen («Un fil amb 13 missatges s'ha mogut a #target») i una nota al destí («Aquest fil s'ha mogut des de #source»), sota el fil mogut o, amb flatten, després dels seus missatges. A més del text del missatge, les seves propietats permeten a un client dibuixar el nom del canal com un enllaç:
- El punter:
MovedThreadPermalink,NumMessages,MovedThreadChannelId,MovedThreadTeamName,MovedThreadPostIdi, per a un destí públic,MovedThreadChannelNameiMovedThreadChannelDisplayName. - La nota:
MovedFromChannelId,MovedFromTeamName,MovedFromPostId(el punter),MovedFromPermalinki, per a un origen públic,MovedFromChannelNameiMovedFromChannelDisplayName.
Ambdós tenen també un TranslationID. El nom d'un canal privat s'ometeix: els lectors veuen «un altre canal». L'endpoint POST /posts/{post_id}/move de Mattermost queda desactivat a Antimatter; utilitza aquest endpoint.
Normes de la comunitat
Els administradors d'una comunitat poden exigir que els seus membres acceptin les normes abans de publicar als seus canals. Mentre les normes estan activades, un membre que no hagi acceptat la versió actual no pot publicar, respondre, enviar fitxers, programar, editar o restaurar un missatge, ni executar una comanda que publiqui als canals de la comunitat: el servidor respon amb 403 i l'ID api.post.community_rules_not_accepted, i un missatge programat que arriba aleshores falla amb el codi d'error community_rules_not_accepted. La lectura, les reaccions i els missatges directes i de grup no es bloquegen; tampoc els bots, els webhooks d'entrada, els missatges del sistema ni els administradors de la comunitat (permís manage_team, que també tenen els administradors del sistema).
| Punt d'accés | Què fa |
|---|---|
GET /teams/{team_id}/rules | Les regles (enabled, text en Markdown, version), amb la darrera versió que has acceptat (accepted_version) i si cal acceptar-les abans de publicar (must_accept). Per als membres i per a qualsevol persona que pugui unir-se a una comunitat oberta. |
PUT /teams/{team_id}/rules | Les desa, amb {"enabled", "text", "ask_again"} (manage_team). ask_again crea una nova versió que tothom ha de tornar a acceptar; el primer desament correspon a la versió 1. El text és obligatori per activar-les i pot tenir com a màxim 16.000 caràcters. |
POST /teams/{team_id}/rules/accept | Accepta, com a membre, la version que has llegit; retorna 409 si s'ha desat una versió més nova des de llavors, i 0 accepta la versió actual. |
GET /teams/{team_id}/rules/stats | Quants membres de la comunitat han acceptat la versió actual (manage_team). |
L'event community_rules_updated s'envia a la comunitat quan un administrador desa les regles (team_id, enabled, version), i community_rules_accepted a la persona que les ha acceptat, en totes les seves sessions (team_id, version).
Mode de concentració
El mode de concentració és un estat de No molestar amb una hora de finalització: les notificacions es silencien (no hi ha notificacions push, per correu electrònic, d'escriptori ni persistents, inclosos els missatges urgents), el motiu es converteix en l'estat personal amb l'emoji 🎯 (dart), que caduca al final del temps, i les aplicacions d'Antimatter amaguen les insígnies de no llegits de la persona. Només la persona mateixa pot utilitzar aquests endpoints (me o el seu propi ID): ningú més, inclosos els administradors del sistema, pot iniciar, finalitzar o llegir el mode de concentració d'una altra persona ni el seu resum.
| Punt d'accés | Què fa |
|---|---|
GET /users/me/focus | El mode de concentració actual (active, start_at, end_at, reason), o l'últim un cop ha finalitzat (ended_at definit), o tots els valors a zero. |
POST /users/me/focus | Inicia el mode de concentració o, si ja està actiu, canvia la finalització i el motiu: {"duration": "1h30m", "reason": "…"}, o bé {"end_at": ms} en lloc de la durada, des d'un minut fins a una setmana vista. "duration": "tomorrow" finalitza a les 09:00 del dia següent en la zona horària de la persona. La finalització s'arrodoneix a la baixa al minut; el motiu pot tenir com a màxim 100 caràcters. Cal que els estats d'usuari estiguin activats (ServiceSettings.EnableUserStatuses); els bots no poden activar el mode de concentració. |
DELETE /users/me/focus | Finalitza el mode de concentració ara. |
GET /users/me/focus/summary?since=&until= | El que s'ha omès en aquesta finestra (el start_at i l'ended_at d'una atenció): els canals amb missatges no llegits d'altres persones (primer els missatges directes i de grup, després els que tenen mencions; els canals silenciats només si hi ha una menció) i, amb els fils de resposta plegats, els fils seguits amb noves respostes, cadascun amb el seu recompte, les mencions i l'últim remitent. |
POST /users/me/focus/summary/read | Amb {"since", "until"}: marca com a llegits fins a until només aquests canals i fils; el que ve després continua com a no llegit. |
Mentre una persona té l'atenció activada, el seu usuari té la propietat focus_until (en mil·lisegons), que els clients utilitzen per mostrar l'estat d'atenció; no es pot canviar des del perfil. L'atenció finalitza quan la persona la tanca, quan arriba el temps (en un minut) o quan tria un estat per si mateixa, que llavors es manté. En cas contrari, tornen l'estat i l'estat personalitzat anteriors. Totes les seves sessions reben llavors l'event focus_ended, amb start_at, end_at i ended_by (user, timer o status).
Connexions de models
Una connexió de model és l'adreça i la clau d'un proveïdor d'IA, configurada per un administrador. Les funcions d'IA del servidor i les aplicacions que criden el servei d'IA les utilitzen. Els administradors de sistema gestionen les connexions de tot el servidor (manage_ai_connections); els administradors d'una comunitat gestionen les de la seva comunitat (manage_team_ai_connections). Les claus són només d'escriptura: cap resposta les conté, només api_key_set i api_key_last4.
| Punt d'accés | Què fa |
|---|---|
GET /ai/connections?scope= | Les connexions que gestiones. scope és server o l'ID d'una comunitat; sense ell, tots els àmbits que gestiones. |
POST /ai/connections | Afegeix una connexió (respon 201). |
POST /ai/connections/test, POST /ai/connections/models | Prova una connexió, o n'enumera els models, abans de desar-la. Mateix cos que per afegir-ne una; no es desa res. |
GET, PATCH (o PUT), DELETE /ai/connections/{connection_id} | Llegeix, canvia o elimina una connexió. Un patch porta només els camps a canviar; deixa fora api_key per mantenir la clau. |
POST /ai/connections/{connection_id}/test | Prova una connexió desada: {"ok", "error", "status_code", "latency_ms", "model_count"}. |
GET /ai/connections/{connection_id}/models | Els models que ofereix el proveïdor. |
GET /ai/connections/{connection_id}/usage | Les sol·licituds i els tokens d'aquest mes. |
GET /ai/connections/usable?channel_id=&team_id= | Per a qualsevol usuari iniciat: les connexions que hi podeu utilitzar, amb els seus models i capacitats, mai les seves claus o adreces. |
El cos d'una connexió nova:
{
"name": "Local models",
"scope": "server",
"provider": "openai_compatible",
"base_url": "http://llm.internal:8000/v1",
"api_key": "…",
"extra_headers": {},
"models": {"chat": "qwen3-32b", "embeddings": "", "transcription": "", "decisions": ""},
"limits": {"requests_per_minute": 0, "monthly_token_budget": 0, "per_user_requests_per_minute": 0, "per_user_monthly_token_budget": 0},
"sharing": {"all_teams": true, "team_ids": []},
"audience": {"everyone": true, "group_ids": [], "roles": [], "allow_guests": false}
}
provider és openai_compatible o anthropic. scope per defecte és server; l'ID d'una comunitat la converteix en la connexió d'aquesta comunitat. A limits, 0 significa sense límit; les sol·licituds per minut es compten a cada servidor, i els pressupostos de tokens per mes calendàric (UTC) són per a tot el clúster. sharing indica quines comunitats poden utilitzar una connexió de tot el servidor (els missatges directes i de grup requereixen all_teams), i audience qui pot utilitzar-la; els invitats només amb allow_guests. Els canvis s'escriuen al registre d'auditoria. La guia d'administració explica la configuració: vegeu IA.
Agents
Un agent és un compte de bot del tipus agent (is_agent en el seu usuari), amb la seva configuració: l'àmbit (server o l'ID d'una comunitat), si és integrat o external, i, en el cas d'un agent integrat, la connexió al model, el model, la indicació del sistema i el raonament. Els administradors del sistema gestionen els agents de tot el servidor (manage_system) i els administradors d'una comunitat gestionen els de la seva comunitat (manage_team). A més, manage_own_agent permet gestionar un agent propi i manage_others_agent permet gestionar els d'altres. En aquestes rutes, l'ID de l'agent és el seu ID d'usuari. L'execució d'un agent extern i la manera com es defineix l'estat d'un agent integrat s'expliquen a Bots; PUT /users/{user_id}/status i els punts d'accés d'estat personalitzat rebutgen l'ID d'un agent integrat, fins i tot per als administradors del sistema (403, api.status.agent.app_error).
| Punt d'accés | Què fa |
|---|---|
GET /ai/agents?scope= | Els agents que gestiones: scope és server o l'ID d'una comunitat; si no s'indica, tots els agents que gestiones. |
POST /ai/agents | Crea un agent i el seu compte (respon 201). Un agent d'una comunitat s'uneix a la seva comunitat. |
GET, PATCH, DELETE /ai/agents/{agent_id}POST …/enable, POST …/disable | Llegeix, modifica, elimina (el seu compte es desactiva, els seus missatges es mantenen), activa o desactiva un agent. |
GET /ai/agents/connections?scope=GET /ai/agents/connections/{connection_id}/models | Les connexions al model que un agent d'aquest àmbit pot utilitzar, i els seus models. |
GET, PUT /ai/agents/{agent_id}/activityPOST /ai/agents/activity/ids | El que està fent un agent; definit pel seu propi token o pels seus gestors. El lot accepta fins a 200 IDs d'usuari. |
POST /ai/agents/{agent_id}/tasks | Demana a un agent integrat que podeu utilitzar per a una tasca: summarize_thread, find_action_items o find_open_questions (al post_id d'un fil, o a un channel_id des de since en endavant), summarize_channel, ask_channel (amb una question) o summarize_transcription (la publicació de la transcripció d'una trucada). La sol·licitud es converteix en el vostre missatge al vostre missatge directe amb l'agent, en el vostre idioma, i es respon allà mateix; la resposta (201) és aquest missatge. Una publicació o un canal que no podeu llegir es considera inexistent. |
GET /ai/agents/conversations?agent_id=&before=&per_page= | Les vostres converses amb els agents que podeu utilitzar, de la més recent a la més antiga: els fils que heu iniciat als vostres missatges directes amb ells, i els fils d'altres llocs on un d'ells ha respost i que seguiu. before (una hora) proporciona la pàgina següent; per_page és com a màxim 100. |
El cos d'un nou agent:
{
"username": "researcher",
"display_name": "Researcher",
"description": "Answers with sources",
"scope": "server",
"external": false,
"connection_id": "…",
"model": "",
"system_prompt": "You research questions and answer with sources.",
"reasoning": {"enabled": false, "effort": "", "budget_tokens": 0},
"max_tool_turns": 0,
"access": {"everyone": true, "team_ids": [], "channel_ids": [], "roles": [], "user_ids": [], "allow_guests": false}
}
Un model buit utilitza el model de xat de la connexió. access.channel_ids fa referència als membres d'aquests canals. Un agent extern no té connexió, model ni indicador del sistema. GET /agents enumera els agents amb qui podeu parlar, tal com els llegeix l'aplicació de xat amb IA.