Matrix, Mattermost, Nextcloud Talk
Matrix E2EE를 포함한 자체 호스팅 워크스페이스 채팅 플랫폼.
이 페이지는 Revka의 세 가지 자체 호스팅 워크스페이스 채팅 채널인 Matrix(종단 간 암호화 룸 포함), Mattermost, Nextcloud Talk에 대한 레퍼런스입니다. 세 채널 모두 에이전트의 대화 기록을 귀하가 관리하는 인프라 내에 보관하므로, 프라이빗하거나 규제 환경에 있거나 에어갭 배포에 적합합니다. 정확한 설정 키, 전달 동작, 빌드 요구 사항, 웹훅 서명 계약이 필요할 때 이 페이지를 참고하십시오. 단계별 설정은 Mattermost 및 Nextcloud Talk 설정과 Telegram 및 Matrix 설정을 참조하십시오.
세 채널 모두 ~/.revka/config.toml의 [channels_config] 아래에서 구성합니다. 파일을 직접 편집하거나 revka onboard --channels-only를 실행한 뒤 데몬을 재시작하여 변경 사항을 적용하십시오. 모든 채널이 공유하는 트레이트 모델, 전달 모드, 허용 목록 시맨틱스는 채널 개요를 참조하십시오.
한눈에 보기
섹션 제목: “한눈에 보기”| 채널 | 수신 방식 | 공개 인바운드 포트 필요 여부 | 빌드 기능 플래그 |
|---|---|---|---|
| Matrix | sync API (E2EE) | 아니요 | channel-matrix |
| Mattermost | REST v4 폴링 | 아니요 | — |
| Nextcloud Talk | 웹훅 (푸시) | 예 | — |
세 채널 중 빌드 시점에 기능 게이팅이 적용되는 것은 Matrix뿐입니다. Mattermost와 Nextcloud Talk는 항상 컴파일에 포함됩니다.
Matrix
섹션 제목: “Matrix”Matrix 채널은 matrix-sdk를 통해 Matrix 클라이언트-서버 API를 사용합니다. 암호화된 룸에 대한 종단 간 암호화(E2EE), 다중 허용 룸, 룸 별칭 해석, 초안 스트리밍, 다중 메시지 문단 전달, 오디오 첨부 파일의 음성 전사, 일회성 키(OTK) 충돌 감지, 서버 측 키 백업에서의 교차 서명 복구를 지원합니다.
Matrix 설정
섹션 제목: “Matrix 설정”[channels_config.matrix]homeserver = "https://matrix.example.com"access_token = "syt_..."user_id = "@revka:matrix.example.com"device_id = "DEVICEID123"room_id = "!room:matrix.example.com"allowed_rooms = []allowed_users = ["*"]stream_mode = "partial" # off | partial | multi_messagedraft_update_interval_ms = 1500multi_message_delay_ms = 800recovery_key = "" # optional: cross-signing recovery| 필드 | 타입 | 기본값 | 설명 |
|---|---|---|---|
homeserver | string | — | 홈서버 기본 URL. 필수. |
access_token | string | — | 봇 계정 액세스 토큰. 필수. |
user_id | string | — | 봇 Matrix ID(@name:server). E2EE 세션 복원을 위해 권장. |
device_id | string | — | 안정적인 디바이스 식별자. E2EE에 권장; 없으면 재시작마다 새 디바이스가 등록되어 키 공유가 중단됩니다. |
room_id | string | — | 기본 룸. 정규 ID(!room:server)를 권장하며, 별칭(#name:server)은 런타임에 해석됩니다. |
allowed_rooms | array | [] | 비어 있지 않으면 봇이 메시지를 수락하는 룸 ID/별칭의 전체 집합입니다(단일 룸 필터를 대체하며, 기본 room_id도 계속 수락하려면 여기에 포함해야 합니다). 비어 있으면(기본값) 구성된 room_id에서만 수신합니다. |
allowed_users | array | — | 상호작용을 허용할 Matrix 사용자 ID. []는 모두 거부, ["*"]는 모두 허용. |
stream_mode | string | — | "off", "partial"(m.replace를 통한 초안 실시간 편집), 또는 "multi_message"(문단 분할). |
draft_update_interval_ms | number | 1500 | 초안 스트리밍의 편집 스로틀. E2EE 오버헤드를 흡수하기 위해 다른 채널보다 높게 설정됩니다. |
multi_message_delay_ms | number | 800 | multi_message 모드에서 문단 청크 간 지연 시간. |
recovery_key | string | — | 서버 백업에서 룸 키를 복원하기 위한 교차 서명 복구 키. |
transcription.* | table | — | 오디오 첨부 파일의 음성-텍스트 변환. 음성, TTS 및 전사를 참조하십시오. |
Matrix 채널은 공개 인바운드 포트가 필요하지 않습니다. 홈서버에 아웃바운드로 연결하여 sync API를 통해 메시지를 수신합니다.
종단 간 암호화(E2EE)
섹션 제목: “종단 간 암호화(E2EE)”E2EE는 matrix-sdk를 통해 투명하게 처리됩니다. 봇의 디바이스에 룸 키가 있는 경우 별도 설정 없이 암호화된 룸에서 복호화 및 응답이 이루어집니다. 안정적인 암호화 동작을 위해 다음을 권장합니다.
- 안정적인
device_id를 설정하십시오. 디바이스 ID가 변경되면 재시작마다 새 디바이스 등록이 강제되어 기존 키 공유 및 디바이스 검증이 중단됩니다./_matrix/client/v3/account/whoami, 비밀번호 로그인, 또는 Element의 설정 → 세션에서 값을 확인할 수 있습니다. user_id를 설정하여 재시작 후에도 아이덴티티가 유지되도록 하십시오.recovery_key를 설정하여 암호화 스토어 초기화, 신규 설치, 또는 디바이스 초기화 후 서버 측 백업에서 룸 키와 교차 서명 시크릿이 자동으로 복원되도록 하십시오. 복원에 성공하면 Revka는Matrix E2EE recovery successful을 로그에 기록합니다.
로컬 암호화 스토어는 ~/.revka/state/matrix/에 위치합니다. 홈서버에서 디바이스를 등록 해제하지 않고 삭제하면 오래된 디바이스로 인해 OTK 업로드 충돌이 발생합니다.
”연결됐지만 응답 없음” 체크리스트
섹션 제목: “”연결됐지만 응답 없음” 체크리스트”Matrix에서 가장 흔한 증상은 “설정은 올바르고 확인도 통과했지만 봇이 응답하지 않는다”는 것입니다. 다음 순서로 확인하십시오.
- 발신자가
allowed_users에 의해 허용되어 있는지 확인합니다(테스트 시["*"]사용 —[]는 모두 거부). - 봇 계정이 대상 룸에 실제로 입장했는지 확인합니다.
access_token이 동일한 봇 계정 소유인지 확인합니다(whoami검사).- E2EE 룸의 경우 봇 디바이스가 신뢰할 수 있는 디바이스로부터 룸 키를 수신했는지 확인합니다.
- 설정 변경 후 데몬을 재시작했는지 확인합니다.
E2EE 진단을 위해 채널의 로그 레벨을 높이십시오.
RUST_LOG=revka::channels::matrix=debug revka daemonSDK 수준 암호화 세부 정보를 보려면 matrix_sdk_crypto=debug를 추가하십시오.
Mattermost
섹션 제목: “Mattermost”Mattermost 채널은 봇 액세스 토큰으로 Mattermost REST API v4를 폴링합니다. 공개 인바운드 포트가 필요 없습니다. 스레드 답장, 멘션 전용 필터링, 타이핑 인디케이터, 오디오 첨부 파일의 음성 전사(25 MB 제한)를 지원합니다.
Mattermost 설정
섹션 제목: “Mattermost 설정”[channels_config.mattermost]url = "https://mm.example.com"bot_token = "mattermost-token"channel_id = "channel-id"allowed_users = ["*"]thread_replies = truemention_only = false| 필드 | 타입 | 기본값 | 설명 |
|---|---|---|---|
url | string | — | Mattermost 서버의 기본 URL. 필수. |
bot_token | string | — | 봇 계정 개인 액세스 토큰. 필수. |
channel_id | string | — | 수신할 채널. 리슨 모드에서 필수; 생략하면 접근 가능한 모든 채널에서 수신. |
allowed_users | array | — | 상호작용을 허용할 Mattermost 사용자 ID. []는 모두 거부, ["*"]는 모두 허용. |
thread_replies | bool | true | 최상위 메시지에 스레드로 답장. |
mention_only | bool | false | true이면 봇을 @ 멘션한 메시지만 처리. |
proxy_url | string | — | 선택적 채널별 HTTP/SOCKS5 프록시. |
transcription.* | table | — | 오디오 첨부 파일의 음성-텍스트 변환(25 MB 제한). |
스레딩 및 멘션 전용 동작
섹션 제목: “스레딩 및 멘션 전용 동작”- 사용자가 기존 스레드 내에서 답장하면 Revka는 항상 같은 스레드에 답장합니다.
thread_replies = true(기본값)이면 Revka는 최상위 메시지에 스레드로 답장합니다.thread_replies = false이면 채널 루트에 답장합니다.mention_only = true이면 Revka는allowed_users검사 이후 추가 필터를 적용합니다. 봇을 명시적으로@bot_username멘션하지 않은 메시지는 무시되며, 멘션 토큰은 모델에 전달되기 전에 제거됩니다. 이는 바쁜 공유 채널에서 불필요한 모델 호출을 줄이는 데 유용합니다.
폴링은 재시도 백오프가 적용된 속도 제한이 있습니다. 봇 계정 생성 및 채널 ID 확인 방법은 Mattermost 및 Nextcloud Talk 설정을 참조하십시오.
Nextcloud Talk
섹션 제목: “Nextcloud Talk”Nextcloud Talk 채널은 웹훅 모드로 동작합니다. Nextcloud가 각 룸 이벤트를 게이트웨이의 POST /nextcloud-talk으로 푸시하면, Revka는 서명을 검증하고 에이전트를 실행한 뒤 Nextcloud Talk OCS API를 통해 응답합니다. Nextcloud가 게이트웨이에 접근해야 하므로 공개 HTTPS URL이 필요합니다. 터널로 게이트웨이 노출하기를 참조하십시오.
Nextcloud Talk 설정
섹션 제목: “Nextcloud Talk 설정”[channels_config.nextcloud_talk]base_url = "https://cloud.example.com"app_token = "nextcloud-talk-app-token"bot_name = "revka"webhook_secret = "optional-webhook-secret"allowed_users = ["*"]| 필드 | 타입 | 기본값 | 설명 |
|---|---|---|---|
base_url | string | — | Nextcloud 인스턴스 URL. 필수. 끝에 슬래시가 있으면 자동으로 제거됩니다. |
app_token | string | — | 아웃바운드 OCS 답장 시 Authorization: Bearer <token>으로 전송되는 봇 앱 토큰. 필수. |
bot_name | string | — | 봇의 Talk 표시 이름. 셀프 에코 방지에 사용됩니다(아래 참조). 설정하지 않으면 빈 문자열이 기본값이 되지만, 리터럴 이름 revka는 이 설정에 관계없이 하드코딩된 검사를 통해 항상 봇으로 처리됩니다. |
webhook_secret | string | — | 인바운드 웹훅 서명 검증을 위한 공유 HMAC 시크릿. 권장. REVKA_NEXTCLOUD_TALK_WEBHOOK_SECRET 환경 변수로 덮어쓸 수 있습니다. |
allowed_users | array | — | 허용할 Nextcloud 액터 ID. []는 모두 거부, ["*"]는 모두 허용. users/ 또는 bots/ 접두사를 제거한 후 매칭됩니다. |
proxy_url | string | — | 선택적 채널별 HTTP/SOCKS5 프록시. |
웹훅 인그레스 엔드포인트
섹션 제목: “웹훅 인그레스 엔드포인트”Nextcloud Talk 봇의 웹훅 URL을 게이트웨이 인그레스 경로로 지정하십시오. 게이트웨이는 시작 시 해당 라우트를 로그에 기록합니다(POST /nextcloud-talk — Nextcloud Talk bot webhook).
POST /nextcloud-talkContent-Type: application/jsonX-Nextcloud-Talk-Random: <random-seed>X-Nextcloud-Talk-Signature: <hmac-hex>이 엔드포인트는 베어러 토큰을 사용하지 않으며 서명으로 인증됩니다(아래 참조).
| 응답 | 발생 조건 |
|---|---|
404 | [channels_config.nextcloud_talk]가 구성되지 않은 경우. |
400 | 요청 본문이 유효한 JSON이 아닌 경우. |
401 | 서명 검증 실패(시크릿이 설정된 경우에만 확인). |
200 | 수락됨. 페이로드에 처리 가능한 사용자 메시지가 없는 경우에도 반환됨 — 봇, 시스템, Note가 아닌 이벤트, 허용되지 않은 이벤트는 자동으로 확인 응답됩니다. |
아웃바운드 답장은 웹훅 페이로드의 Talk 룸으로 OCS 채팅 API를 통해 전송됩니다.
POST <base_url>/ocs/v2.php/apps/spreed/api/v1/chat/<room-token>?format=jsonAuthorization: Bearer <app_token>OCS-APIRequest: trueRevka는 현재 Nextcloud Talk 봇이 전송하는 Activity Streams 2.0 Create 페이로드와 레거시 message 형식을 모두 파싱하며, 밀리초 및 초 단위 타임스탬프를 모두 정규화합니다.
bot_name 셀프 에코 방지
섹션 제목: “bot_name 셀프 에코 방지”웹훅 봇은 자신의 답장이 새 룸 이벤트로 에코되어 에이전트가 스스로 영원히 답장하는 피드백 루프를 일으킬 수 있습니다. Revka는 자체 발신 이벤트가 모델에 도달하기 전에 제거합니다.
- 액터 타입이
bots또는application인 이벤트는 무시됩니다. - 액터 ID에
bots/접두사가 있는 이벤트는 무시됩니다. - 액터 이름이 구성된
bot_name과 일치하는(대소문자 무시) 이벤트는 무시됩니다. 리터럴 이름revka는 다른bot_name을 설정한 경우에도 항상 봇으로 처리됩니다.
이름 검사는 안전망 역할을 합니다. Nextcloud는 봇이 보낸 메시지에 대해 액터 타입을 항상 신뢰할 수 있게 설정하지 않으므로, bot_name으로 매칭하면 타입 검사를 통과하는 에코를 잡을 수 있습니다. bot_name을 봇의 정확한 Talk 표시 이름으로 설정하십시오.
웹훅 서명 검증
섹션 제목: “웹훅 서명 검증”Nextcloud Talk 웹훅은 세 채널 중 유일한 인그레스 엔드포인트입니다(Matrix와 Mattermost는 아웃바운드 연결 방식이므로 서명할 인바운드 웹훅이 없습니다). webhook_secret이 구성된 경우, POST /nextcloud-talk로 들어오는 모든 요청은 HMAC-SHA256 서명으로 인증됩니다.
Revka는 두 헤더를 읽고 다음을 계산합니다.
hex( hmac_sha256( secret, X-Nextcloud-Talk-Random + raw_request_body ) )결과는 X-Nextcloud-Talk-Signature 헤더와 상수 시간 비교됩니다. 주요 사항:
- HMAC는 랜덤 시드 뒤에 원시 요청 본문을 연결한 값을 대상으로 합니다 — 재직렬화된 JSON 객체가 아닙니다. Nextcloud와 게이트웨이 사이에서 프록시가 본문을 재작성하거나 재포맷하지 않도록 하십시오. 그렇지 않으면 검증이 실패합니다.
- 서명 헤더에
sha256=접두사가 있으면 수락 후 제거됩니다. X-Nextcloud-Talk-Random헤더가 없거나, 서명이 잘못된 형식이거나(유효한 16진수가 아님), 다이제스트가 일치하지 않으면 게이트웨이는401 Invalid signature를 반환합니다.
REVKA_NEXTCLOUD_TALK_WEBHOOK_SECRET
섹션 제목: “REVKA_NEXTCLOUD_TALK_WEBHOOK_SECRET”시크릿은 설정 파일 또는 환경 변수에서 가져올 수 있으며, 환경 변수가 우선합니다.
export REVKA_NEXTCLOUD_TALK_WEBHOOK_SECRET="your-webhook-secret"우선 순위:
REVKA_NEXTCLOUD_TALK_WEBHOOK_SECRET(환경 변수) — 설정되어 있고 비어 있지 않으면 사용.[channels_config.nextcloud_talk]아래의webhook_secret— 그 외의 경우 사용.
환경 변수를 사용하면 시크릿을 config.toml에서 제외할 수 있습니다. Nextcloud Talk 봇에도 동일한 시크릿을 설정해야 양쪽에서 동일한 HMAC가 계산됩니다. 게이트웨이 인그레스 엔드포인트 전체와 서명 규칙은 웹훅 인그레스를 참조하십시오.
channel-matrix 기능 플래그
섹션 제목: “channel-matrix 기능 플래그”Matrix 지원은 matrix-sdk 의존성을 가져오는 Cargo 기능 channel-matrix 뒤에 컴파일됩니다. 이는 기본 Cargo 기능이 아니므로 cargo build나 cargo install만 실행하면 Matrix가 제외됩니다. 공식 릴리스 바이너리는 릴리스 파이프라인에서 --features channel-matrix를 명시적으로 지정하여 빌드하므로 Matrix가 포함됩니다. 직접 빌드하려면 다음을 실행하십시오.
cargo build --release --features channel-matrix--no-default-features와 직접 선택한 기능 목록으로 빌드하는 경우, Matrix가 필요하면 channel-matrix를 다시 추가하십시오. Mattermost와 Nextcloud Talk는 기능 플래그가 없으며 항상 사용 가능합니다. 채널 기능 플래그 전체 목록(Matrix, Lark, Nostr, WhatsApp Web, Voice Wake)은 Cargo 기능 플래그 및 ADR을 참조하십시오.
허용 목록 시맨틱스
섹션 제목: “허용 목록 시맨틱스”세 채널 모두 allowed_users로 인바운드 발신자를 제한합니다.
- 빈 목록(
[])은 모든 발신자를 거부합니다. "*"단일 항목은 모든 발신자를 허용합니다.- 그 외에는 목록에 있는 ID만 수락됩니다 — 각각 Matrix 사용자 ID, Mattermost 사용자 ID, Nextcloud 액터 ID.
전달 여부를 확인할 때는 allowed_users = ["*"]로 시작한 뒤 명시적 ID로 제한하십시오. Nextcloud Talk의 경우 액터 ID는 users/ / bots/ 접두사를 제거한 후 매칭됩니다.
관련 페이지
섹션 제목: “관련 페이지”- Mattermost 및 Nextcloud Talk 설정 — 단계별 봇 생성 및 웹훅 등록.
- Telegram 및 Matrix 설정 — E2EE 가이드를 포함한 Matrix 설정.
- 채널 개요 — 채널 트레이트, 전달 모드, 허용 목록 모델.
- 웹훅 인그레스 — 모든 게이트웨이 웹훅 엔드포인트 및 요청 서명.
- 터널로 게이트웨이 노출하기 — Nextcloud Talk 웹훅에 공개 HTTPS URL 제공.
- 음성, TTS 및 전사 — 이 채널들이 사용하는 오디오 첨부 파일 전사.
- Cargo 기능 플래그 및 ADR —
channel-matrix플래그 및 기타 빌드 옵션.