feat(docs): add mattermost platform usage guide (#125)
@@ -560,6 +560,7 @@
|
||||
"en/usage/platforms/discord",
|
||||
"en/usage/platforms/telegram",
|
||||
"en/usage/platforms/slack",
|
||||
"en/usage/platforms/mattermost",
|
||||
"en/usage/platforms/line",
|
||||
"en/usage/platforms/webpage",
|
||||
"en/usage/platforms/http-bot",
|
||||
@@ -892,6 +893,7 @@
|
||||
"zh/usage/platforms/discord",
|
||||
"zh/usage/platforms/telegram",
|
||||
"zh/usage/platforms/slack",
|
||||
"zh/usage/platforms/mattermost",
|
||||
"zh/usage/platforms/line",
|
||||
"zh/usage/platforms/webpage",
|
||||
"zh/usage/platforms/http-bot"
|
||||
@@ -1159,6 +1161,7 @@
|
||||
"ja/usage/platforms/discord",
|
||||
"ja/usage/platforms/telegram",
|
||||
"ja/usage/platforms/slack",
|
||||
"ja/usage/platforms/mattermost",
|
||||
"ja/usage/platforms/line",
|
||||
"ja/usage/platforms/webpage",
|
||||
"ja/usage/platforms/http-bot",
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
title: "Mattermost"
|
||||
description: "Connect a Mattermost bot to LangBot and bring agents and workflows to your Mattermost server in minutes."
|
||||
icon: "/images/platforms/mattermost.svg"
|
||||
---
|
||||
|
||||
<Note>
|
||||
The screenshots below use the Chinese interface. Follow the corresponding menu items and fields described in the text.
|
||||
</Note>
|
||||
|
||||
## Create a bot account
|
||||
|
||||
Log in to your Mattermost instance (self-hosted or hosted by Mattermost). Click the `Mattermost icon` in the upper-left corner and select `Integrations` from the menu.
|
||||
|
||||

|
||||
|
||||
On the Integrations page, select `Bot Accounts` in the left menu, then click `Add Bot Account` in the upper-right corner.
|
||||
|
||||

|
||||
|
||||
Choose a username for the bot.
|
||||
|
||||

|
||||
|
||||
Set the role to `Member` (administrator-related features are not currently supported). Select `post:all` if you need direct messages, or select only `post:channels` if you only need public channels. Then click `Create Bot Account` in the lower-right corner.
|
||||
|
||||

|
||||
|
||||
Click the button to copy the token. It is shown only once, so save it securely. Then click `Done` in the lower-right corner.
|
||||
|
||||

|
||||
|
||||
## Configure the bot in LangBot
|
||||
|
||||
Open LangBot Cloud or your self-hosted LangBot instance and follow the red arrows in the screenshot below:
|
||||
|
||||
- Hover over the `Bots` tab on the left and click the `+` icon that appears.
|
||||
- Enter a name in the `Bot Name` field.
|
||||
- Open the platform adapter dropdown and select `Mattermost`.
|
||||
- Enter the address of your Mattermost instance and the token for the bot account you just created.
|
||||
- (Optional) Disable streaming output if your pipeline or AI provider does not support it.
|
||||
- Click `Submit` in the upper-right corner to open the bot editing page.
|
||||
|
||||

|
||||
|
||||
Bind an existing pipeline, configure routing if needed, and click `Save` in the upper-right corner.
|
||||
|
||||

|
||||
@@ -13,6 +13,7 @@ Bots are used to receive message events from messaging platforms and call pipeli
|
||||
| Discord | ✅ | | [Tutorial](/en/usage/platforms/discord) |
|
||||
| Telegram | ✅ | | [Tutorial](/en/usage/platforms/telegram) |
|
||||
| Slack | ✅ | | [Tutorial](/en/usage/platforms/slack) |
|
||||
| Mattermost | ✅ | Supports the open-source, Free, Professional, and Enterprise editions | [Tutorial](/en/usage/platforms/mattermost) |
|
||||
| LINE | ✅ | | [Tutorial](/en/usage/platforms/line) |
|
||||
| KOOK | ✅ | | [Tutorial](/en/usage/platforms/kook) |
|
||||
| Lark | ✅ | | [Tutorial](/en/usage/platforms/lark) |
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="Artwork" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 140 140"><defs><style>.cls-1{fill:#1e325c;fill-rule:evenodd;}</style></defs><path class="cls-1" d="M111.11,13.36l.74,14.86c12.04,13.3,16.8,32.15,10.81,49.86-8.95,26.44-38.46,40.33-65.92,31.04-27.46-9.29-42.45-38.26-33.5-64.7,6.01-17.77,21.32-29.87,39.05-33.07L71.87.03C41.99-.77,13.8,17.77,3.72,47.55c-12.4,36.6,7.24,76.33,43.85,88.73,36.6,12.4,76.33-7.24,88.73-43.85,10.07-29.74-1-61.55-25.14-79.07h-.03Z"/><path class="cls-1" d="M93.95,57.21l-.51-20.77-.41-11.95-.28-10.35s.07-4.99-.11-6.16c-.03-.25-.11-.44-.21-.62,0-.03-.02-.05-.03-.07,0-.02-.03-.05-.03-.07-.2-.33-.49-.59-.89-.72s-.8-.1-1.17.05h-.02s-.08.03-.13.07c-.16.08-.34.2-.51.36-.85.82-3.84,4.83-3.84,4.83l-6.5,8.06-7.59,9.25-13.02,16.19s-5.98,7.46-4.65,16.64c1.31,9.18,8.15,13.65,13.43,15.44,5.29,1.79,13.43,2.38,20.05-4.11,6.62-6.49,6.4-16.04,6.4-16.04l.02-.02Z"/></svg>
|
||||
|
After Width: | Height: | Size: 938 B |
|
After Width: | Height: | Size: 255 KiB |
|
After Width: | Height: | Size: 190 KiB |
|
After Width: | Height: | Size: 225 KiB |
|
After Width: | Height: | Size: 190 KiB |
|
After Width: | Height: | Size: 403 KiB |
|
After Width: | Height: | Size: 369 KiB |
|
After Width: | Height: | Size: 242 KiB |
@@ -0,0 +1,48 @@
|
||||
---
|
||||
title: "Mattermost"
|
||||
description: "LangBot に Mattermost ボットを接続し、エージェントやワークフローを数分で Mattermost サーバーに導入します。"
|
||||
icon: "/images/platforms/mattermost.svg"
|
||||
---
|
||||
|
||||
<Note>
|
||||
以下のスクリーンショットは中国語の画面です。本文で説明する対応するメニューや入力欄を参照して操作してください。
|
||||
</Note>
|
||||
|
||||
## ボットアカウントの作成
|
||||
|
||||
Mattermost インスタンス(セルフホスト版または Mattermost が提供するホスト版)にログインします。左上の `Mattermost アイコン`をクリックし、メニューから「統合機能(Integrations)」を選択します。
|
||||
|
||||

|
||||
|
||||
統合機能のページで、左側のメニューから「ボットアカウント(Bot Accounts)」を選択し、右上の「ボットアカウントを追加(Add Bot Account)」をクリックします。
|
||||
|
||||

|
||||
|
||||
ボットのユーザー名を入力します。
|
||||
|
||||

|
||||
|
||||
ロールは「メンバー(Member)」を選択します(管理者向けの機能には現在対応していません)。ダイレクトメッセージが必要な場合は `post:all`、公開チャンネルのみを使用する場合は `post:channels` だけを選択します。右下の「ボットアカウントを作成(Create Bot Account)」をクリックします。
|
||||
|
||||

|
||||
|
||||
ボタンをクリックしてトークンをコピーします。トークンは一度しか表示されないため、安全な場所に保存してください。右下の「完了(Done)」をクリックします。
|
||||
|
||||

|
||||
|
||||
## LangBot でのボット設定
|
||||
|
||||
LangBot Cloud またはセルフホストの LangBot インスタンスを開き、以下の画像の赤い矢印の順に操作します。
|
||||
|
||||
- 左側の「ボット」タブにカーソルを合わせ、表示される `+` アイコンをクリックします。
|
||||
- 「ボット名」欄にボットの名前を入力します。
|
||||
- プラットフォームアダプターのドロップダウンを開き、`Mattermost` を選択します。
|
||||
- Mattermost インスタンスのアドレスと、先ほど作成したボットアカウントのトークンを入力します。
|
||||
- (任意)パイプラインまたは AI プロバイダーがストリーミング出力に対応していない場合は、このオプションを無効にします。
|
||||
- 右上の「送信(Submit)」をクリックすると、ボットの編集画面が開きます。
|
||||
|
||||

|
||||
|
||||
既存のパイプラインを紐付け、必要に応じてルーティングを設定し、右上の「保存(Save)」をクリックします。
|
||||
|
||||

|
||||
@@ -13,6 +13,7 @@ description: "LangBot を各メッセージングプラットフォームに接
|
||||
| Discord | ✅ | | [チュートリアル](/ja/usage/platforms/discord) |
|
||||
| Telegram | ✅ | | [チュートリアル](/ja/usage/platforms/telegram) |
|
||||
| Slack | ✅ | | [チュートリアル](/ja/usage/platforms/slack) |
|
||||
| Mattermost | ✅ | オープンソース版・無料版・Professional 版・Enterprise 版に対応 | [チュートリアル](/ja/usage/platforms/mattermost) |
|
||||
| LINE | ✅ | | [チュートリアル](/ja/usage/platforms/line) |
|
||||
| KOOK | ✅ | | [チュートリアル](/ja/usage/platforms/kook) |
|
||||
| Lark | ✅ | | [チュートリアル](/ja/usage/platforms/lark) |
|
||||
|
||||
@@ -170,8 +170,8 @@ test("MDX compatibility normalization removes internal .html route suffixes", ()
|
||||
test("canonical MDX and nested OpenAPI sources are discovered", async () => {
|
||||
const docs = JSON.parse(await readFile(path.join(root, "docs.json"), "utf8"));
|
||||
const pages = await collectMdxDocuments(root);
|
||||
assert.equal(pages.length, 302);
|
||||
assert.deepEqual(Object.fromEntries([...pages.reduce((acc, page) => acc.set(page.split("/", 1)[0], (acc.get(page.split("/", 1)[0]) ?? 0) + 1), new Map()).entries()]), { en: 96, zh: 110, ja: 96 });
|
||||
assert.equal(pages.length, 305);
|
||||
assert.deepEqual(Object.fromEntries([...pages.reduce((acc, page) => acc.set(page.split("/", 1)[0], (acc.get(page.split("/", 1)[0]) ?? 0) + 1), new Map()).entries()]), { en: 97, zh: 111, ja: 97 });
|
||||
assert.deepEqual(collectOpenApiSources(docs), [
|
||||
{ locale: "en", source: "openapi/service-api-en.json", directory: "en/api-reference" },
|
||||
{ locale: "zh", source: "openapi/service-api-zh.json", directory: "zh/api-reference" },
|
||||
@@ -216,7 +216,7 @@ test("prebuild is deterministic and preserves local assets and SEO files", async
|
||||
const first = await prepareFumapress({ root, outRoot: temp });
|
||||
const second = await prepareFumapress({ root, outRoot: temp });
|
||||
assert.deepEqual(first, second);
|
||||
assert.equal(first.documents, 302);
|
||||
assert.equal(first.documents, 305);
|
||||
assert.equal(first.fallbackDefaults, 0);
|
||||
assert.equal(first.localeOnlyDocuments, 14);
|
||||
assert.equal(first.redirects, 103);
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
"""Read-only contracts for Mattermost documentation translations; no network access."""
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
import re
|
||||
import unittest
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
LOCALES = {"en": "en", "cn": "zh", "jp": "ja"}
|
||||
GUIDE = "usage/platforms/mattermost"
|
||||
IMAGE = re.compile(r"!\[([^\]]*)\]\((/images/[^)]+)\)")
|
||||
|
||||
|
||||
class MattermostDocsTests(unittest.TestCase):
|
||||
def test_each_site_locale_has_a_guide_and_support_table_entry(self):
|
||||
docs = json.loads((ROOT / "docs.json").read_text(encoding="utf-8"))
|
||||
for language in docs["navigation"]["languages"]:
|
||||
locale = LOCALES[language["language"]]
|
||||
with self.subTest(locale=locale):
|
||||
guide = ROOT / f"{locale}/{GUIDE}.mdx"
|
||||
self.assertTrue(guide.is_file(), f"Missing translated guide: {guide}")
|
||||
readme = (guide.parent / "readme.mdx").read_text(encoding="utf-8")
|
||||
rows = [line for line in readme.splitlines() if line.startswith("| Mattermost |")]
|
||||
self.assertEqual(len(rows), 1)
|
||||
self.assertIn("✅", rows[0])
|
||||
self.assertIn(f"](/{locale}/{GUIDE})", rows[0])
|
||||
self.assertTrue(rows[0].split("|")[3].strip(), "Edition support notes missing")
|
||||
|
||||
def test_each_site_locale_lists_mattermost_in_bot_navigation(self):
|
||||
docs = json.loads((ROOT / "docs.json").read_text(encoding="utf-8"))
|
||||
|
||||
def page_lists(value):
|
||||
if isinstance(value, dict):
|
||||
if "pages" in value:
|
||||
yield value["pages"]
|
||||
for child in value.values():
|
||||
yield from page_lists(child)
|
||||
elif isinstance(value, list):
|
||||
for child in value:
|
||||
yield from page_lists(child)
|
||||
|
||||
for language in docs["navigation"]["languages"]:
|
||||
locale = LOCALES[language["language"]]
|
||||
with self.subTest(locale=locale):
|
||||
groups = [pages for pages in page_lists(language)
|
||||
if f"{locale}/usage/platforms/slack" in pages]
|
||||
self.assertEqual(len(groups), 1)
|
||||
self.assertEqual(groups[0].count(f"{locale}/{GUIDE}"), 1)
|
||||
|
||||
def test_translations_preserve_source_steps_permissions_and_assets(self):
|
||||
source = (ROOT / f"zh/{GUIDE}.mdx").read_text(encoding="utf-8")
|
||||
source_images = [url for _, url in IMAGE.findall(source)]
|
||||
for locale, screenshot_note in (("en", "Chinese"), ("ja", "中国語")):
|
||||
with self.subTest(locale=locale):
|
||||
path = ROOT / f"{locale}/{GUIDE}.mdx"
|
||||
self.assertTrue(path.is_file(), f"Missing translated guide: {path}")
|
||||
text = path.read_text(encoding="utf-8")
|
||||
self.assertTrue(text.startswith('---\ntitle: "Mattermost"\n'))
|
||||
self.assertRegex(text, r'(?m)^description: ".+"$')
|
||||
self.assertIn('icon: "/images/platforms/mattermost.svg"', text)
|
||||
self.assertTrue((ROOT / "images/platforms/mattermost.svg").is_file())
|
||||
for permission in ("`post:all`", "`post:channels`"):
|
||||
self.assertIn(permission, text)
|
||||
self.assertEqual(len(re.findall(r"^## ", text, re.M)),
|
||||
len(re.findall(r"^## ", source, re.M)))
|
||||
self.assertEqual(len(re.findall(r"^- ", text, re.M)),
|
||||
len(re.findall(r"^- ", source, re.M)))
|
||||
self.assertIn(screenshot_note, text)
|
||||
images = IMAGE.findall(text)
|
||||
self.assertEqual([url for _, url in images], source_images)
|
||||
for alt, url in images:
|
||||
self.assertTrue(alt.strip(), "Translated screenshot alt text missing")
|
||||
self.assertTrue((ROOT / url.lstrip("/")).is_file(), url)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,44 @@
|
||||
---
|
||||
title: "Mattermost"
|
||||
description: "用 LangBot 接入 Mattermost 机器人,几分钟内将 智能体/工作流 接入 Mattermost 服务器。"
|
||||
icon: "/images/platforms/mattermost.svg"
|
||||
---
|
||||
|
||||
## 创建机器人账号
|
||||
|
||||
登录Mattermost实例(自部署/官方皆可),点击左上角的`Mattermost图标`,在下拉菜单中选择`集成`。
|
||||
|
||||

|
||||
|
||||
进入集成页面后,在左侧菜单中选择`机器人账号`,点击右上角的添加机器人账号。
|
||||
|
||||

|
||||
|
||||
为机器人起一个用户名。
|
||||
|
||||

|
||||
|
||||
身份选择`成员`即可(暂不支持管理员相关功能),需要私聊选`post:all`,仅需要公共频道就只勾选`post:channels`,然后点击右下角的`创建机器人账号`。
|
||||
|
||||

|
||||
|
||||
点击按钮复制令牌(只显示一次,记得保存),点右下角`完成`。
|
||||
|
||||

|
||||
|
||||
## 配置LangBot机器人
|
||||
|
||||
进入LangBot官网或自部署实例,按下图中红箭头指示的顺序操作:
|
||||
|
||||
- 光标移到左侧`机器人`选项卡上,会显示一个加号`+`,点击加号
|
||||
- 给机器人起一个名字,输进`机器人名称`的文本框
|
||||
- 点击平台适配器选择的选项框,在下拉菜单中选择`Mattermost`
|
||||
- 输入`Mattermost`实例的地址和刚才创建的机器人账号的令牌
|
||||
- (可选)如果你的流水线/AI供应商不支持流式输出,则关闭该选项
|
||||
- 点击右上角的提交后会进入编辑该机器人的界面
|
||||
|
||||

|
||||
|
||||
绑定现有的流水线,以及配置路由(如果有需求的话),并点击右上角的保存。
|
||||
|
||||

|
||||
@@ -21,6 +21,7 @@ description: "将 LangBot 接入各消息平台:Discord、Telegram、Slack、
|
||||
| Discord | ✅ | | [教程](/zh/usage/platforms/discord) |
|
||||
| Telegram | ✅ | | [教程](/zh/usage/platforms/telegram) |
|
||||
| Slack | ✅ | | [教程](/zh/usage/platforms/slack) |
|
||||
| Mattermost | ✅ | 适用于开源版、免费版、专业版、企业版 | [教程](/zh/usage/platforms/mattermost) |
|
||||
| LINE | ✅ | | [教程](/zh/usage/platforms/line) |
|
||||
| KOOK | ✅ | | [教程](/zh/usage/platforms/kook) |
|
||||
| 页面机器人 | ✅ | 将聊天组件嵌入网站 | [教程](/zh/usage/platforms/webpage) |
|
||||
|
||||