REST API

Mọi thao tác của các ứng dụng Antimatter đều đi qua cùng một HTTP API, vì vậy các script của bạn cũng có thể làm tương tự. Trang này giải thích cách xác thực, các tài nguyên bạn sẽ sử dụng thường xuyên nhất, cách các phản hồi và lỗi trông như thế nào, và cách theo dõi sự kiện trực tiếp qua WebSocket.

Cơ bản

  • URL gốc: https://chat.example.com/api/v4. Tất cả các endpoint bên dưới đều là đường dẫn tương đối so với URL này.
  • Định dạng: JSON cho cả đầu vào và đầu ra, ngoại trừ việc tải tệp lên (multipart). Gửi Content-Type: application/json.
  • ID: mỗi đối tượng có một id gồm 26 ký tự. Thời gian được tính bằng mili giây kể từ Unix epoch (create_at, update_at, delete_at; 0 có nghĩa là "chưa bị xóa").
  • Cộng đồng là nhóm: API gọi chúng là teams, với một team_id.
  • Bản thân bạn: ở bất kỳ nơi nào đường dẫn nhận một user_id, me có nghĩa là người dùng đã đăng nhập, như trong GET /users/me.

Danh sách đầy đủ các endpoint nằm trong mã nguồn của máy chủ: các route được khai báo trong server/channels/api4/*.go và các kiểu dữ liệu trong server/public/model. Mô tả OpenAPI trong thư mục api/v4/source của kho mã nguồn bao gồm các endpoint kế thừa từ Mattermost và một số phần bổ sung của Antimatter: di chuyển chủ đề, kết nối mô hình và các thao tác trên tin nhắn. Các endpoint khác chỉ có trong mã nguồn.

Xác thực

Mọi yêu cầu, ngoại trừ đăng nhập và một số endpoint công khai, đều cần một token trong header Authorization:

curl -H "Authorization: Bearer $TOKEN" https://chat.example.com/api/v4/users/me

Ba loại token được chấp nhận ở đó: token truy cập cá nhân, token phiên và token truy cập OAuth. Authorization: Token … cũng được chấp nhận. Token trong chuỗi truy vấn (?access_token=) chỉ được chấp nhận cho token truy cập OAuth.

Token truy cập cá nhân (khuyến nghị cho script)

Token truy cập cá nhân hoạt động thay mặt cho bạn, không hết hạn trừ khi bạn đặt ngày hết hạn, và có thể bị thu hồi bất cứ lúc nào. Token truy cập cá nhân bị tắt theo mặc định:

  1. Quản trị viên hệ thống bật Bật Mã truy cập Cá nhân trong Bảng điều khiển Hệ thống › Tích Hợp › Quản lý tích hợp (ServiceSettings.EnableUserAccessTokens, AM_SERVICESETTINGS_ENABLEUSERACCESSTOKENS).
  2. Đối với mỗi người có thể tạo token, quản trị viên hệ thống mở Bảng điều khiển Hệ thống › Quản lý người dùng › Người dùng, chọn Quản lý vai trò trong menu của người đó và đánh dấu Cho phép tài khoản này tạo token truy cập cá nhân. Quản trị viên hệ thống luôn có thể tạo token.
  3. Người dùng mở avatar ở góc trên bên phải, sau đó chọn Hồ sơ & cài đặt › Bảo mật. Trong phần Mã thông báo truy cập cá nhân, họ mô tả mục đích sử dụng của mã thông báo và chọn Tạo mã thông báo. Mã thông báo chỉ được hiển thị một lần: hãy sao chép nó.

Thông qua API: POST /users/{user_id}/tokens với {"description": "backup script", "expires_at": 0} (expires_at tính bằng mili giây; 0 nếu không có thời hạn). Trường token trong phản hồi là bí mật; trường id của nó được sử dụng để thu hồi token (POST /users/tokens/revoke với {"token_id": "…"}). Từ dòng lệnh: amctl token generate <user> <description>.

Quản trị viên hệ thống có thể giới hạn thời hạn của token bằng cách sử dụng Thời hạn tối đa của token truy cập cá nhân (ngày) trên cùng trang Bảng điều khiển Hệ thống.

Token phiên

Đăng nhập bằng mật khẩu sẽ trả về một token phiên trong tiêu đề phản hồi Token, cùng loại phiên mà các ứng dụng sử dụng:

curl -i -X POST https://chat.example.com/api/v4/users/login \
  -H 'Content-Type: application/json' \
  -d '{"login_id": "maya", "password": "…"}'

Thêm "token": "123456" cho một tài khoản có xác thực đa yếu tố. Các phiên sẽ hết hạn theo cài đặt phiên của máy chủ, và điểm cuối đăng nhập bị giới hạn tốc độ (5 yêu cầu mỗi giây). POST /users/logout sẽ kết thúc phiên.

Trình duyệt xác thực bằng cookie. Yêu cầu được xác thực bằng cookie cũng phải gửi tiêu đề X-CSRF-Token cho mọi thao tác khác ngoài GET; token trong tiêu đề Authorization không cần tiêu đề CSRF.

Ứng dụng OAuth 2.0

Để cho phép người dùng đăng nhập vào ứng dụng của bạn bằng tài khoản Antimatter, hãy đăng ký một ứng dụng OAuth 2.0. Khi đó, Antimatter sẽ đóng vai trò là nhà cung cấp OAuth:

  1. Bật nhà cung cấp dịch vụ OAuth 2.0 phải được bật (Bảng điều khiển Hệ thống › Tích hợp › Quản lý tích hợp, ServiceSettings.EnableOAuthServiceProvider, mặc định là bật).
  2. Người có quyền quản lý các ứng dụng OAuth (mặc định là quản trị viên hệ thống) mở avatar của họ, sau đó chọn Tích hợp › Ứng dụng OAuth 2.0, và thêm ứng dụng cùng với các URL callback. Họ sẽ nhận được một ID client và một bí mật client.
  3. Ứng dụng của bạn gửi người dùng đến https://chat.example.com/oauth/authorize với response_type=code, client_id, redirect_uri và state. PKCE với code_challenge_method=S256 được hỗ trợ.
  4. Nó đổi mã tại POST https://chat.example.com/oauth/access_token (grant_type=authorization_code, sau đó dùng refresh_token để làm mới), và gọi API với Authorization: Bearer <access token>.

Người dùng xem các ứng dụng đã ủy quyền trong Hồ sơ & cài đặt › Bảo mật › Ứng dụng bạn đã ủy quyền.

Tài nguyên chính

Nội dungĐiểm cuối
Bạn và người khácGET /users/me, GET /users/{user_id}, GET /users/username/{username}, POST /users/ids (một danh sách ID), POST /users/search, GET /users?in_team=…&in_channel=…
Cộng đồngGET /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
KênhGET /users/me/teams/{team_id}/channels, GET /teams/name/{team}/channels/name/{channel}, POST /channels, POST /channels/direct (hai ID người dùng), POST /channels/group, POST /channels/{channel_id}/members
Tin nhắn (bài đăng)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
Phản ứngPOST /reactions với {"user_id", "post_id", "emoji_name"}, DELETE /users/{user_id}/posts/{post_id}/reactions/{emoji_name}
TệpPOST /files (multipart: channel_id và files), sau đó đặt các ID trả về vào file_ids của bài đăng; GET /files/{file_id}
Tùy chọnGET /users/me/preferences, PUT /users/me/preferences
Tích hợp/hooks/incoming, /hooks/outgoing, /commands, /bots, /oauth/apps (xem các trang tiếp theo)
Máy chủGET /system/ping (kiểm tra sức khỏe, không cần token), GET /config/client?format=old (các cài đặt mà client nhìn thấy)

Đăng một tin nhắn

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"}'

Tin nhắn sử dụng Markdown. Thêm "root_id" (bài đăng đầu tiên của một chủ đề) để trả lời trong chủ đề, "file_ids" cho tệp và "props" cho tệp đính kèm và các phần bổ sung khác (xem Tệp đính kèm).

Tìm ID của một kênh

curl -H "Authorization: Bearer $TOKEN" \
  https://chat.example.com/api/v4/teams/name/lumen-labs/channels/name/ops-alerts

Tên là những tên trong liên kết của kênh: /lumen-labs/channels/ops-alerts.

Phân trang

Các điểm cuối danh sách nhận page (bắt đầu từ 0) và per_page (mặc định là 60, tối đa 200). Tiếp tục yêu cầu trang tiếp theo cho đến khi một trang trả về ngắn hơn per_page.

Tin nhắn của một kênh (GET /channels/{channel_id}/posts) cũng nhận since (thời gian: mọi thay đổi kể từ đó), hoặc before và after (ID bài đăng). Kết quả trả về dưới dạng danh sách bài đăng: {"order": [IDs, newest first], "posts": {ID: post}, "next_post_id", "prev_post_id"}.

Lỗi

Lỗi sử dụng các mã trạng thái HTTP thông thường (400 đầu vào không hợp lệ, 401 chưa đăng nhập, 403 không được phép, 404 không tìm thấy, 501 tính năng đã bị tắt) kèm theo thân JSON:

{
  "id": "api.context.permissions.app_error",
  "message": "You do not have the appropriate permissions.",
  "detailed_error": "",
  "request_id": "jz8zm5nunpbt8f3gpqsz5dq6so",
  "status_code": 403
}

Sử dụng id trong mã của bạn: message được dịch sang ngôn ngữ của người dùng. detailed_error sẽ trống trừ khi máy chủ chạy ở chế độ phát triển (ServiceSettings.EnableDeveloper). Cung cấp request_id cho quản trị viên của máy chủ: nó có trong nhật ký.

Giới hạn tần suất

Giới hạn tỷ lệ mặc định là tắt. Khi quản trị viên hệ thống bật tính năng này (Bảng điều khiển Hệ thống › Môi trường › Giới hạn Tỷ lệ), mỗi client mặc định được phép 10 yêu cầu mỗi giây với độ bùng phát lên đến 100, được tính theo địa chỉ IP hoặc theo người dùng. Phản hồi bao gồm X-RateLimit-Limit, X-RateLimit-Remaining và X-RateLimit-Reset; khi vượt quá giới hạn, máy chủ trả về mã 429 kèm tiêu đề Retry-After tính bằng giây. Một số endpoint, chẳng hạn như đăng nhập, có giới hạn riêng bất kể cài đặt chung.

Viết các script chờ và thử lại khi gặp 429, và tránh việc truy vấn lặp lại: hãy theo dõi WebSocket thay vào đó.

Dòng sự kiện WebSocket

Kết nối đến wss://chat.example.com/api/v4/websocket. Xác thực bằng tiêu đề Authorization: Bearer trong yêu cầu kết nối, hoặc bằng cách gửi điều này như tin nhắn đầu tiên:

{"seq": 1, "action": "authentication_challenge", "data": {"token": "…"}}

Máy chủ gửi sự kiện hello, sau đó gửi sự kiện cho mọi thứ mà bạn được phép xem:

{
  "event": "posted",
  "data": {"channel_id": "…", "channel_type": "O", "post": "{\"id\":\"…\",\"message\":\"Hello\",…}"},
  "broadcast": {"channel_id": "…", "team_id": "", "user_id": "", "omit_users": null},
  "seq": 4
}

Lưu ý rằng data.post là tin nhắn dưới dạng chuỗi JSON. Các sự kiện phổ biến: posted, post_edited, post_deleted, reaction_added, reaction_removed, typing, status_change, user_added, direct_added. Các ứng dụng gửi sự kiện riêng của chúng, được đặt tên là custom_<app id>_<event>.

Bạn cũng có thể gửi các hành động, mỗi hành động có một seq tăng dần: user_typing với {"channel_id", "parent_id"}, hoặc get_statuses. Kết nối lại khi kết nối bị ngắt, và lấy lại những gì bạn đã bỏ lỡ bằng since (xem Phân trang).

Antimatter bổ sung các sự kiện sau: community_attributes_updated, member_timeouts_updated, post_put_on_top, post_removed_from_top, server_categories_updated, channel_overrides_updated và category_overrides_updated.

Thư viện client

  • Go: model.Client4 trong server/public/model (nhập github.com/mattermost/mattermost/server/public/model). Dùng model.NewAPIv4Client(url), sau đó client.SetToken(token); model.NewWebSocketClient4(wsURL, token) dùng để theo dõi các sự kiện. Bản sao của Antimatter bổ sung các phương thức cho các endpoint riêng của nó, chẳng hạn như UpdateMessageRequest, PutPostOnTop và ExportChannel.
  • TypeScript: lớp Client4 của @mattermost/client, trong webapp/platform/client, với các kiểu dữ liệu trong webapp/platform/types. Bản sao trong kho lưu trữ của Antimatter bao gồm các endpoint của Antimatter; gói được phát hành trên npm bởi Mattermost thì không.
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)
}

Những gì Antimatter bổ sung vào API

Các endpoint và trường dữ liệu này không tồn tại trên máy chủ Mattermost. Tất cả đều yêu cầu phiên làm việc.

EndpointChức năng
GET /teams/{team_id}/user_attributes/fields
POST cùng đường dẫn
PATCH, DELETE …/fields/{field_id}
Thuộc tính cộng đồng: các trường hồ sơ do quản trị viên của cộng đồng định nghĩa cho thành viên của cộng đồng đó (tối đa 20). Thành viên có thể đọc chúng; quản trị viên cộng đồng tạo và thay đổi chúng.
GET /teams/{team_id}/members/{user_id}/user_attributes
PATCH cùng đường dẫn
POST /teams/{team_id}/user_attributes/values/search
Giá trị thuộc tính của một thành viên, dưới dạng {field_id: value}. Thành viên tự đặt giá trị của mình (trừ các trường do quản trị viên quản lý); quản trị viên có thể đặt giá trị cho bất kỳ ai. Tìm kiếm nhận {"user_ids": [...]} (tối đa 200).
GET /teams/{team_id}/timeouts
PUT /teams/{team_id}/members/{user_id}/timeout
GET /teams/{team_id}/members/{user_id}/moderation
Hết thời gian: {"until": time, "reason": "…"} ngăn một người đăng bài, phản ứng và tải lên tệp trong cộng đồng cho đến thời điểm đó (tối đa 28 ngày); "until": 0 để gỡ bỏ. Giao diện điều chế hiển thị thời điểm họ tham gia và số lượng bài đăng gần đây.
GET /channels/{channel_id}/on_top
PUT, DELETE /posts/{post_id}/on_top
Các tin nhắn được ghim ở đầu kênh (tối đa 10). {"duration": ms}, tối đa 30 ngày; giá trị 0 giữ tin nhắn cho đến khi bị gỡ. Bất kỳ ai có quyền đọc kênh đều có thể xem danh sách này. Việc ghim hoặc gỡ ghim một tin nhắn đòi hỏi quyền đăng bài trong kênh và, trong kênh của một cộng đồng, phải là quản trị viên của kênh hoặc của cộng đồng, hoặc có quyền Quản lý tin nhắn (delete_others_posts) tại đó. Trong tin nhắn trực tiếp hoặc nhóm, các thành viên có thể thực hiện. Không được phép trong các kênh đã lưu trữ.
POST /channels/{channel_id}/message_requestThao tác trên yêu cầu tin nhắn của chính bạn: {"action": "accept"}, "dismiss", hoặc "request" để đưa cuộc trò chuyện trở lại danh sách các yêu cầu. Trả về thành viên kênh của bạn.
GET, PUT /channels/{channel_id}/overrides
GET /channels/{channel_id}/overrides/effective
GET, PUT /channels/{channel_id}/role_access
Những gì một vai trò hoặc một người có thể thực hiện trong một kênh, và những vai trò nào có thể xem một kênh bị chặn theo vai trò.
GET, PUT /teams/{team_id}/server_categories
GET, PUT …/server_categories/overrides
Các danh mục kênh dùng chung của cộng đồng, và các ghi đè áp dụng cho mọi kênh trong một danh mục.
GET /groups/{group_id}/team_role
PUT …/team_role/permissions
Các quyền mà một vai trò cộng đồng cấp.
POST /teams/{team_id}/autolinks/previewKiểm tra các quy tắc liên kết tự động của cộng đồng trên một đoạn văn bản.
POST /channels/{channel_id}/export?format=csv&since=&until=Tải xuống các tin nhắn của một kênh dưới dạng CSV (tối đa 50.000), dành cho những người có thể đọc kênh đó.
GET /posts/{post_id}/speechTin nhắn được đọc thành tiếng, dưới dạng âm thanh, khi chức năng chuyển văn bản thành giọng nói được cấu hình.
POST /posts/{post_id}/move_to_channelDi chuyển một chủ đề sang kênh khác trong cùng một cộng đồng: xem Di chuyển một chủ đề.
GET, POST /ai/connections
GET, PATCH, DELETE /ai/connections/{connection_id}
GET /ai/connections/usable
Các kết nối mô hình, nhà cung cấp AI mà các tính năng và ứng dụng AI của máy chủ sử dụng: xem Kết nối mô hình.
GET /channels/{channel_id}/message_actions
POST /posts/{post_id}/message_actions/{hook_id}
GET, POST /hooks/outgoing/{hook_id}/icon
Hành động tin nhắn: các webhook gửi đi mà người dùng thực hiện từ menu tin nhắn. Xem Hành động tin nhắn.

Các trường mới

  • Cộng đồng (Team, và PUT /teams/{team_id}/patch): all_channels_membership (mọi người đều thuộc mọi kênh mà họ có thể xem), default_channel_id (nơi người mới đến; nếu trống nghĩa là General), kind (community hoặc workplace: trong một nơi làm việc, quản trị viên kênh cũng có thể lưu trữ kênh của họ; các cộng đồng mới nhận TeamSettings.DefaultCommunityKind của máy chủ, mặc định là community), member_list_view (cách danh sách thành viên nhóm các thành viên: choice, mặc định, cho phép mỗi thành viên tự chọn; roles hoặc teams cố định cách nhóm), hide_role_colors, require_team_badges, onboarding và autolinks (cả hai đều là chuỗi JSON).
  • Kênh mặc định của một cộng đồng mới là general (General), không phải town-square. Bản nâng cấp 0.9.0 đổi tên town-square của mỗi cộng đồng thành general, giữ nguyên ID, trừ khi cộng đồng đã có kênh general. Các tên cũ vẫn hoạt động: GET /teams/{team_id}/channels/name/town-square, GET /teams/name/{team}/channels/name/town-square và trường channel của webhook đến sẽ trả về kênh mặc định của cộng đồng nếu không có kênh nào có tên đó. Hãy sử dụng default_channel_id, hoặc tên general, trong mã mới.
  • Liên kết kênh: #channel-name liên kết đến một kênh, giống như ~channel-name. Thuộc tính channel_mentions của bài đăng liệt kê các kênh được liên kết bằng cách này hoặc cách kia; một #word không khớp với tên kênh nào sẽ vẫn là hashtag. Giao diện web và ứng dụng di động của Antimatter ghi #name.
  • Kênh lưu trữ vẫn có thể nhận thành viên mới (POST /channels/{channel_id}/members), và họ có thể đọc lịch sử. Không ai có thể đăng bài, phản ứng, ghim, đưa tin nhắn lên đầu, đổi tên kênh hoặc thay đổi vai trò của thành viên trong đó.
  • Trả lời nội tuyến: một bài đăng có "props": {"reply_to": "<post id>"} sẽ trích dẫn tin nhắn đó từ cùng kênh. Thêm "reply_to_mention": false để không gửi thông báo cho tác giả. Máy chủ sẽ điền metadata.reply_to với một mô tả ngắn về tin nhắn được trích dẫn.
  • Ẩn nội dung nhạy cảm: "props": {"spoiler": true} sẽ ẩn văn bản và tệp của một bài đăng cho đến khi người đọc chọn xem chúng.
  • Bỏ qua và chặn là các tùy chọn: danh mục user_block, đặt tên theo ID của người kia, với giá trị ignore hoặc block. Việc một tin nhắn trực tiếp có chờ như một yêu cầu hay không nằm trong notify_props.dm_request của thành viên kênh của bạn (pending, accepted hoặc dismissed).
  • Tệp đính kèm của tin nhắn có thể chứa stages và một chart: xem Thẻ.

Di chuyển chủ đề

POST /posts/{post_id}/move_to_channel di chuyển một chủ đề, tin nhắn đầu tiên và tất cả các tin nhắn trả lời của nó, sang một kênh khác trong cùng cộng đồng. post_id có thể là tin nhắn đầu tiên hoặc bất kỳ tin nhắn trả lời nào.

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 (bắt buộc): kênh mà chủ đề sẽ được di chuyển đến.
  • flatten (mặc định false): true biến các tin nhắn trả lời thành tin nhắn của kênh đích thay vì một chủ đề. Tính năng Make it a channel của Fusion sử dụng tham số này.

Các tin nhắn giữ nguyên tác giả, thời gian, phản ứng và tệp. Bản sao của chúng mang thuộc tính silent_notification, do đó không gửi thông báo cho ai. Tin nhắn gốc sẽ bị xóa. Phản hồi là tin nhắn đầu tiên đã được di chuyển, kèm ID mới.

Ai có thể di chuyển một chủ đề

  • Bạn phải có quyền đọc chủ đề và đăng bài trong kênh đích.
  • Quản trị viên của kênh, quản trị viên của cộng đồng, người có quyền Quản lý tin nhắn (delete_others_posts) trong kênh, và quản trị viên hệ thống có thể di chuyển bất kỳ chủ đề nào.
  • Tác giả của chủ đề có thể di chuyển nó khi cả hai kênh đều là kênh công khai, hoặc khi tất cả tin nhắn trong chủ đề đều do họ viết. Trong trường hợp khác, phản hồi là 403 với ID api.post.move_thread.private_needs_moderator.app_error.
  • Cả hai kênh phải thuộc cùng một cộng đồng (không phải tin nhắn trực tiếp hoặc tin nhắn nhóm), khác nhau và không được lưu trữ. Tin nhắn hệ thống và tin nhắn tự hủy sau khi đọc không thể di chuyển.
  • Một chủ đề dài hơn WranglerSettings.MoveThreadMaxCount tin nhắn (mặc định là 100; 0 để không giới hạn) sẽ bị từ chối.

Con trỏ và ghi chú

Việc di chuyển tạo ra hai tin nhắn hệ thống kiểu system_wrangler: một con trỏ trong kênh cũ ("Một chủ đề gồm 13 tin nhắn đã được di chuyển đến #target") và một ghi chú trong kênh đích ("Chủ đề này được di chuyển từ #source"), nằm dưới chủ đề đã di chuyển hoặc, nếu dùng flatten, sau các tin nhắn của nó. Ngoài nội dung tin nhắn, thuộc tính của chúng cho phép client hiển thị tên kênh dưới dạng liên kết:

  • Con trỏ: MovedThreadPermalink, NumMessages, MovedThreadChannelId, MovedThreadTeamName, MovedThreadPostId, và, đối với đích công khai, MovedThreadChannelName và MovedThreadChannelDisplayName.
  • Ghi chú: MovedFromChannelId, MovedFromTeamName, MovedFromPostId (con trỏ), MovedFromPermalink, và, đối với nguồn công khai, MovedFromChannelName và MovedFromChannelDisplayName.

Cả hai đều có TranslationID. Tên của kênh riêng tư bị lược bỏ: người đọc sẽ thấy "một kênh khác". Giao thức POST /posts/{post_id}/move của Mattermost bị tắt trong Antimatter; hãy sử dụng điểm cuối này.

Kết nối mô hình

Một kết nối mô hình là địa chỉ và khóa của nhà cung cấp AI, do quản trị viên thiết lập. Các tính năng AI của máy chủ và các ứng dụng gọi dịch vụ AI sẽ sử dụng chúng. Quản trị viên hệ thống quản lý các kết nối trên toàn máy chủ (manage_ai_connections); quản trị viên của một cộng đồng quản lý các kết nối của cộng đồng đó (manage_team_ai_connections). Khóa chỉ ghi: không có phản hồi nào chứa khóa, chỉ có api_key_set và api_key_last4.

EndpointChức năng
GET /ai/connections?scope=Các kết nối mà bạn quản lý. scope là server hoặc ID của một cộng đồng; nếu không có, sẽ là mọi phạm vi mà bạn quản lý.
POST /ai/connectionsThêm một kết nối (trả về 201).
POST /ai/connections/test, POST /ai/connections/modelsKiểm tra một kết nối, hoặc liệt kê các mô hình của nó, trước khi lưu. Cùng thân yêu cầu như khi thêm; không có gì được lưu trữ.
GET, PATCH (hoặc PUT), DELETE /ai/connections/{connection_id}Đọc, thay đổi hoặc xóa một kết nối. Một bản vá chỉ chứa các trường cần thay đổi; bỏ qua api_key để giữ nguyên khóa.
POST /ai/connections/{connection_id}/testKiểm tra một kết nối đã lưu: {"ok", "error", "status_code", "latency_ms", "model_count"}.
GET /ai/connections/{connection_id}/modelsCác mô hình mà nhà cung cấp cung cấp.
GET /ai/connections/{connection_id}/usageSố lượng yêu cầu và token trong tháng này.
GET /ai/connections/usable?channel_id=&team_id=Đối với bất kỳ ai đã đăng nhập: các kết nối mà bạn có thể sử dụng ở đó, cùng với các mô hình và khả năng của chúng, không bao giờ chứa khóa hoặc địa chỉ của chúng.

Thân yêu cầu của một kết nối mới:

{
  "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 là openai_compatible hoặc anthropic. scope mặc định là server; ID của một cộng đồng sẽ làm cho kết nối đó thuộc về cộng đồng đó. Trong limits, 0 có nghĩa là không giới hạn; số yêu cầu mỗi phút được tính trên mỗi máy chủ, ngân sách token theo tháng dương lịch (UTC) cho toàn bộ cụm. sharing xác định cộng đồng nào có thể sử dụng kết nối toàn máy chủ (tin nhắn trực tiếp và tin nhắn nhóm cần all_teams), và audience xác định ai có thể sử dụng nó; khách chỉ được phép khi có allow_guests. Các thay đổi sẽ được ghi vào nhật ký kiểm toán. Hướng dẫn quản trị viên giải thích các cài đặt: xem AI.