REST API
Всичко, което приложенията на Antimatter извършват, минава през един и същ HTTP API, така че и скриптовете ви могат да го направят. Тази страница обяснява как да се автентифицирате, кои ресурси ще използвате най-често, как изглеждат отговорите и грешките и как да следите събития в реално време през WebSocket.
Основни понятия
- Базов URL:
https://chat.example.com/api/v4. Всички ендпойнти по-долу са относителни към него. - Формат: JSON влязо и излязо, с изключение на качване на файлове (multipart). Изпращайте
Content-Type: application/json. - Идентификатори: всеки обект има 26-символен
id. Времето е в милисекунди от Unix epoch (create_at,update_at,delete_at; 0 означава „не е изтрито“). - Общностите са екипи: API-то ги нарича
teams, сteam_id. - Само вас: навсякъде, където пътят приема
user_id,meозначава текущия влязъл потребител, както вGET /users/me.
Пълният списък с крайни точки е в кода на сървъра: маршрутите са декларирани в server/channels/api4/*.go, а типовете – в server/public/model. Описанието на OpenAPI в папката api/v4/source на хранилището обхваща крайните точки, наследени от Mattermost, и някои от допълненията на Antimatter: преместване на нишки, връзки с модели, агенти, правила на екипа, режим на фокус и действия със съобщения. Останалите са само в кода.
Автентификация
Всяка заявка, с изключение на влизане и няколко публични ендпойнта, изисква токен в заглавието Authorization:
curl -H "Authorization: Bearer $TOKEN" https://chat.example.com/api/v4/users/me
Приемат се три вида токени: лични достъпни токени, сесийни токени и OAuth достъпни токени. Приема се и Authorization: Token …. Токените в query string (?access_token=) се приемат само за OAuth достъпни токени.
Лични достъпни токени (препоръчани за скриптове)
Личният достъпен токен действа от ваше име, не изтича, освен ако не му зададете срок на валидност, и може да бъде отменен по всяко време. Личните достъпни токени са изключени по подразбиране:
- Системният администратор активира Разреши маркери за личен достъп в Системна конзола › Интеграции › Управление на интеграциите (
ServiceSettings.EnableUserAccessTokens,AM_SERVICESETTINGS_ENABLEUSERACCESSTOKENS). - За всеки, който може да създава токени, системният администратор отваря Системна конзола › Управление на потребители › Потребители, избира Управление на роли от менюто на съответния човек и отметва Разреши на този акаунт да генерира лични достъпни токени. Системните администратори винаги могат да ги създават.
- Потребителят отваря аватара си в горния десен ъгъл, след което Профил и настройки › Сигурност. Под Лични маркери за достъп описва за какво е предназначен маркерът и избира Създайте маркер. Маркерът се показва само веднъж: копирайте го.
Чрез API: POST /users/{user_id}/tokens с {"description": "backup script", "expires_at": 0} (expires_at е в милисекунди; 0 означава без срок). Поле token в отговора е тайната стойност; id се използва за отмяна (POST /users/tokens/revoke с {"token_id": "…"}). От командния ред: amctl token generate <user> <description>.
Системният администратор може да ограничи срока на валидност на маркерите чрез Максимален срок на валидност на личния достъпен токен (дни) на същата страница в Системната конзола.
Сесийни токени
Входът с парола връща сесийен токен в заглавието на отговора Token, същия тип сесия, който използват приложенията:
curl -i -X POST https://chat.example.com/api/v4/users/login \
-H 'Content-Type: application/json' \
-d '{"login_id": "maya", "password": "…"}'
Добавете "token": "123456" за акаунт с мултифакторна автентикация. Сесиите изтичат според настройките за сесии на сървъра, а входният endpoint е с ограничение на честотата (5 заявки в секунда). POST /users/logout приключва сесията.
X-CSRF-Token за всичко, което не е GET; токен в заглавието Authorization не изисква CSRF заглавие.Приложения за OAuth 2.0
За да позволите на хората да влизат в вашето приложение с акаунта си в Antimatter, регистрирайте OAuth 2.0 приложение. Antimatter става OAuth доставчик:
- Разреши доставчик OAuth 2.0 услуги трябва да е активиран (Системна конзола › Интеграции › Управление на интеграциите,
ServiceSettings.EnableOAuthServiceProvider, активиран по подразбиране). - Потребител с права за управление на OAuth приложенията (по подразбиране системните администратори) отваря Интеграции › OAuth 2.0 приложения (менюто на екипа › Настройки на екипа › Интеграции) и добавя приложението с неговите URL адреси за обратно извикване. Получава идентификатор на клиент и клиентска тайна.
- Приложението ви изпраща потребителите на
https://chat.example.com/oauth/authorizeсresponse_type=code,client_id,redirect_uriиstate. Поддържа се PKCE сcode_challenge_method=S256. - Кодът се разменя на
POST https://chat.example.com/oauth/access_token(сgrant_type=authorization_code, а после сrefresh_tokenза подновяване), а API-то се извиква сAuthorization: Bearer <access token>.
Потребителите виждат приложенията, на които са дали достъп, в Профил и настройки › Сигурност › Приложения, на които сте дали достъп.
Основни ресурси
| Какво | Крайни точки |
|---|---|
| Вие и други потребители | GET /users/me, GET /users/{user_id}, GET /users/username/{username}, POST /users/ids (списък с ID-та), POST /users/search, GET /users?in_team=…&in_channel=… |
| Общности | 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 |
| Канали | GET /users/me/teams/{team_id}/channels, GET /teams/name/{team}/channels/name/{channel}, POST /channels, POST /channels/direct (два потребителски ID-та), POST /channels/group, POST /channels/{channel_id}/members |
| Съобщения (пости) | 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 |
| Реакции | POST /reactions с {"user_id", "post_id", "emoji_name"}, DELETE /users/{user_id}/posts/{post_id}/reactions/{emoji_name} |
| Файлове | POST /files (multipart: channel_id и files), после поставете върнатите ID-та в file_ids на поста; GET /files/{file_id} |
| Предпочитания | GET /users/me/preferences, PUT /users/me/preferences |
| Интеграции | /hooks/incoming, /hooks/outgoing, /commands, /bots, /oauth/apps (вижте следващите страници) |
| Сървър | GET /system/ping (състояние, не изисква токен), GET /config/client?format=old (настройките, които клиентите виждат) |
Изпращане на съобщение
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"}'
Съобщенията са в Markdown. Добавете "root_id" (първото съобщение в нишка), за да отговорите в нишка, "file_ids" за файлове и "props" за прикачени файлове и други допълнения (вижте Прикачени файлове).
Намиране на ID на канал
curl -H "Authorization: Bearer $TOKEN" \
https://chat.example.com/api/v4/teams/name/lumen-labs/channels/name/ops-alerts
Имената са тези от връзката към канала: /lumen-labs/channels/ops-alerts.
Пагинация
Списъчните крайни точки приемат page (от 0) и per_page (по подразбиране 60, максимум 200). Продължавайте да искате следващата страница, докато не се върне страница, по-къса от per_page.
Съобщенията в канал (GET /channels/{channel_id}/posts) също приемат since (време: всичко, променено от тогава нататък), или before и after (ID на съобщение). Те се връщат като списък със съобщения: {"order": [IDs, newest first], "posts": {ID: post}, "next_post_id", "prev_post_id"}.
Грешки
Грешките използват стандартните HTTP статуси (400 невалиден вход, 401 неавторизиран, 403 не е разрешено, 404 не е намерено, 501 функцията е изключена) и JSON тяло:
{
"id": "api.context.permissions.app_error",
"message": "You do not have the appropriate permissions.",
"detailed_error": "",
"request_id": "jz8zm5nunpbt8f3gpqsz5dq6so",
"status_code": 403
}
Използвайте id в кода си: message се превежда на езика на потребителя. detailed_error е празно, освен ако сървърът не работи в разработчически режим (ServiceSettings.EnableDeveloper). Посочете request_id на администратора на сървъра: той се намира в логовете.
Ограничения на честотата
Ограничаването на трафика е изключено по подразбиране. Когато системният администратор го активира (Системна конзола › Обкръжение › Ограничаване на трафика), всеки клиент получава 10 заявки в секунда с възможност за скок до 100 по подразбиране, преброени по IP адрес или по потребител. Отговорите съдържат X-RateLimit-Limit, X-RateLimit-Remaining и X-RateLimit-Reset; при надхвърляне на лимита сървърът отговаря с 429 и заглавка Retry-After в секунди. Някои краища, като влизане, имат собствен лимит независимо от настройката.
Пишете скриптове, които чакат и опитват отново при 429, и избягвайте опитите за периодично извличане: следете WebSocket вместо това.
Потокът с WebSocket събития
Свържете се с wss://chat.example.com/api/v4/websocket. Автентифицирайте се или с заглавка Authorization: Bearer в заявката за свързване, или като изпратите това като първо съобщение:
{"seq": 1, "action": "authentication_challenge", "data": {"token": "…"}}
Сървърът изпраща събитие hello, а след това събитие за всичко, което имате право да виждате:
{
"event": "posted",
"data": {"channel_id": "…", "channel_type": "O", "post": "{\"id\":\"…\",\"message\":\"Hello\",…}"},
"broadcast": {"channel_id": "…", "team_id": "", "user_id": "", "omit_users": null},
"seq": 4
}
Забележете, че data.post е съобщението като JSON низ. Чести събития: posted, post_edited, post_deleted, reaction_added, reaction_removed, typing, status_change, user_added, direct_added. Приложенията изпращат собствените си събития, наречени custom_<app id>_<event>.
Можете също да изпращате действия, всяко с нарастващо seq: user_typing с {"channel_id", "parent_id"}, или get_statuses. Върнете се, когато връзката се прекъсне, и извличете пропуснатото с since (вижте Пагинация).
Antimatter добавя следните събития: agent_activity_changed и agent_post_stream (вижте Агенти), ai_tools_changed (вижте Агенти), community_rules_updated и community_rules_accepted (вижте Правила на общността), focus_ended (вижте Режим на фокус), community_attributes_updated, member_timeouts_updated, post_put_on_top, post_removed_from_top, server_categories_updated, channel_overrides_updated и category_overrides_updated. Новото влизане във вашия собствен акаунт изпраща session_created към другите ви сесии (session_id, create_at, platform, os, browser, mobile; никога не се изпраща токен), а обработването на предупреждението изпраща session_revoked или session_acknowledged (session_id) към всички тях.
Библиотеки за клиент
- Отиди:
model.Client4вserver/public/model(импортирайтеgithub.com/mattermost/mattermost/server/public/model).model.NewAPIv4Client(url), след коетоclient.SetToken(token);model.NewWebSocketClient4(wsURL, token)следва събитията. Копието на Antimatter добавя методи за собствените си краища, катоUpdateMessageRequest,PutPostOnTopиExportChannel. - TypeScript: класът
Client4от@mattermost/client, вwebapp/platform/client, с типовете му вwebapp/platform/types. Копието в репозиторията на Antimatter включва ендпойнтите на Antimatter; пакетът, публикуван на npm от Mattermost, не ги включва.
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)
}
Какво Antimatter добавя към API-то
Тези ендпойнти и полета не съществуват на сървър на Mattermost. Всички изискват сесия.
| Ендпойнт | Какво прави |
|---|---|
GET /teams/{team_id}/user_attributes/fieldsPOST същия пътPATCH, DELETE …/fields/{field_id} | Атрибути на общността: полетата на профила, които администраторите на общността дефинират за нейните членове (до 20). Членовете могат да ги четат; администраторите на общността ги създават и променят. |
GET /teams/{team_id}/members/{user_id}/user_attributesPATCH същия пътPOST /teams/{team_id}/user_attributes/values/search | Стойностите на атрибутите на член, като {field_id: value}. Членовете задават собствените си (освен администрираните от администратори); администраторите задават на всеки. Търсенето приема {"user_ids": [...]} (до 200). |
GET /teams/{team_id}/timeoutsPUT /teams/{team_id}/members/{user_id}/timeoutGET /teams/{team_id}/members/{user_id}/moderation | Изчаквания: {"until": time, "reason": "…"} спира някой да публикува, реагира и качва в общността до тогава (до 28 дни); "until": 0 го вдига. Изгледът за модерация показва кога са се присъединили и колко са публикували наскоро. |
GET /channels/{channel_id}/on_topPUT, DELETE /posts/{post_id}/on_top | Съобщения, задържани в горната част на канал (до 10). {"duration": ms}, максимум 30 дни; 0 ги задържа, докато не бъдат премахнати. Всеки, който може да чете канала, вижда списъка им. За да се постави съобщение в горната част или да се махне, е необходимо право за публикуване в канала и, в канал на общност, да се бъде администратор на канала или на общността, или да се има Управление на съобщения (delete_others_posts) там. В директно или групово съобщение това могат да направят неговите членове. В архивирани канали това се отхвърля. |
GET, PUT /teams/{team_id}/rulesPOST /teams/{team_id}/rules/acceptGET /teams/{team_id}/rules/stats | Правила на екипа: вижте Правила на екипа. |
GET, POST, DELETE /users/me/focusGET /users/me/focus/summary?since=&until=POST /users/me/focus/summary/read | Режим на фокус: вижте Режим на фокус. |
POST /channels/{channel_id}/message_request | Действа върху вашето искане за съобщение: {"action": "accept"}, "dismiss" или "request", за да върнете разговор сред исканията. Връща вашия член на канала. |
GET, PUT /channels/{channel_id}/overridesGET /channels/{channel_id}/overrides/effectiveGET, PUT /channels/{channel_id}/role_access | Какво може да направи роля или човек в канал и кои роли виждат канал, достъпът до който е ограничен по роли. |
GET, PUT /teams/{team_id}/server_categoriesGET, PUT …/server_categories/overrides | Споделените категории канали на общността и изключенията, които се прилагат към всеки канал в дадена категория. |
GET /groups/{group_id}/team_rolePUT …/team_role/permissions | Разрешенията, които предоставя роля на общността. |
POST /teams/{team_id}/autolinks/preview | Тества правилата за автоматични връзки на общността върху даден текст. |
POST /channels/{channel_id}/export?format=csv&since=&until= | Изтегля съобщенията от канал като CSV (до 50 000) за хора, които имат право да четат канала. |
GET /posts/{post_id}/speech | Съобщението, прочетено на глас като аудио, когато е настроена функция за превръщане на текст в реч. |
POST /posts/{post_id}/move_to_channel | Премества нишка в друг канал от същата общност: вижте Преместване на нишка. |
GET, POST /ai/connectionsGET, PATCH, DELETE /ai/connections/{connection_id}GET /ai/connections/usable | Връзки с модели, доставчиците на изкуствен интелект, които използват функциите и приложенията с ИИ на сървъра: вижте Връзки с модели. |
GET, POST /ai/agentsGET, PATCH, DELETE /ai/agents/{agent_id}POST /ai/agents/{agent_id}/tasksGET /ai/agents/conversations | AI агенти, тяхната дейност и задачите и разговорите на AI чата: вижте Агенти. |
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 | Инструментите на агента, каталогът с инструменти, които той може да използва, потвърждаването или отказването на чакащо извикване на инструмент и MCP сървърите, достъпни за агенти: вижте AI. |
GET /channels/{channel_id}/message_actionsPOST /posts/{post_id}/message_actions/{hook_id}GET, POST /hooks/outgoing/{hook_id}/icon | Действия върху съобщения: изходящи Webhook-ове, които хората изпълняват от менюто на съобщението. Вижте Действия върху съобщения. |
POST /users/me/sessions/acknowledge | Премахва предупреждението за ново влизане на една от вашите собствени сесии: {"session_id"}. Само влезлият потребител може да извика това за своите собствени сесии. |
PUT /channels/{channel_id}/type | Променя предварително зададеното състояние на канал или неговите настройки: вижте Типове канали. |
GET /channels/{channel_id}/topicsPATCH /posts/{post_id}/topic | Темите във форум и приемането на отговор или задаването на статус на тема: вижте Типове канали. |
Нови полета
- Общности (
TeamиPUT /teams/{team_id}/patch):all_channels_membership(всички са членове на всеки канал, който могат да видят),default_channel_id(каналът, в който попадат новите потребители),welcome_channel_id(каналът, в който се изпращат съобщенията за присъединяване и напускане; оставете празно, за да няма такива),kind(communityилиworkplace, показвани в интерфейса съответно като Guild и Workspace: при избор на guild се активира иall_channels_membership; новите общности получават стойността наTeamSettings.DefaultCommunityKindот сървъра, която по подразбиране еcommunity/Guild),member_list_view(как списъкът с членове групира потребителите:choice(по подразбиране) позволява на всеки член да избере;rolesилиteamsфиксира начина на групиране),hide_role_colors,require_team_badges,name_display(как общността показва имената на потребителите; оставете празно за сървърната настройка по подразбиране), както иonboardingиautolinks(и двете са JSON низове). - Каналът по подразбиране на ново общност е
general(General), а неtown-square. Апгрейдът до 0.9.0 преименуваtown-squareна всяка общност вgeneral, запазвайки идентификатора ѝ, освен ако общността вече няма каналgeneral. Старите имена продължават да действат:GET /teams/{team_id}/channels/name/town-square,GET /teams/name/{team}/channels/name/town-squareиchannelна входящ webhook връщат канала по подразбиране на общността, когато няма канал с това име. Използвайтеdefault_channel_idили иметоgeneralв новия код. - Връзки към канали:
#channel-nameсъздава връзка към канал, както и~channel-name. Свойствотоchannel_mentionsна публикацията изброява каналите, свързани по който и да е от двата начина;#word, който не отговаря на име на канал, остава хаштаг. Уеб интерфейсът и мобилното приложение на Antimatter използват#name. - Архивирани канали все още приемат нови членове (
POST /channels/{channel_id}/members), които могат да четат историята им. Никой не може да публикува, да реагира, да закача, да поставя съобщение на върха, да преименува канала или да променя ролята на членовете му там. - Вградени отговори: публикация с
"props": {"reply_to": "<post id>"}цитира това съобщение от същия канал. Добавете"reply_to_mention": false, за да не се уведомява авторът. Сервърът попълваmetadata.reply_toс кратко описание на цитираното съобщение. - Спойлери:
"props": {"spoiler": true}скрива текста и файловете на публикация, докато читателят не реши да ги види. - Игнорирането и блокирането са предпочитания: категория
user_block, наименувана според ID-то на другия човек, със стойностignoreилиblock. Дали директно съобщение чака като заявка се намира вnotify_props.dm_requestна вашия член на канала (pending,acceptedилиdismissed). - Прикачените файлове към съобщения могат да носят
stagesиchart: вижте Карти. - Канали (
Channel):propsна всеки канал в общността винаги съдържаam_type(text,voiceилиforum),am_mode,am_root_posts(membersилиmoderators) иam_preset(идентификаторът на съответния набор от настройки или празен низ за персонализирани настройки), а за форуми – иam_forum_view(topicsилиimageboard). Ако в данните липсваam_type, това означава, че полето не е попълнено, а не че каналът е текстов. Директните и груповите съобщения не съдържат тези полета. Вижте Типове канали.
Типове канали
Канал в общност е text, voice или forum (типът се определя окончателно при създаването на канала), работи в един от режимите на своя тип и има допълнителни настройки. Наборът от настройки (preset) е именувано обединение на режим и настройки, което клиентът предлага като един избор; наборите не се съхраняват, затова am_preset на канала се извлича от неговите настройки и приема стойност "", когато те не съответстват на нито един набор ("Персонализирано").
| Идентификатор на набора | Тип | Режим | 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 |
Създаване и промяна на типа на канал
POST /channels чете props.am_preset (който се разгръща първи), след което отделните props.am_type, am_mode, am_root_posts и am_forum_view върху него; всеки друг am_ параметър се игнорира. Създаването на гласов канал, когато приложението за гласови канали не е активно, се отказва (400 api.channel.type.voice_unavailable.app_error); създаването на директно или групово съобщение с параметри за тип се отказва (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 променя предварителната настройка или настройките на съществуващ канал: {"preset"?, "mode"?, "root_posts"?, "view"?}, като предварителната настройка се разгръща първо, както при създаването. Изисква се разрешаването manage_public_channel_properties или manage_private_channel_properties в канала (одиторско събитие updateChannelType) и връща попълнения канал. Тяло на заявката, което посочва друг type, се отказва (api.channel.type.fixed.app_error): самият тип никога не се променя. Други грешки: api.channel.type.invalid.app_error (неизвестна стойност, режим, който не е от типа на канала, или изглед за не-форум).
Масовият внос и износ (amctl import bulk) носят същите четири полета в реда на канала: am_type, am_mode, am_root_posts, am_forum_view. Реда на канал без тях се внася като обикновен текстов канал за чат, както преди въвеждането на типовете канали.
Кой може да започва разговори или да отваря теми
Публикуването на основно съобщение (за разлика от отговор) изисква разрешаването create_root_post, което в редактора за замяна на разрешенията се показва като Започване на разговори (текст, глас) или Отваряне на теми (форуми). Никоя роля не го притежава: преди замяната на разрешенията, всеки, който може да публикува, го има, когато root_posts е members, а само модераторите на канала (системни администратори, администратори на общност, администратори на канал и всеки с Управление на съобщения там) го имат, когато е moderators. Замяната на разрешението create_root_post за роля или човек се прилага отгоре, както за всяко друго разрешение. Отговорът (root_id зададен) изисква само обичайното право за публикуване.
Коренов пост, който не отговаря на това изискване, връща 403: app.post.root_posts.moderators_only.app_error, когато root_posts е moderators, а автора не е модератор на канала, или app.post.root_posts.denied.app_error при явно забраняващо заместване. Проверката се извършва за REST API, ботове, входящи и изходящи webhooks (за създателя на hook-а) и отговори на команди с наклонена черта; постове от приложения (чрез Plugin API) и копия на преместени нишки не се проверяват (там се проверява лицето, което премества нишката). Масовият импорт също пропуска тази проверка.
Форумите приемат само теми
В форум кореновият пост изисква props.am_thread_title (заглавието на темата), с премахнати водещи и крайни интервали, между 1 и 100 знака, независимо от източника (включително приложения и преместени нишки): липсващото заглавие връща 400 app.post.forum.title_required.app_error, а твърде дългото – app.post.forum.title_too_long.app_error. Отговорите не изискват заглавие и всяко изпратено заглавие в отговор се игнорира. Редактирането на кореновия пост на тема без заглавие или с празно такова запазва съществуващото заглавие; непразното заглавие я преименува. Преместването на нишка във форум (по-долу) също изисква заглавие – от заявката или от самата нишка.
Приетият отговор на тема от тип Q&A (am_accepted_answer, ID на отговор) и статусът на тема от тип Ideas (am_topic_status, заедно с am_topic_status_by и am_topic_status_at) се записват единствено чрез PATCH /posts/{post_id}/topic; ако някое от тези три полета е изпратено при създаване, обновяване или patch от клиент или приложение, то се игнорира и съхранената стойност се запазва.
Изброяване на темите във форум
GET /channels/{channel_id}/topics?sort=votes&per_page=25
Изисква се право за четене на канала. Параметри на заявката:
sort:activity(по подразбиране),newest,votes,unanswered(само за Q&A) илиstatus(само за Ideas).answered(true/false, Q&A) иstatus(едно отopen,planned,in_progress,done,declined, Ideas): филтрирайте по тези параметри. Използването на който и да е от тях извън съответния режим връща400.mine=true: само темите, които сте създали.following=true: само тези, които следвате.q: съвпадение със заглавието или текста на първия пост, до 200 знака.before:next_cursorот предишната страница.per_page: по подразбиране 25, най-много 100.replies: от 0 до 5 от най-новите отговори във всяка тема, за изглед като на борда с изображения.
Отговор: {"topics": [{"post", "reply_count", "last_reply_at", "participant_ids", "votes", "accepted_answer_id", "status", "on_top", "replies": [post, …]}], "next_cursor"}. Гласовете са реакции 👍 (+1 и thumbsup се броят заедно), минус автора на самата тема; accepted_answer_id се предоставя само във форуми Q&A, status – само във форуми Ideas. Темите, закачени отгоре в канала, са първи.
Приемане на отговор или задаване на статус на тема
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 трябва да е основната публикация на тема от форум, иначе 400 app.topic.not_a_topic.app_error. accepted_answer_id (ИД на отговор или "", за да го оттеглите) изисква форум Q&A; status изисква форум Ideas; ако е зададено в грешен режим, връща 400 app.topic.mode.app_error.
- Приемане на отговор: само автора на въпроса в темата (докато все още може да публикува там) или модератор на канала; иначе
403 app.topic.accept.not_allowed.app_error. Отговорът трябва да е активен, несистемен отговор на тази тема, иначе400 app.topic.accept.not_a_reply.app_error. Изтриването на приетия отговор изчиства отговора. - Задаване на статус: само за модератори на канала, иначе
403 app.topic.status.not_allowed.app_error; неизвестна стойност връща400 app.topic.status.invalid.app_error.
Всяка промяна публикува системен отговор в темата (уведомяващ последователите ѝ) и връща основната публикация на темата, както е в момента. Във форум Ideas гласуването за тема ви прави и неин последовател.
Преместване на нишка
POST /posts/{post_id}/move_to_channel премества нишка, първото ѝ съобщение и всички отговори в друг канал от същата общност. post_id може да бъде първото съобщение или който и да е отговор.
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(задължително): каналът, в който се премества нишката.flatten(по подразбиранеfalse):trueпревръща отговорите в съобщения в целевия канал, вместо в нишка. Направи го канал на Fusion използва това. Отхвърля се, когато целевият канал е форум (400 app.post.move_thread.forum_flatten.app_error): отговорите му биха станали теми без заглавия.title: заглавието на темата, когато целевият канал е форум. Без него се запазва собственото заглавие на нишката, ако има такова; липсата на което и да е от двете връща400 app.post.move_thread.forum_title_required.app_error. Игнорира се за целеви канал, който не е форум.
Съобщенията запазват авторите, времето, реакциите и файловете си. Копиите им носят свойството silent_notification, така че не известяват никого. Оригиналите се изтриват. Отговорът е преместеното първо съобщение с новото му ID.
Кой може да премества нишка
- Трябва да можете да четете нишката и да публикувате в целевия канал.
- Администраторите на канала, администраторите на общността, хората с Управление на съобщения (
delete_others_posts) в канала и системните администратори могат да преместват всяка нишка. - Авторът на нишката може да я премести, когато и двата канала са публични, или когато всички съобщения в нишката са неговите. В противен случай отговорът е
403с IDapi.post.move_thread.private_needs_moderator.app_error. - И двата канала трябва да са в една и съща общност (не директни или групови съобщения), да са различни и да не са архивирани. Системните съобщения и съобщенията, които се изтриват при четене, не могат да бъдат преместени.
- Нишка, по-дълга от
WranglerSettings.MoveThreadMaxCountсъобщения (по подразбиране 100; 0 за без лимит), се отхвърля.
Указателят и бележката
Преместването оставя две системни съобщения от тип system_wrangler: указател в стария канал („Нишка с 13 съобщения е преместена в #target“) и бележка в целевия („Тази нишка е преместена от #source“), под преместената нишка или, при flatten, след съобщенията ѝ. Освен текста на съобщенията, техните свойства позволяват на клиента да изобразява името на канала като връзка:
- Указателят:
MovedThreadPermalink,NumMessages,MovedThreadChannelId,MovedThreadTeamName,MovedThreadPostIdи, за публична дестинация,MovedThreadChannelNameиMovedThreadChannelDisplayName. - Бележката:
MovedFromChannelId,MovedFromTeamName,MovedFromPostId(указателят),MovedFromPermalinkи, за публичен източник,MovedFromChannelNameиMovedFromChannelDisplayName.
И двете също имат TranslationID. Името на частен канал се пропуска: четците виждат „друг канал“. Собственият POST /posts/{post_id}/move на Mattermost остава изключен в Antimatter; използвайте този endpoint.
Правила на екипа
Администраторите на екип могат да изискат от членовете му да се съгласят с правилата, преди да публикуват в каналите му. Докато правилата са активни, член, който не е приел текущата версия, не може да публикува, да отговаря, да изпраща файлове, да планира, редактира или възстановява съобщение, нито да изпълнява команда, която публикува в каналите на екипа: сървърът отговаря с 403 и ID api.post.community_rules_not_accepted, а планирано съобщение, което трябва да бъде изпратено тогава, завършва с грешка с код community_rules_not_accepted. Четенето, реакциите и директните и групови съобщения не се ограничават; същото важи и за ботовете, входящите webhook-и, системните съобщения и администраторите на екипа (manage_team, което системните администратори също притежават).
| Ендпойнт | Какво прави |
|---|---|
GET /teams/{team_id}/rules | Правилата (enabled, text в Markdown, version), с последната версия, която сте приели (accepted_version), и дали трябва да приемете правилата, преди да публикувате (must_accept). За членове и за всеки, който може да се присъедини към отворена общност. |
PUT /teams/{team_id}/rules | Запазва ги с {"enabled", "text", "ask_again"} (manage_team). ask_again създава нова версия, която всеки трябва да приеме отново; първото запазване е версия 1. Текстът е задължителен, за да ги активирате, и е с максимална дължина 16 000 знака. |
POST /teams/{team_id}/rules/accept | Приема като член version, която сте прочели; връща 409, ако е запазена по-нова версия, и 0, ако приемете текущата. |
GET /teams/{team_id}/rules/stats | Броят на членовете на общността, които са приели текущата версия (manage_team). |
Събитието community_rules_updated се изпраща до общността, когато администратор запази правилата (team_id, enabled, version), а community_rules_accepted се изпраща до този, който ги е приел, във всички негови сесии (team_id, version).
Режим на фокус
Режимът на фокус е „Не ме безпокой“ с крайно време: известията се заглушават (без push, имейл, десктоп или постоянни известия, включително спешни съобщения), причината става персонализиран статус с емоджи 🎯 (dart), изтичащ в края на фокуса, и приложенията на Antimatter скриват собствените непрочетени маркери на потребителя. Само самият потребител може да използва тези крайни точки (me или неговия собствен ID): никой друг, включително системните администратори, не може да стартира, прекратява или чете фокуса на някого или неговото обобщение.
| Ендпойнт | Какво прави |
|---|---|
GET /users/me/focus | Текущият фокус (active, start_at, end_at, reason) или последният, след като е приключил (ended_at е зададено), или всички нули. |
POST /users/me/focus | Стартира фокус или, докато сте във фокус, променя края и причината: {"duration": "1h30m", "reason": "…"}, или {"end_at": ms} вместо продължителност, от един минута до една седмица напред. "duration": "tomorrow" завършва в 09:00 на следващия ден в часовата зона на потребителя. Краят се закръгля надолу до минутата; причината е с максимална дължина 100 знака. Изисква статусите на потребителите да са активирани (ServiceSettings.EnableUserStatuses); ботовете не могат да използват фокус. |
DELETE /users/me/focus | Прекратява фокуса сега. |
GET /users/me/focus/summary?since=&until= | Какво е пропуснато в този прозорец (полетата start_at и ended_at на фокуса): каналите с непрочетени съобщения от други (първо директни и групови съобщения, след това тези с споменавания; заглушените канали само при споменаване) и, при свити нишки с отговори, следваните нишки с нови отговори, всяка със своя брой, споменавания и последен изпращач. |
POST /users/me/focus/summary/read | С {"since", "until"}: маркира тези канали и нишки като прочетени само до until; съобщенията след това остават непрочетени. |
Докато някой е на фокус, потребителят му има свойството focus_until (в милисекунди), което клиентите използват за показване на статуса на фокус; то не може да се променя през профила. Фокусът приключва, когато човекът го прекрати, когато изтече времето му (в рамките на една минута) или когато той сам избере статус, който след това остава. В противен случай се възстановяват предишният статус и персонализиран статус. Тогава всички негови сесии получават събитието focus_ended, с start_at, end_at и ended_by (user, timer или status).
Връзки с модели
Моделно свързване е адресът и ключът на AI доставчик, настроени от администратор. Функциите за изкуствен интелект на сървъра и приложенията, които извикват AI услугата, ги използват. Системните администратори управляват свързванията за целия сървър (manage_ai_connections); администраторите на общност управляват собствените си (manage_team_ai_connections). Ключовете са само за запис: нито един отговор не съдържа такъв, само api_key_set и api_key_last4.
| Ендпойнт | Какво прави |
|---|---|
GET /ai/connections?scope= | Свързванията, които управлявате. scope е server или ID на общност; без него — всички обхвати, които управлявате. |
POST /ai/connections | Добавя свързване (отговаря с 201). |
POST /ai/connections/test, POST /ai/connections/models | Тества свързване или изброява моделите му, преди да бъде записано. Същият тяло като при добавяне; нищо не се съхранява. |
GET, PATCH (или PUT), DELETE /ai/connections/{connection_id} | Чете, променя или изтрива свързване. Патчът съдържа само полетата за промяна; оставете api_key извън него, за да запазите ключа. |
POST /ai/connections/{connection_id}/test | Тества записано свързване: {"ok", "error", "status_code", "latency_ms", "model_count"}. |
GET /ai/connections/{connection_id}/models | Моделите, които доставчикът предлага. |
GET /ai/connections/{connection_id}/usage | Заявките и токените за този месец. |
GET /ai/connections/usable?channel_id=&team_id= | За всеки, който е влязъл: връзките, които можете да използвате там, с техните модели и възможности, но никога с техните ключове или адреси. |
Съдържанието на нова връзка:
{
"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 е openai_compatible или anthropic. scope по подразбиране е server; ID на общност я прави връзка за тази общност. В limits, 0 означава без ограничение; заявките на минута се броят на всеки сървър, а бюджетът на токени е на календарен месец (UTC) за целия клъстер. sharing посочва кои общности могат да използват сървърна връзка (директните и груповите съобщения изискват all_teams), а audience — кой може да я използва; гости само при allow_guests. Промените се записват в журнала за одит. Ръководството за администратори обяснява настройките: вижте AI.
Агенти
Агентът е бот акаунт от тип agent (is_agent в потребителските данни), със следните настройки: обхват (server или ID на общност), тип – вграден или external, а за вграден агент – връзка с модела, модел, системен промпт и разсъждения. Системните администратори управляват агентите за цял сървър (manage_system), а администраторите на общност – тези на своята общност (manage_team). Освен това има права manage_own_agent за агент, създаден от потребителя, и manage_others_agent за останалите агенти. В тези пътища ID на агента е неговото потребителско ID. Стартирането на външен агент и начинът, по който се задава статусът на вграден агент, са описани в раздел Ботове. Крайните точки PUT /users/{user_id}/status и тези за персонализиран статус отказват ID на вграден агент, дори за системни администратори (403, api.status.agent.app_error).
| Ендпойнт | Какво прави |
|---|---|
GET /ai/agents?scope= | Агентите, които управлявате: scope е server или ID на общност; без него – всеки агент, който управлявате. |
POST /ai/agents | Създава агент и неговия акаунт (връща 201). Агент на общност се присъединява към общността. |
GET, PATCH, DELETE /ai/agents/{agent_id}POST …/enable, POST …/disable | Чете, променя, изтрива (акаунтът му се деактивира, съобщенията му остават), включва или изключва агент. |
GET /ai/agents/connections?scope=GET /ai/agents/connections/{connection_id}/models | Връзките с модели, които агент от този обхват може да използва, и техните модели. |
GET, PUT /ai/agents/{agent_id}/activityPOST /ai/agents/activity/ids | Какво прави агента; задава се от неговия собствен токен или от неговите управители. Пакетът приема до 200 потребителски ID-та. |
POST /ai/agents/{agent_id}/tasks | Задава въпрос на вграден агент, който можете да използвате за задача: summarize_thread, find_action_items или find_open_questions (за post_id на нишка или channel_id от since нататък), summarize_channel, ask_channel (с question) или summarize_transcription (запис на транскрипция от обаждане). Заявката се превръща във вашето съобщение в директното съобщение с агента, на вашия език, и получава отговор там; отговорът (201) е това съобщение. Пост или канал, които не можете да прочетете, се разглеждат като несъществуващи. |
GET /ai/agents/conversations?agent_id=&before=&per_page= | Вашите разговори с агентите, които можете да използвате, най-новите първи: нишките, които сте започнали в директните си съобщения с тях, и нишките на други места, в които някой от тях е отговорил и които следите. before (време) дава следващата страница; per_page е най-много 100. |
Тялото на нов агент:
{
"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}
}
Празен model използва модела за чат на връзката. access.channel_ids означава членовете на тези канали. Външният агент няма връзка, модел или системен промпт. GET /agents изброява агентите, с които можете да разговаряте, както ги вижда приложението за AI чат.