REST API

Antimatter অ্যাপস যা কিছু করে তা সবই একই HTTP API-র মাধ্যমে ঘটে, তাই আপনার স্ক্রিপ্টও তা করতে পারে। এই পেজে ব্যাখ্যা করা হয়েছে কীভাবে অথেনটিকেশন করতে, কোন রিসোর্সগুলো সবচেয়ে বেশি ব্যবহার করা হয়, রেসপন্স এবং এররগুলো কেমন দেখায়, এবং WebSocket-এর মাধ্যমে লাইভ ইভেন্ট ফলো করার উপায়।

মৌলিক বিষয়

  • বেস URL: https://chat.example.com/api/v4। নিচের সব এন্ডপয়েন্ট এর সাপেক্ষে।
  • ফরম্যাট: ইনপুট এবং আউটপুট উভয়ই JSON, ফাইল আপলোড (মাল্টিপার্ট) ছাড়া। পাঠান Content-Type: application/json।
  • ID: প্রতিটি অবজেক্টের একটি ২৬ অক্ষরের 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 এ। রিপোজিটরির api/v4/source ফোল্ডারে থাকা OpenAPI বিবরণ Mattermost থেকে উত্তরাধিকারসূত্রে পাওয়া এন্ডপয়েন্টসমূহ এবং Antimatter-এর কিছু সংযোজন কভার করে: থ্রেডসমূহ স্থানান্তর, মডেল সংযোগ, এজেন্টসমূহ, কমিউনিটি নিয়ম, ফোকাস মোড এবং মেসেজ অ্যাকশনসমূহ। বাকিগুলো শুধুমাত্র কোডে রয়েছে।

অথেনটিকেশন

সাইন-ইন এবং কিছু পাবলিক এন্ডপয়েন্ট ছাড়া প্রতিটি রিকোয়েস্টের জন্য Authorization হেডারে একটি টোকেন প্রয়োজন:

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

সেখানে তিন ধরনের টোকেন গ্রহণ করা হয়: পার্সোনাল অ্যাক্সেস টোকেন, সেশন টোকেন এবং OAuth অ্যাক্সেস টোকেন। Authorization: Token …ও গ্রহণ করা হয়। কুয়েরি স্ট্রিং-এ থাকা টোকেন (?access_token=) শুধুমাত্র OAuth অ্যাক্সেস টোকেনের জন্য গ্রহণ করা হয়।

পার্সোনাল অ্যাক্সেস টোকেন (স্ক্রিপ্টের জন্য সুপারিশকৃত)

একটি পার্সোনাল অ্যাক্সেস টোকেন আপনার হয়ে কাজ করে, আপনি যদি মেয়াদ শেষের তারিখ না দেন তবে এটি মেয়াদ শেষ হয় না, এবং যেকোনো সময় এটি বাতিল করা যায়। ডিফল্টভাবে পার্সোনাল অ্যাক্সেস টোকেন বন্ধ থাকে:

  1. একজন সিস্টেম অ্যাডমিন System Console › Integrations › Integration Management পেজে ব্যক্তিগত অ্যাক্সেস টোকেন সক্রিয় করুন সক্রিয় করেন (ServiceSettings.EnableUserAccessTokens, AM_SERVICESETTINGS_ENABLEUSERACCESSTOKENS)।
  2. যে ব্যক্তিগণ টোকেন তৈরি করতে পারেন, তাদের জন্য একজন সিস্টেম অ্যাডমিন System Console › User Management › Users খোলেন, সেই ব্যক্তির মেনু থেকে রোল পরিচালনা বেছে নেন এবং Allow this account to generate personal access tokens টিক করেন। সিস্টেম অ্যাডমিনসমূহ সবসময় টোকেন তৈরি করতে পারেন।
  3. ব্যক্তিটি ডানদিকে উপরে থাকা তার অ্যাভাটার খোলেন, তারপর Profile & settings › Security। পার্সোনাল অ্যাক্সেস টোকেনসমূহ অংশে, তারা টোকেনটির উদ্দেশ্য বর্ণনা করেন এবং টোকেন তৈরি করুন বেছে নেন। টোকেনটি একবার দেখানো হয়: সেটি কপি করুন।

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>।

একজন সিস্টেম অ্যাডমিন একই System Console পেজে সর্বোচ্চ পার্সোনাল অ্যাক্সেস টোকেন মেয়াদ (দিন) দিয়ে টোকেনের মেয়াদ সীমাবদ্ধ করতে পারেন।

সেশন টোকেন

