refactor(channels): make built-in channels self-contained (#4908)
* refactor(channels): own setup and instance contracts * refactor(channels): isolate management contracts * refactor(channels): normalize activation contracts * fix(channels): enforce management contracts * refactor(channels): finish setup ownership migration * fix(channels): harden management contracts * fix(channels): enforce lazy loading and runtime ownership * fix(feishu): make multi-instance startup idempotent * fix(webui): render channel setup contracts cleanly * fix(feishu): stop websocket clients cleanly * fix(channels): enforce persistence and activation gates * fix(channels): preserve global feature action scope * fix(channels): apply defaults for single plugins * fix(channels): enforce management contract boundaries * refactor(feishu): remove identity helper indirection * fix(channels): preserve management setup contracts * refactor(channels): generalize instance settings UI * refactor(channels): package channel plugins with web UI metadata * refactor(channels): make built-ins self-contained packages * test(channels): colocate tests with channel packages * fix(dingtalk): use official brand icon * feat(channels): colocate webui translations * docs(channels): clarify plugin ownership * test(exec): remove output wait race * refactor(channels): unify plugin descriptors * fix(channels): enforce descriptor-owned contracts * refactor(channels): finish package-owned plugin setup * refactor(channels): use repository-owned packages only * fix(channels): self-describe dependencies and runtime state * fix(channels): warn about legacy entry points
This commit is contained in:
@@ -0,0 +1 @@
|
||||
"""Matrix channel package."""
|
||||
@@ -0,0 +1,39 @@
|
||||
"""Matrix management contract."""
|
||||
|
||||
from nanobot.channels._manifest import GROUP_POLICIES, field, one_of, required_fields
|
||||
from nanobot.channels.contracts import ChannelSetupSpec
|
||||
from nanobot.channels.matrix.validation import validate
|
||||
from nanobot.channels.plugin import ChannelPlugin
|
||||
|
||||
SETUP_SPEC = ChannelSetupSpec(
|
||||
fields={
|
||||
"homeserver": field(default="https://matrix.org"),
|
||||
"userId": field(),
|
||||
"password": field("secret"),
|
||||
"accessToken": field("secret"),
|
||||
"deviceId": field(),
|
||||
"groupPolicy": field("enum", choices=GROUP_POLICIES, default="open"),
|
||||
"allowFrom": field("list", writable=False),
|
||||
},
|
||||
required=(
|
||||
*required_fields("homeserver", "userId"),
|
||||
one_of(("password",), ("accessToken", "deviceId")),
|
||||
),
|
||||
official_url="https://matrix.org/ecosystem/clients/",
|
||||
validator=validate,
|
||||
)
|
||||
|
||||
PLUGIN = ChannelPlugin(
|
||||
name="matrix",
|
||||
display_name="Matrix",
|
||||
runtime=f"{__package__}.runtime:MatrixChannel",
|
||||
setup=SETUP_SPEC,
|
||||
dependencies=(
|
||||
"matrix-nio[e2e]>=0.25.2; sys_platform != 'win32'",
|
||||
"matrix-nio>=0.25.2; sys_platform == 'win32'",
|
||||
"aiohttp>=3.9.0,<4.0.0",
|
||||
"mistune>=3.0.0,<4.0.0",
|
||||
"nh3>=0.2.17,<1.0.0",
|
||||
),
|
||||
webui="webui/index.ts",
|
||||
)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
||||
"""Tests for the Matrix channel package."""
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,51 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from nanobot.channels.validation import validate_channel_config
|
||||
from nanobot.config.loader import save_config
|
||||
from nanobot.config.schema import Config
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("credentials", "expected_status", "expected_missing"),
|
||||
[
|
||||
({}, "needs_setup", "password_or_accessToken"),
|
||||
({"channels.matrix.accessToken": "token"}, "needs_setup", "deviceId"),
|
||||
({"channels.matrix.password": "secret"}, "configured", None),
|
||||
(
|
||||
{
|
||||
"channels.matrix.accessToken": "token",
|
||||
"channels.matrix.deviceId": "DEVICE",
|
||||
},
|
||||
"configured",
|
||||
None,
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_validate_matrix_requires_a_complete_login_method(
|
||||
tmp_path,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
credentials: dict[str, str],
|
||||
expected_status: str,
|
||||
expected_missing: str | None,
|
||||
) -> None:
|
||||
config_path = tmp_path / "config.json"
|
||||
save_config(Config(), config_path)
|
||||
monkeypatch.setattr("nanobot.config.loader._current_config_path", config_path)
|
||||
|
||||
result = validate_channel_config(
|
||||
"matrix",
|
||||
{
|
||||
"channels.matrix.homeserver": "https://matrix.example",
|
||||
"channels.matrix.userId": "@nanobot:matrix.example",
|
||||
**credentials,
|
||||
},
|
||||
)
|
||||
|
||||
assert result["status"] == expected_status
|
||||
assert result["can_enable"] is (expected_status == "configured")
|
||||
if expected_missing is None:
|
||||
assert result["missing_fields"] == []
|
||||
else:
|
||||
assert expected_missing in result["missing_fields"]
|
||||
@@ -0,0 +1,46 @@
|
||||
"""Matrix setup validation owned by the channel package."""
|
||||
|
||||
from typing import Any
|
||||
|
||||
from nanobot.channels.contracts import ChannelValidationContext
|
||||
from nanobot.channels.validation import check, required_checks, status_from_checks, string_value
|
||||
|
||||
|
||||
def validate(values: dict[str, Any], _context: ChannelValidationContext) -> dict[str, Any]:
|
||||
checks, missing = required_checks("matrix", values)
|
||||
password = string_value(values.get("password"))
|
||||
access_token = string_value(values.get("accessToken"))
|
||||
device_id = string_value(values.get("deviceId"))
|
||||
|
||||
if password:
|
||||
checks.append(check("login", "Login credentials", "pass", "Password login is configured."))
|
||||
elif access_token and device_id:
|
||||
checks.append(
|
||||
check(
|
||||
"login",
|
||||
"Login credentials",
|
||||
"pass",
|
||||
"Access token login is configured with its device ID.",
|
||||
)
|
||||
)
|
||||
else:
|
||||
if not password and not access_token:
|
||||
missing.append("password_or_accessToken")
|
||||
message = "Add a password, or an access token with its device ID."
|
||||
else:
|
||||
missing.append("deviceId")
|
||||
message = "A device ID is required with an access token."
|
||||
checks.append(check("login", "Login credentials", "fail", message))
|
||||
|
||||
checks.append(
|
||||
check(
|
||||
"manual_review",
|
||||
"Matrix account",
|
||||
"skipped",
|
||||
"Room access is verified when the channel starts.",
|
||||
)
|
||||
)
|
||||
return status_from_checks("matrix", checks, list(dict.fromkeys(missing)))
|
||||
|
||||
|
||||
__all__ = ["validate"]
|
||||
@@ -0,0 +1,23 @@
|
||||
import type { ChannelUiContribution } from "@/channel-plugins/types";
|
||||
import { chatAppGuideUrl } from "@/components/settings/channels/catalog";
|
||||
|
||||
export default {
|
||||
presentation: {
|
||||
displayName: "Matrix",
|
||||
initials: "MX",
|
||||
color: "#0DBD8B",
|
||||
logoUrl: "https://matrix.org/favicon.ico",
|
||||
setup: {
|
||||
mode: "credentials",
|
||||
docsUrl: chatAppGuideUrl("matrix"),
|
||||
fields: [
|
||||
{ key: "channels.matrix.homeserver" },
|
||||
{ key: "channels.matrix.userId" },
|
||||
{ key: "channels.matrix.password" },
|
||||
{ key: "channels.matrix.accessToken" },
|
||||
{ key: "channels.matrix.deviceId" },
|
||||
{ key: "channels.matrix.groupPolicy" },
|
||||
],
|
||||
},
|
||||
},
|
||||
} satisfies ChannelUiContribution;
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"description": "Use nanobot from Matrix rooms.",
|
||||
"requirements": "Homeserver, account token, room access",
|
||||
"setup": {
|
||||
"docsLabel": "Open Matrix setup",
|
||||
"officialLabel": "Open Matrix clients",
|
||||
"tryIt": "Invite the Matrix account into a room and send a test message.",
|
||||
"summary": "Matrix needs a homeserver account and either password login or an access token.",
|
||||
"steps": [
|
||||
"Create or choose a Matrix account for nanobot.",
|
||||
"Enter the homeserver, user ID, and either password or access-token credentials.",
|
||||
"Save and enable Matrix, invite the account to a room, and send a test message."
|
||||
],
|
||||
"fields": {
|
||||
"homeserver": {
|
||||
"label": "Homeserver",
|
||||
"placeholder": "https://matrix.org"
|
||||
},
|
||||
"userId": {
|
||||
"label": "User ID",
|
||||
"placeholder": "@nanobot:matrix.org"
|
||||
},
|
||||
"password": {
|
||||
"label": "Password",
|
||||
"placeholder": "••••••",
|
||||
"help": "Use either password login or access token login."
|
||||
},
|
||||
"accessToken": {
|
||||
"label": "Access token",
|
||||
"placeholder": "Optional token login",
|
||||
"help": "Preferred when your Matrix client exposes an access token."
|
||||
},
|
||||
"deviceId": {
|
||||
"label": "Device ID",
|
||||
"placeholder": "Required with an access token",
|
||||
"help": "Copy the device ID associated with the access token. Password login does not need it."
|
||||
},
|
||||
"groupPolicy": {
|
||||
"label": "Group behavior",
|
||||
"choices": {
|
||||
"mention": "Mention only",
|
||||
"open": "All messages",
|
||||
"allowlist": "Allowlist"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"description": "Usa nanobot desde salas de Matrix.",
|
||||
"requirements": "Homeserver, token de cuenta y acceso a salas",
|
||||
"setup": {
|
||||
"docsLabel": "Abrir guía de Matrix",
|
||||
"officialLabel": "Abrir lista de clientes Matrix",
|
||||
"tryIt": "Invita la cuenta de Matrix a una sala y envía un mensaje de prueba.",
|
||||
"summary": "Matrix necesita una cuenta de homeserver y acceso por contraseña o token.",
|
||||
"steps": [
|
||||
"Crea o elige una cuenta de Matrix para nanobot.",
|
||||
"Introduce el homeserver, ID de usuario y contraseña o token de acceso.",
|
||||
"Guarda y activa Matrix, invita la cuenta a una sala y envía un mensaje de prueba."
|
||||
],
|
||||
"fields": {
|
||||
"homeserver": {
|
||||
"label": "Homeserver",
|
||||
"placeholder": "https://matrix.org"
|
||||
},
|
||||
"userId": {
|
||||
"label": "ID de usuario",
|
||||
"placeholder": "@nanobot:matrix.org"
|
||||
},
|
||||
"password": {
|
||||
"label": "Contraseña",
|
||||
"placeholder": "••••••",
|
||||
"help": "Usa contraseña o token de acceso."
|
||||
},
|
||||
"accessToken": {
|
||||
"label": "Token de acceso",
|
||||
"placeholder": "Acceso opcional con token",
|
||||
"help": "Preferible si tu cliente Matrix muestra un token de acceso."
|
||||
},
|
||||
"deviceId": {
|
||||
"label": "ID del dispositivo",
|
||||
"placeholder": "Obligatorio con token",
|
||||
"help": "Copia el ID asociado al token. No se necesita con contraseña."
|
||||
},
|
||||
"groupPolicy": {
|
||||
"label": "Comportamiento en grupos",
|
||||
"choices": {
|
||||
"mention": "Solo menciones",
|
||||
"open": "Todos los mensajes",
|
||||
"allowlist": "Lista permitida"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"description": "Utilisez nanobot depuis les salons Matrix.",
|
||||
"requirements": "Serveur d’accueil, jeton de compte et accès aux salons",
|
||||
"setup": {
|
||||
"docsLabel": "Ouvrir le guide Matrix",
|
||||
"officialLabel": "Ouvrir la liste des clients Matrix",
|
||||
"tryIt": "Invitez le compte Matrix dans un salon et envoyez un message test.",
|
||||
"summary": "Matrix nécessite un compte sur un serveur d’accueil et une connexion par mot de passe ou jeton d’accès.",
|
||||
"steps": [
|
||||
"Créez ou choisissez un compte Matrix pour nanobot.",
|
||||
"Saisissez le serveur, l’ID utilisateur et le mot de passe ou le jeton d’accès.",
|
||||
"Enregistrez et activez Matrix, invitez le compte dans un salon et envoyez un message test."
|
||||
],
|
||||
"fields": {
|
||||
"homeserver": {
|
||||
"label": "Serveur d’accueil",
|
||||
"placeholder": "https://matrix.org"
|
||||
},
|
||||
"userId": {
|
||||
"label": "ID utilisateur",
|
||||
"placeholder": "@nanobot:matrix.org"
|
||||
},
|
||||
"password": {
|
||||
"label": "Mot de passe",
|
||||
"placeholder": "••••••",
|
||||
"help": "Utilisez le mot de passe ou le jeton d’accès."
|
||||
},
|
||||
"accessToken": {
|
||||
"label": "Jeton d’accès",
|
||||
"placeholder": "Connexion facultative par jeton",
|
||||
"help": "À privilégier si votre client Matrix expose un jeton d’accès."
|
||||
},
|
||||
"deviceId": {
|
||||
"label": "ID de l’appareil",
|
||||
"placeholder": "Requis avec un jeton d’accès",
|
||||
"help": "Copiez l’ID d’appareil associé au jeton. Il n’est pas nécessaire avec un mot de passe."
|
||||
},
|
||||
"groupPolicy": {
|
||||
"label": "Comportement en groupe",
|
||||
"choices": {
|
||||
"mention": "Mentions uniquement",
|
||||
"open": "Tous les messages",
|
||||
"allowlist": "Liste d’autorisation"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"description": "Gunakan nanobot dari ruang Matrix.",
|
||||
"requirements": "Homeserver, token akun, dan akses ruang",
|
||||
"setup": {
|
||||
"docsLabel": "Buka panduan Matrix",
|
||||
"officialLabel": "Buka daftar klien Matrix",
|
||||
"tryIt": "Undang akun Matrix ke ruang dan kirim pesan uji.",
|
||||
"summary": "Matrix memerlukan akun homeserver dan login dengan kata sandi atau token akses.",
|
||||
"steps": [
|
||||
"Buat atau pilih akun Matrix untuk nanobot.",
|
||||
"Masukkan homeserver, ID pengguna, dan kata sandi atau token akses.",
|
||||
"Simpan dan aktifkan Matrix, undang akun ke ruang, lalu kirim pesan uji."
|
||||
],
|
||||
"fields": {
|
||||
"homeserver": {
|
||||
"label": "Homeserver",
|
||||
"placeholder": "https://matrix.org"
|
||||
},
|
||||
"userId": {
|
||||
"label": "ID pengguna",
|
||||
"placeholder": "@nanobot:matrix.org"
|
||||
},
|
||||
"password": {
|
||||
"label": "Kata sandi",
|
||||
"placeholder": "••••••",
|
||||
"help": "Gunakan kata sandi atau token akses."
|
||||
},
|
||||
"accessToken": {
|
||||
"label": "Token akses",
|
||||
"placeholder": "Login token opsional",
|
||||
"help": "Disarankan jika klien Matrix menyediakan token akses."
|
||||
},
|
||||
"deviceId": {
|
||||
"label": "ID perangkat",
|
||||
"placeholder": "Wajib dengan token akses",
|
||||
"help": "Salin ID perangkat yang terkait token. Login kata sandi tidak memerlukannya."
|
||||
},
|
||||
"groupPolicy": {
|
||||
"label": "Perilaku grup",
|
||||
"choices": {
|
||||
"mention": "Hanya sebutan",
|
||||
"open": "Semua pesan",
|
||||
"allowlist": "Daftar izin"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"description": "Matrix ルームから nanobot を利用します。",
|
||||
"requirements": "ホームサーバー、アカウントトークン、ルームへのアクセス",
|
||||
"setup": {
|
||||
"docsLabel": "Matrix 設定ガイドを開く",
|
||||
"officialLabel": "Matrix クライアント一覧を開く",
|
||||
"tryIt": "Matrix アカウントをルームに招待し、テストメッセージを送信します。",
|
||||
"summary": "Matrix にはホームサーバーのアカウントと、パスワードまたはアクセストークンが必要です。",
|
||||
"steps": [
|
||||
"nanobot 用の Matrix アカウントを作成または選択します。",
|
||||
"ホームサーバー、ユーザー ID、パスワードまたはアクセストークンを入力します。",
|
||||
"保存して Matrix を有効にし、アカウントをルームに招待してテストメッセージを送信します。"
|
||||
],
|
||||
"fields": {
|
||||
"homeserver": {
|
||||
"label": "ホームサーバー",
|
||||
"placeholder": "https://matrix.org"
|
||||
},
|
||||
"userId": {
|
||||
"label": "ユーザー ID",
|
||||
"placeholder": "@nanobot:matrix.org"
|
||||
},
|
||||
"password": {
|
||||
"label": "パスワード",
|
||||
"placeholder": "••••••",
|
||||
"help": "パスワードまたはアクセストークンのどちらかを使います。"
|
||||
},
|
||||
"accessToken": {
|
||||
"label": "アクセストークン",
|
||||
"placeholder": "任意のトークンログイン",
|
||||
"help": "Matrix クライアントでアクセストークンを取得できる場合に推奨します。"
|
||||
},
|
||||
"deviceId": {
|
||||
"label": "デバイス ID",
|
||||
"placeholder": "アクセストークン使用時に必須",
|
||||
"help": "トークンに関連付けられたデバイス ID をコピーします。パスワードログインでは不要です。"
|
||||
},
|
||||
"groupPolicy": {
|
||||
"label": "グループでの動作",
|
||||
"choices": {
|
||||
"mention": "メンションのみ",
|
||||
"open": "すべてのメッセージ",
|
||||
"allowlist": "許可リスト"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"description": "Matrix 룸에서 nanobot을 사용합니다.",
|
||||
"requirements": "홈서버, 계정 토큰 및 룸 접근 권한",
|
||||
"setup": {
|
||||
"docsLabel": "Matrix 설정 가이드 열기",
|
||||
"officialLabel": "Matrix 클라이언트 목록 열기",
|
||||
"tryIt": "Matrix 계정을 룸에 초대하고 테스트 메시지를 보내세요.",
|
||||
"summary": "Matrix에는 홈서버 계정과 비밀번호 또는 액세스 토큰이 필요합니다.",
|
||||
"steps": [
|
||||
"nanobot용 Matrix 계정을 만들거나 선택하세요.",
|
||||
"홈서버, 사용자 ID, 비밀번호 또는 액세스 토큰을 입력하세요.",
|
||||
"저장하고 Matrix를 활성화한 다음 계정을 룸에 초대하고 테스트 메시지를 보내세요."
|
||||
],
|
||||
"fields": {
|
||||
"homeserver": {
|
||||
"label": "홈서버",
|
||||
"placeholder": "https://matrix.org"
|
||||
},
|
||||
"userId": {
|
||||
"label": "사용자 ID",
|
||||
"placeholder": "@nanobot:matrix.org"
|
||||
},
|
||||
"password": {
|
||||
"label": "비밀번호",
|
||||
"placeholder": "••••••",
|
||||
"help": "비밀번호 또는 액세스 토큰 중 하나를 사용하세요."
|
||||
},
|
||||
"accessToken": {
|
||||
"label": "액세스 토큰",
|
||||
"placeholder": "선택적 토큰 로그인",
|
||||
"help": "Matrix 클라이언트에서 토큰을 확인할 수 있다면 권장합니다."
|
||||
},
|
||||
"deviceId": {
|
||||
"label": "장치 ID",
|
||||
"placeholder": "액세스 토큰 사용 시 필수",
|
||||
"help": "토큰과 연결된 장치 ID를 복사하세요. 비밀번호 로그인에는 필요하지 않습니다."
|
||||
},
|
||||
"groupPolicy": {
|
||||
"label": "그룹 동작",
|
||||
"choices": {
|
||||
"mention": "멘션만",
|
||||
"open": "모든 메시지",
|
||||
"allowlist": "허용 목록"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"description": "Use o nanobot em salas do Matrix.",
|
||||
"requirements": "Homeserver, token da conta e acesso às salas",
|
||||
"setup": {
|
||||
"docsLabel": "Abrir guia do Matrix",
|
||||
"officialLabel": "Abrir lista de clientes Matrix",
|
||||
"tryIt": "Convide a conta Matrix para uma sala e envie uma mensagem de teste.",
|
||||
"summary": "O Matrix precisa de uma conta no homeserver e login por senha ou token de acesso.",
|
||||
"steps": [
|
||||
"Crie ou escolha uma conta Matrix para o nanobot.",
|
||||
"Informe o homeserver, ID de usuário e senha ou token de acesso.",
|
||||
"Salve e ative o Matrix, convide a conta para uma sala e envie uma mensagem de teste."
|
||||
],
|
||||
"fields": {
|
||||
"homeserver": {
|
||||
"label": "Homeserver",
|
||||
"placeholder": "https://matrix.org"
|
||||
},
|
||||
"userId": {
|
||||
"label": "ID de usuário",
|
||||
"placeholder": "@nanobot:matrix.org"
|
||||
},
|
||||
"password": {
|
||||
"label": "Senha",
|
||||
"placeholder": "••••••",
|
||||
"help": "Use senha ou token de acesso."
|
||||
},
|
||||
"accessToken": {
|
||||
"label": "Token de acesso",
|
||||
"placeholder": "Login opcional por token",
|
||||
"help": "Preferível quando o cliente Matrix fornece um token."
|
||||
},
|
||||
"deviceId": {
|
||||
"label": "ID do dispositivo",
|
||||
"placeholder": "Obrigatório com token",
|
||||
"help": "Copie o ID associado ao token. O login por senha não precisa dele."
|
||||
},
|
||||
"groupPolicy": {
|
||||
"label": "Comportamento em grupos",
|
||||
"choices": {
|
||||
"mention": "Somente menções",
|
||||
"open": "Todas as mensagens",
|
||||
"allowlist": "Lista de permissão"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"description": "Sử dụng nanobot từ các phòng Matrix.",
|
||||
"requirements": "Homeserver, token tài khoản và quyền truy cập phòng",
|
||||
"setup": {
|
||||
"docsLabel": "Mở hướng dẫn Matrix",
|
||||
"officialLabel": "Mở danh sách ứng dụng Matrix",
|
||||
"tryIt": "Mời tài khoản Matrix vào phòng và gửi tin nhắn thử.",
|
||||
"summary": "Matrix cần tài khoản homeserver và đăng nhập bằng mật khẩu hoặc token truy cập.",
|
||||
"steps": [
|
||||
"Tạo hoặc chọn tài khoản Matrix cho nanobot.",
|
||||
"Nhập homeserver, ID người dùng và mật khẩu hoặc token truy cập.",
|
||||
"Lưu và bật Matrix, mời tài khoản vào phòng rồi gửi tin nhắn thử."
|
||||
],
|
||||
"fields": {
|
||||
"homeserver": {
|
||||
"label": "Homeserver",
|
||||
"placeholder": "https://matrix.org"
|
||||
},
|
||||
"userId": {
|
||||
"label": "ID người dùng",
|
||||
"placeholder": "@nanobot:matrix.org"
|
||||
},
|
||||
"password": {
|
||||
"label": "Mật khẩu",
|
||||
"placeholder": "••••••",
|
||||
"help": "Dùng mật khẩu hoặc token truy cập."
|
||||
},
|
||||
"accessToken": {
|
||||
"label": "Token truy cập",
|
||||
"placeholder": "Đăng nhập token tùy chọn",
|
||||
"help": "Nên dùng khi ứng dụng Matrix cung cấp token truy cập."
|
||||
},
|
||||
"deviceId": {
|
||||
"label": "ID thiết bị",
|
||||
"placeholder": "Bắt buộc khi dùng token",
|
||||
"help": "Sao chép ID thiết bị gắn với token. Đăng nhập mật khẩu không cần."
|
||||
},
|
||||
"groupPolicy": {
|
||||
"label": "Hành vi trong nhóm",
|
||||
"choices": {
|
||||
"mention": "Chỉ khi được nhắc",
|
||||
"open": "Mọi tin nhắn",
|
||||
"allowlist": "Danh sách cho phép"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"description": "在 Matrix 房间中使用 nanobot。",
|
||||
"requirements": "主服务器、账户令牌和房间访问权限",
|
||||
"setup": {
|
||||
"docsLabel": "打开 Matrix 配置指南",
|
||||
"officialLabel": "打开 Matrix 客户端列表",
|
||||
"tryIt": "将 Matrix 账户邀请进房间并发送一条测试消息。",
|
||||
"summary": "Matrix 需要主服务器账户,并使用密码或访问令牌登录。",
|
||||
"steps": [
|
||||
"为 nanobot 创建或选择一个 Matrix 账户。",
|
||||
"填写主服务器、用户 ID,以及密码或访问令牌凭据。",
|
||||
"保存并启用 Matrix,将账户邀请进房间,然后发送一条测试消息。"
|
||||
],
|
||||
"fields": {
|
||||
"homeserver": {
|
||||
"label": "主服务器",
|
||||
"placeholder": "https://matrix.org"
|
||||
},
|
||||
"userId": {
|
||||
"label": "用户 ID",
|
||||
"placeholder": "@nanobot:matrix.org"
|
||||
},
|
||||
"password": {
|
||||
"label": "密码",
|
||||
"placeholder": "••••••",
|
||||
"help": "密码登录和访问令牌登录任选其一。"
|
||||
},
|
||||
"accessToken": {
|
||||
"label": "访问令牌",
|
||||
"placeholder": "可选的令牌登录",
|
||||
"help": "如果 Matrix 客户端可以显示访问令牌,建议使用该方式。"
|
||||
},
|
||||
"deviceId": {
|
||||
"label": "设备 ID",
|
||||
"placeholder": "使用访问令牌时必填",
|
||||
"help": "复制与访问令牌关联的设备 ID;密码登录不需要。"
|
||||
},
|
||||
"groupPolicy": {
|
||||
"label": "群组行为",
|
||||
"choices": {
|
||||
"mention": "仅提及时",
|
||||
"open": "所有消息",
|
||||
"allowlist": "白名单"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"description": "在 Matrix 房間中使用 nanobot。",
|
||||
"requirements": "主伺服器、帳戶權杖和房間存取權限",
|
||||
"setup": {
|
||||
"docsLabel": "開啟 Matrix 設定指南",
|
||||
"officialLabel": "開啟 Matrix 用戶端列表",
|
||||
"tryIt": "將 Matrix 帳戶邀請進房間並傳送一則測試訊息。",
|
||||
"summary": "Matrix 需要主伺服器帳戶,並使用密碼或存取權杖登入。",
|
||||
"steps": [
|
||||
"為 nanobot 建立或選擇一個 Matrix 帳戶。",
|
||||
"填入主伺服器、使用者 ID,以及密碼或存取權杖憑證。",
|
||||
"儲存並啟用 Matrix,將帳戶邀請進房間,然後傳送一則測試訊息。"
|
||||
],
|
||||
"fields": {
|
||||
"homeserver": {
|
||||
"label": "主伺服器",
|
||||
"placeholder": "https://matrix.org"
|
||||
},
|
||||
"userId": {
|
||||
"label": "使用者 ID",
|
||||
"placeholder": "@nanobot:matrix.org"
|
||||
},
|
||||
"password": {
|
||||
"label": "密碼",
|
||||
"placeholder": "••••••",
|
||||
"help": "密碼登入和存取權杖登入任選其一。"
|
||||
},
|
||||
"accessToken": {
|
||||
"label": "存取權杖",
|
||||
"placeholder": "可選的權杖登入",
|
||||
"help": "若 Matrix 用戶端可顯示存取權杖,建議使用此方式。"
|
||||
},
|
||||
"deviceId": {
|
||||
"label": "裝置 ID",
|
||||
"placeholder": "使用存取權杖時必填",
|
||||
"help": "複製與存取權杖關聯的裝置 ID;密碼登入不需要。"
|
||||
},
|
||||
"groupPolicy": {
|
||||
"label": "群組行為",
|
||||
"choices": {
|
||||
"mention": "僅提及時",
|
||||
"open": "所有訊息",
|
||||
"allowlist": "允許清單"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user