পাসওয়ার্ড দিয়ে সাইন ইন করলে 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" যোগ করুন। সার্ভারের সেশন সেটিংস অনুযায়ী সেশন মেয়াদ শেষ হয়, এবং লগইন এন্ডপয়েন্টে রেট লিমিট প্রযোজ্য (প্রতি সেকেন্ডে ৫টি রিকোয়েস্ট)। POST /users/logout সেশন শেষ করে।

ব্রাউজাররা কুকি ব্যবহার করে অথেনটিকেশন করে। GET ছাড়া অন্য যেকোনো কাজের জন্য কুকি দিয়ে অথেনটিকেটেড রিকোয়েস্টে X-CSRF-Token হেডার পাঠাতে হবে; Authorization হেডারে থাকা টোকেনের জন্য CSRF হেডারের প্রয়োজন নেই।

OAuth 2.0 অ্যাপস

আপনার অ্যাপ্লিকেশনে Antimatter অ্যাকাউন্ট দিয়ে সাইন ইন করার অনুমতি দিতে, একটি OAuth 2.0 অ্যাপ নিবন্ধন করুন। Antimatter তখন OAuth প্রোভাইডার হিসেবে কাজ করবে:

  1. OAuth 2.0 সার্ভিস প্রোভাইডার সক্রিয় করুন সক্রিয় থাকতে হবে (System Console › Integrations › Integration Management, ServiceSettings.EnableOAuthServiceProvider, ডিফল্টরূপে সক্রিয়)।
  2. যার OAuth অ্যাপসমূহ পরিচালনার অনুমতি রয়েছে (ডিফল্ট অনুযায়ী সিস্টেম অ্যাডমিনসমূহ) ইন্টিগ্রেশনসমূহ › OAuth 2.0 অ্যাপ (কমিউনিটি মেনু › টিম সেটিংস › ইন্টিগ্রেশনসমূহ) খুলে, এবং কলব্যাক URL-এর সাথে অ্যাপটি যোগ করে। তারা একটি ক্লায়েন্ট ID এবং একটি ক্লায়েন্ট সিক্রেট পায়।
  3. আপনার অ্যাপ্লিকেশন ব্যবহারকারীদের https://chat.example.com/oauth/authorize ঠিকানায় পাঠায়, যেখানে response_type=code, client_id, redirect_uri এবং state থাকে। code_challenge_method=S256 সহ PKCE সমর্থিত।
  4. এটি POST https://chat.example.com/oauth/access_token ঠিকানায় কোড বিনিময় করে (grant_type=authorization_code, তারপর refresh_token দিয়ে নতুন করে), এবং Authorization: Bearer <access token> ব্যবহার করে API-তে কল করে।

ব্যক্তিগণ Profile & settings › Security › Apps you authorized অংশে তাদের অনুমোদিত অ্যাপসমূহ দেখতে পান।

প্রধান রিসোর্স

কীএন্ডপয়েন্ট
আপনি এবং অন্যরাGET /users/me, GET /users/{user_id}, GET /users/username/{username}, POST /users/ids (একটি আইডি তালিকা), 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 (দুটি ইউজার আইডি), 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 (মাল্টিপার্ট: channel_id এবং files), তারপর ফিরে আসা আইডিগুলো পোস্টের 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" এবং আটachment ও অন্যান্য বাড়তি তথ্যের জন্য "props" (দেখুন আটachment)।

একটি চ্যানেলের আইডি খুঁজুন

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-এর চেয়ে ছোট ফিরে আসে, ততক্ষণ পরের পেজের জন্য জিজ্ঞাসা করতে থাকুন।

একটি চ্যানেলের মESSAGES (GET /channels/{channel_id}/posts)-এর জন্য since (একটি সময়: সেই সময়ের পরে যা কিছু পরিবর্তিত হয়েছে) অথবা before এবং after (একটি পোস্ট আইডি) ব্যবহার করা যায়। এগুলো একটি পোস্ট তালিকা হিসেবে ফিরে আসে: {"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 উদ্ধৃত করুন: এটি লগে থাকে।

রেট লিমিট

ডিফল্টরূপে রেট লিমিটিং বন্ধ থাকে। যখন একজন সিস্টেম অ্যাডমিন এটি সক্রিয় করেন (System Console › Environment › Rate Limiting), তখন ডিফল্টরূপে প্রতিটি ক্লায়েন্ট প্রতি সেকেন্ডে ১০টি রিকোয়েস্ট পাঠাতে পারে, ১০০টির বার্স্টসহ, যা 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 ব্যবহার করে যা মিস করেছেন তা আনুন (দেখুন Pagination)।

Antimatter এই ইভেন্টসমূহ যোগ করে: agent_activity_changed এবং agent_post_stream (দেখুন Agents), ai_tools_changed (দেখুন Agents), community_rules_updated এবং community_rules_accepted (দেখুন Community rules), focus_ended (দেখুন Focus mode), 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) পাঠানো হয়।

ক্লায়েন্ট লাইব্রেরি

  • যান: server/public/model এ model.Client4 (github.com/mattermost/mattermost/server/public/model ইমপোর্ট করুন)। model.NewAPIv4Client(url), তারপর client.SetToken(token); model.NewWebSocketClient4(wsURL, token) ইভেন্টসমূহ অনুসরণ করে। Antimatter-এর কপি তার নিজস্ব এন্ডপয়েন্টসমূহের জন্য পদ্ধতি যোগ করে, যেমন UpdateMessageRequest, PutPostOnTop এবং ExportChannel।
  • TypeScript: webapp/platform/client-এ @mattermost/client-এর Client4 ক্লাস, এবং webapp/platform/types-এ এর টাইপস। Antimatter-এর রিপোজিটরিতে থাকা কপিতে Antimatter-এর এন্ডপয়েন্ট রয়েছে; Mattermost-এর দ্বারা npm-এ প্রকাশিত প্যাকেজে তা নেই।
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/fields
POST একই পথ
PATCH, DELETE …/fields/{field_id}
কমিউনিটি অ্যাট্রিবিউট: কমিউনিটির অ্যাডমিনদের দ্বারা সদস্যদের জন্য সংজ্ঞায়িত প্রোফাইল ফিল্ড (সর্বোচ্চ ২০টি)। সদস্যরা এগুলো পড়তে পারে; কমিউনিটির অ্যাডমিনরা এগুলো তৈরি এবং পরিবর্তন করতে পারে।
GET /teams/{team_id}/members/{user_id}/user_attributes
PATCH একই পথ
POST /teams/{team_id}/user_attributes/values/search
একজন সদস্যের অ্যাট্রিবিউট মান, {field_id: value} হিসেবে। সদস্যরা নিজেরা সেট করতে পারে (অ্যাডমিন-ব্যবস্থিতগুলোর ব্যতীত); অ্যাডমিনরা যেকোনো সদস্যের সেট করতে পারে। সার্চটি {"user_ids": [...]} গ্রহণ করে (সর্বোচ্চ ২০০টি)।
GET /teams/{team_id}/timeouts
PUT /teams/{team_id}/members/{user_id}/timeout
GET /teams/{team_id}/members/{user_id}/moderation
টাইমআউট: {"until": time, "reason": "…"} নির্দিষ্ট সময় পর্যন্ত (সর্বোচ্চ ২৮ দিন) কেউ কমিউনিটিতে পোস্ট, প্রতিক্রিয়া এবং আপলোড করতে বাধা দেয়; "until": 0 এটি তুলে দেয়। মডারেশন ভিউতে তারা কখন যোগ হয়েছিল এবং সাম্প্রতিক কালে কতটা পোস্ট করেছিল তা দেখায়।
GET /channels/{channel_id}/on_top
PUT, DELETE /posts/{post_id}/on_top
চ্যানেলের উপরে রাখা ম্যাসেজ (সর্বোচ্চ ১০টি)। {"duration": ms}, সর্বোচ্চ ৩০ দিন; 0 রাখলে এটি মুছে ফেলা পর্যন্ত থাকবে। যে কেউ চ্যানেলটি পড়তে পারে, তারাই এগুলো তালিকাভুক্ত করতে পারে। একটি ম্যাসেজকে উপরে রাখতে বা সরিয়ে ফেলতে চ্যানেলে পোস্ট করার অনুমতি প্রয়োজন এবং, একটি কমিউনিটির চ্যানেলে, চ্যানেলের অথবা কমিউনিটির অ্যাডমিন হতে হবে, অথবা সেখানে ম্যাসেজ পরিচালনা (delete_others_posts) থাকতে হবে। ডাইরেক্ট বা গ্রুপ ম্যাসেজে, এর সদস্যরা এটি করতে পারে। আরকাইভ করা চ্যানেলে এটি প্রত্যাখ্যাত হয়।
GET, PUT /teams/{team_id}/rules
POST /teams/{team_id}/rules/accept
GET /teams/{team_id}/rules/stats
কমিউনিটি নিয়ম: দেখুন কমিউনিটি নিয়ম।
GET, POST, DELETE /users/me/focus
GET /users/me/focus/summary?since=&until=
POST /users/me/focus/summary/read
ফোকাস মোড: দেখুন ফোকাস মোড।
POST /channels/{channel_id}/message_requestআপনার নিজের মESSAGES অনুরোধের উপর কাজ করে: {"action": "accept"}, "dismiss", বা "request" একটি কথোপকথনকে আবার অনুরোধগুলোর মধ্যে ফিরিয়ে আনতে। এটি আপনার চ্যানেল সদস্যকে ফিরিয়ে দেয়।
GET, PUT /channels/{channel_id}/overrides
GET /channels/{channel_id}/overrides/effective
GET, PUT /channels/{channel_id}/role_access
একটি চ্যানেলে কোনো রোল বা ব্যক্তি কী করতে পারে, এবং কোন কোন রোল রোল-গেটেড চ্যানেল দেখতে পায়।
GET, PUT /teams/{team_id}/server_categories
GET, PUT …/server_categories/overrides
কমিউনিটির শেয়ার্ড চ্যানেল ক্যাটাগরি, এবং একটি ক্যাটাগরির প্রতিটি চ্যানেলে প্রযোজ্য ওভাররাইড।
GET /groups/{group_id}/team_role
PUT …/team_role/permissions
কমিউনিটির রোল যে অনুমতি প্রদান করে।
POST /teams/{team_id}/autolinks/previewকমিউনিটির অটোলিংক নিয়মগুলো একটি টেক্সটে পরীক্ষা করে।
POST /channels/{channel_id}/export?format=csv&since=&until=যে ব্যক্তিরা চ্যানেলটি পড়তে পারে, তাদের জন্য চ্যানেলের ম্যাসেজগুলো CSV হিসেবে ডাউনলোড করে (সর্বোচ্চ ৫০,০০০)।
GET /posts/{post_id}/speechযখন টেক্সট-টু-স্পিচ সেটআপ করা থাকে, তখন ম্যাসেজটি অডিও হিসেবে পড়া হয়।
POST /posts/{post_id}/move_to_channelএকই কমিউনিটির অন্য চ্যানেলে একটি থ্রেড সরানো: দেখুন একটি থ্রেড সরানো।
GET, POST /ai/connections
GET, PATCH, DELETE /ai/connections/{connection_id}
GET /ai/connections/usable
মডেল কানেকশন, সার্ভারের AI ফিচার এবং অ্যাপস যে AI প্রোভাইডার ব্যবহার করে: দেখুন মডেল কানেকশন।
GET, POST /ai/agents
GET, PATCH, DELETE /ai/agents/{agent_id}
POST /ai/agents/{agent_id}/tasks
GET /ai/agents/conversations
AI এজেন্টসমূহ, তাদের কার্যকলাপ, এবং AI চ্যাটের টাস্কসমূহ ও কথোপকথন: দেখুন এজেন্টসমূহ।
GET /ai/agents/{agent_id}/tools
GET /ai/agents/tools/catalogue
POST /ai/tools/calls/{call_id}/confirm, /decline
GET, POST /ai/mcp_servers
GET, PATCH, DELETE /ai/mcp_servers/{server_id}
POST, DELETE /ai/mcp_servers/{server_id}/oauth
একটি এজেন্টের টুলস, যে টুলসগুলো এটি ব্যবহার করতে পারে তার ক্যাটালগ, অপেক্ষমাণ টুল কল নিশ্চিত বা বাতিল করা, এবং এজেন্টদের জন্য উপলব্ধ MCP সার্ভারসমূহ: দেখুন AI।
GET /channels/{channel_id}/message_actions
POST /posts/{post_id}/message_actions/{hook_id}
GET, POST /hooks/outgoing/{hook_id}/icon
ম্যাসেজ অ্যাকশন: আউটগোয়িং ওয়েবহুক যেগুলো মানুষ ম্যাসেজ মেনু থেকে চালায়। দেখুন ম্যাসেজ অ্যাকশন।
POST /users/me/sessions/acknowledgeআপনার নিজের একটি সেশনের নতুন সাইন-ইন সতর্কবার্তা বন্ধ করে দেয়: {"session_id"}। শুধুমাত্র সাইন-ইন করা ব্যবহারকারীই তাদের নিজস্ব সেশনের জন্য এটি কল করতে পারেন।
PUT /channels/{channel_id}/typeএকটি চ্যানেলের প্রিসেট বা সেটিংস পরিবর্তন করে: দেখুন Channel types।
GET /channels/{channel_id}/topics
PATCH /posts/{post_id}/topic
একটি ফোরামের টপিকসমূহ, এবং একটি উত্তর গ্রহণ করা বা টপিকের স্ট্যাটাস নির্ধারণ করা: দেখুন Channel types।

নতুন ফিল্ড

  • কমিউনিটিসমূহ (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 কোনো চ্যানেলের নাম না থাকলে কমিউনিটির ডিফল্ট চ্যানেলটি দেয়। নতুন কোডে 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 (মিল থাকা প্রিসেটের ID, অথবা কাস্টম সেটিংসের জন্য খালি), এবং ফোরামের জন্য am_forum_view (topics বা imageboard) বহন করে। am_type ছাড়া একটি পেলোড মানে এটি পূরণ করা হয়নি, কখনোই নয় যে চ্যানেলটি টেক্সট। ডাইরেক্ট এবং গ্রুপ মেসেজে এগুলোর কোনোটিই থাকে না। দেখুন চ্যানেল টাইপসমূহ।

চ্যানেল টাইপসমূহ

একটি কমিউনিটি চ্যানেল text, voice বা forum হয় (এর টাইপ, তৈরির সময় স্থির করা হয়), এর টাইপের মোডগুলোর একটিতে, উপরে সেটিংসসহ। একটি প্রিসেট হলো একটি মোড এবং সেটিংসের নামযুক্ত বান্ডল যা একটি ক্লায়েন্ট একটি বিকল্প হিসেবে অফার করে; প্রিসেটসমূহ সংরক্ষিত হয় না, তাই একটি চ্যানেলের প্রিসেট (am_preset) এর সেটিংস থেকে ব্যুৎপন্ন হয়, এবং "" পড়ে যখন সেগুলো কোনো প্রিসেটের সাথে মেলে না ("Custom")।

প্রিসেট IDটাইপমোডroot_postsview
text_chattextchatmembers–
text_announcementtextchatmoderators–
voice_talkvoicetalkmembers–
voice_stagevoicestagemembers–
forum_agoraforumdiscussionmemberstopics
forum_qaforumqamemberstopics
forum_ideasforumideasmemberstopics
forum_announcementforumdiscussionmoderatorstopics
forum_imageboardforumdiscussionmembersimageboard

একটি চ্যানেলের টাইপ তৈরি এবং পরিবর্তন করা

POST /channels প্রথমে props.am_preset পড়ে (প্রসারিত করে), তারপর তার উপর আলাদা props.am_type, am_mode, am_root_posts এবং am_forum_view প্রয়োগ করে; অন্য যেকোনো am_ প্রপ উপেক্ষা করা হয়। Voice Channels অ্যাপ সক্রিয় না থাকলে ভয়েস চ্যানেল তৈরি করা যাবে না (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। এই ফিল্ডগুলো ছাড়া চ্যানেল লাইন একটি সাধারণ টেক্সট Chat চ্যানেল হিসেবে ইমপোর্ট হয়, চ্যানেল টাইপ চালু হওয়ার আগের মতো।

কে আলোচনা শুরু করবে বা বিষয় খুলবে

রুট মেসেজ পোস্ট করতে (উত্তর থেকে আলাদা) create_root_post অনুমতি প্রয়োজন, যা ওভাররাইড এডিটরে Start conversations (টেক্সট, ভয়েস) বা Open topics (ফোরাম) হিসেবে দেখানো হয়। কোনো রোলে এটি থাকে না: ওভাররাইডের আগে, যারা পোস্ট করতে পারেন তারা এটি পান যেখানে 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, বটসমূহ, ইনকামিং এবং আউটগোয়িং ওয়েবহুক (হুকের স্রষ্টার ক্ষেত্রে) এবং স্লাশ কমান্ড রেসপন্সের জন্য পরীক্ষা করা হয়; অ্যাপসমূহ থেকে আসা পোস্টসমূহ (প্লাগিন API) এবং স্থানান্তরিত থ্রেডসমূহের কপিগুলোর জন্য নয় (থ্রেড স্থানান্তরকারী ব্যক্তিকে সেখানে পরীক্ষা করা হয়)। বাল্ক ইমপোর্টও এটি এড়িয়ে যায়।

ফোরামসমূহ শুধুমাত্র টপিক নেয়

একটি ফোরামে, একটি রুট পোস্টের জন্য props.am_thread_title প্রয়োজন (এর টপিকের শিরোনাম), ট্রিম করা, ১ থেকে ১০০ অক্ষরের, সব উৎস থেকে, অ্যাপসমূহ এবং স্থানান্তরিত থ্রেডসমূহ অন্তর্ভুক্ত: অনুপস্থিত হলে 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 দ্বারা লেখা হয়; ক্লায়েন্ট বা অ্যাপ দ্বারা তৈরি, আপডেট বা প্যাচের সময় এই তিনটির যেকোনোটি পাঠানো হলে তা উপেক্ষা করা হয় এবং সংরক্ষিত মানটি বজায় থাকে।

একটি ফোরামের টপিকসমূহ তালিকাভুক্ত করুন

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: শিরোনাম বা প্রথম পোস্টের টেক্সটের সাথে মিলে যায়, সর্বোচ্চ ২০০ অক্ষর।
  • before: পূর্ববর্তী পৃষ্ঠার next_cursor। per_page: ডিফল্ট ২৫, সর্বোচ্চ ১০০। replies: প্রতিটি টপিকের সর্বশেষ ০ থেকে ৫টি উত্তর, ইমেজ-বোর্ড ভিউয়ের জন্য।

উত্তর: {"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 (একটি উত্তরের 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 প্রপ বহন করে, তাই তারা কারও নোটিফিকেশন পাঠায় না। মূল মেসেজগুলো মুছে ফেলা হয়। উত্তরটি হলো সরানো প্রথম মেসেজ, যার নতুন আইডি থাকে।

কে একটি থ্রেড সরাতে পারেন

  • আপনাকে থ্রেডটি পড়তে এবং টার্গেট চ্যানেলের মধ্যে পোস্ট করতে সক্ষম হতে হবে।
  • চ্যানেলের অ্যাডমিন, কমিউনিটির অ্যাডমিন, চ্যানেলের মেসেজ পরিচালনা (delete_others_posts) অধিকারী ব্যক্তি এবং সিস্টেম অ্যাডমিন যেকোনো থ্রেড সরাতে পারেন।
  • থ্রেডের লেখক যদি উভয় চ্যানেলই পাবলিক হয়, অথবা থ্রেডের প্রতিটি মেসেজ তার নিজের হয়, তবে সেটি সরাতে পারেন। অন্যথায় উত্তর হবে 403, আইডি api.post.move_thread.private_needs_moderator.app_error সহ।
  • উভয় চ্যানেল একই কমিউনিটির (ডাইরেক্ট বা গ্রুপ মেসেজ নয়) অন্তর্গত হতে হবে, ভিন্ন হতে হবে এবং আর্কাইভ করা নয়। সিস্টেম মেসেজ এবং বার্ন-অন-রিড মেসেজ সরানো যাবে না।
  • WranglerSettings.MoveThreadMaxCount সংখ্যক (ডিফল্ট ১০০; কোনো সীমা না রাখতে ০) মেসেজের চেয়ে দীর্ঘ থ্রেড সরানো অনুমোদিত নয়।

পয়েন্টার এবং নোট

সরানোর ফলে system_wrangler ধরনের দুটি সিস্টেম মেসেজ তৈরি হয়: পুরনো চ্যানেলে একটি পয়েন্টার ("#target-এ ১৩টি মেসেজের একটি থ্রেড সরানো হয়েছে") এবং টার্গেটে একটি নোট ("#source-এর থেকে এই থ্রেডটি সরানো হয়েছে"), সরানো থ্রেডের নিচে বা flatten ব্যবহার করলে তার মেসেজগুলোর পরে। মেসেজের টেক্সটের পাশাপাশি, প্রপসগুলো ক্লায়েন্টকে চ্যানেলের নাম লিংক হিসেবে আঁকতে সাহায্য করে:

  • পয়েন্টার: MovedThreadPermalink, NumMessages, MovedThreadChannelId, MovedThreadTeamName, MovedThreadPostId এবং, পাবলিক টার্গেটের জন্য, MovedThreadChannelName ও MovedThreadChannelDisplayName।
  • নোট: MovedFromChannelId, MovedFromTeamName, MovedFromPostId (পয়েন্টার), MovedFromPermalink এবং, পাবলিক সোর্সের জন্য, MovedFromChannelName ও MovedFromChannelDisplayName।

উভয়েরই একটি TranslationID আছে। প্রাইভেট চ্যানেলের নাম বাদ রাখা হয়: পাঠকেরা "অন্য চ্যানেল" দেখেন। Antimatter-এ Mattermost-এর নিজস্ব POST /posts/{post_id}/move বন্ধ থাকে; এই এন্ডপয়েন্টটি ব্যবহার করুন।

কমিউনিটি নিয়ম

একটি কমিউনিটির অ্যাডমিনসমূহ তাদের চ্যানেলসমূহে পোস্ট করার আগে সদস্যদের নিয়মাবলীতে সম্মত হতে বাধ্য করতে পারে। নিয়মাবলী চালু থাকা অবস্থায়, যে সদস্য বর্তমান সংস্করণের সাথে সম্মত হয়নি, সে পোস্ট করতে, উত্তর দিতে, ফাইল পাঠাতে, সময়সূচী করতে, মেসেজ সম্পাদনা বা পুনরুদ্ধার করতে, বা কমিউনিটির চ্যানেলসমূহে পোস্ট করা কোনো কমান্ড চালাতে পারবে না: সার্ভার 403 এর সাথে ID api.post.community_rules_not_accepted রেসপন্স করে, এবং সেই সময়ের জন্য নির্ধারিত একটি সময়সূচীভুক্ত মেসেজ community_rules_not_accepted এরর কোড দিয়ে ব্যর্থ হয়। পড়া, প্রতিক্রিয়াসমূহ, এবং ডাইরেক্ট ও গ্রুপ মেসেজসমূহ আটকে রাখা হয় না; বটসমূহ, ইনকামিং ওয়েবহুকসমূহ, সিস্টেম মেসেজসমূহ, এবং কমিউনিটির অ্যাডমিনসমূহও (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 একটি নতুন সংস্করণ তৈরি করে যা সবাইকে আবার সম্মত হতে হবে; প্রথম সংরক্ষণটি সংস্করণ ১। এটি চালু করতে হলে টেক্সট আবশ্যক, সর্বোচ্চ ১৬,০০০ অক্ষর।
POST /teams/{team_id}/rules/acceptএকজন সদস্য হিসেবে আপনি যে version পড়েছেন তার সাথে সম্মত হন; যদি সেই সময় থেকে কোনো নতুন সংস্করণ সংরক্ষিত হয়ে থাকে তবে 409, এবং 0 বর্তমান সংস্করণের সাথে সম্মত হন।
GET /teams/{team_id}/rules/statsকমিউনিটির কতজন সদস্য বর্তমান সংস্করণের সাথে সম্মত হয়েছেন (manage_team)।

যখন একজন অ্যাডমিন নিয়মাবলী সংরক্ষণ করেন (team_id, enabled, version), তখন কমিউনিটিতে community_rules_updated ইভেন্ট পাঠানো হয়, এবং যিনি সম্মত হয়েছেন তার সকল সেশনে (team_id, version) community_rules_accepted পাঠানো হয়।

ফোকাস মোড

ফোকাস মোড হলো একটি নির্দিষ্ট সময়ের শেষের সাথে 'বিরক্ত করবেন না' স্ট্যাটাস: নোটিফিকেশনসমূহ মিউট করা হয় (পুশ, ইমেইল, ডেস্কটপ বা স্থায়ী নোটিফিকেশন, জরুরি মেসেজসহ), কারণটি 🎯 ইমোজি (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" ব্যক্তির সময় অঞ্চলে পরবর্তী দিন সকাল ০৯:০০-এ শেষ হয়। শেষ সময়টি মিনিটে রাউন্ড ডাউন করা হয়; কারণটি সর্বোচ্চ ১০০ অক্ষর। ব্যবহারকারীর স্ট্যাটাস চালু থাকা প্রয়োজন (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 ফিচার এবং AI সার্ভিস কল করা অ্যাপসগুলো এগুলোর ব্যবহার করে। সিস্টেম অ্যাডমিনসমূহ সার্ভার-ওয়াইড কানেকশন (manage_ai_connections) পরিচালনা করেন; একটি কমিউনিটির অ্যাডমিনসমূহ তাদের নিজস্ব কমিউনিটির (manage_team_ai_connections) কানেকশন পরিচালনা করেন। কীগুলো write-only: কোনো উত্তরে কোনো কী থাকে না, শুধুমাত্র api_key_set এবং api_key_last4 থাকে।

এন্ডপয়েন্টএটি কী করে
GET /ai/connections?scope=আপনি যে কানেকশনগুলো পরিচালনা করেন। scope হয় server অথবা একটি কমিউনিটির আইডি; এটি না থাকলে আপনি যে সব স্কোপ পরিচালনা করেন, সবগুলোই দেখা যাবে।
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; একটি কমিউনিটির আইডি হলে এটি সেই কমিউনিটির কানেকশন হয়ে যায়। limits-এ, 0-এর অর্থ কোনো সীমা নেই; প্রতি মিনিটে রিকোয়েস্ট প্রতিটি সার্ভারে গণনা করা হয়, আর টোকেন বাজেট পুরো ক্লাস্টারের জন্য ক্যালেন্ডার মাস (UTC) অনুযায়ী। sharing বলে কোন কমিউনিটি সার্ভার-ওয়াইড কানেকশন ব্যবহার করতে পারে (ডাইরেক্ট এবং গ্রুপ মেসেজের জন্য all_teams প্রয়োজন), এবং audience বলে কে ব্যবহার করতে পারে; অতিথিরা কেবল allow_guests থাকলে। পরিবর্তনগুলো অডিট লগে লেখা হয়। অ্যাডমিন গাইডে সেটিংসগুলোর ব্যাখ্যা দেওয়া আছে: দেখুন AI।

এজেন্টসমূহ

একটি এজেন্ট হলো agent ধরনের একটি বট অ্যাকাউন্ট (যার ব্যবহারকারীর ক্ষেত্রে is_agent থাকে), যার সেটিংসমূহ হলো: এর স্কোপ (server, অথবা কোনো কমিউনিটির আইডি), বিল্ট-ইন অথবা external, এবং বিল্ট-ইন এজেন্টের ক্ষেত্রে এর মডেল সংযোগ, মডেল, সিস্টেম প্রম্পট এবং রিজনিং। সিস্টেম অ্যাডমিনরা সার্ভার-ওয়াইড এজেন্টসমূহ পরিচালনা করেন (manage_system), কোনো কমিউনিটির অ্যাডমিনরা তাদের কমিউনিটির এজেন্টসমূহ পরিচালনা করেন (manage_team); এর উপরন্তু, তারা যে এজেন্ট তৈরি করেছেন তার জন্য manage_own_agent এবং অন্যদের এজেন্টের জন্য manage_others_agent। এই পাথগুলোতে এজেন্টের আইডি হলো তার ব্যবহারকারীর আইডি। একটি এক্সটার্নাল এজেন্ট কীভাবে চালানো হয় এবং একটি বিল্ট-ইন এজেন্টের স্ট্যাটাস কীভাবে নির্ধারণ করা হয়, তা Bots ডকুমেন্টেশনে ব্যাখ্যা করা হয়েছে; PUT /users/{user_id}/status এবং কাস্টম স্ট্যাটাস এন্ডপয়েন্টগুলো বিল্ট-ইন এজেন্টের আইডি প্রত্যাখ্যান করে, সিস্টেম অ্যাডমিনদের ক্ষেত্রেও (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}/activity
POST /ai/agents/activity/ids
একটি এজেন্ট কী করছে; এটি এর নিজস্ব টোকেন বা এর পরিচালকদের দ্বারা নির্ধারিত হয়। ব্যাচটি সর্বোচ্চ ২০০টি ব্যবহারকারী ID নেয়।
POST /ai/agents/{agent_id}/tasksএকটি বিল্ট-ইন এজেন্টকে একটি টাস্কের জন্য প্রশ্ন করে: summarize_thread, find_action_items বা find_open_questions (একটি থ্রেডের post_id বা since থেকে শুরু হওয়া একটি channel_id ব্যবহার করে), summarize_channel, ask_channel (একটি question সহ) বা summarize_transcription (একটি কলের ট্রান্সক্রিপশন পোস্ট)। আপনার ভাষায় এজেন্টের সাথে আপনার ডাইরেক্ট মেসেজে এই অনুরোধটি আপনার মেসেজ হিসেবে যুক্ত হয় এবং সেখানেই উত্তর দেওয়া হয়; উত্তরটি (201) হলো সেই মেসেজ। যে পোস্ট বা চ্যানেল আপনি পড়তে পারেন না, সেটি এমনভাবে উত্তর দেওয়া হয় যেন সেটি সেখানে নেই।
GET /ai/agents/conversations?agent_id=&before=&per_page=আপনি যেসব এজেন্ট ব্যবহার করতে পারেন তাদের সাথে আপনার কথোপকথন, সবচেয়ে সাম্প্রতিকটি আগে: আপনার ডাইরেক্ট মেসেজে তাদের সাথে আপনি যে থ্রেডসমূহ শুরু করেছেন এবং অন্য জায়গায় যে থ্রেডসমূহে তাদের মধ্যে কেউ উত্তর দিয়েছে এবং আপনি সেটি ফলো করছেন। before (একটি সময়) পরবর্তী পৃষ্ঠা দেখায়; per_page সর্বোচ্চ ১০০।

একটি নতুন এজেন্টের বডি:

{
  "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 চ্যাট অ্যাপ তাদের পড়ে।