Mattermost 및 Nextcloud Talk 설정
자체 호스팅 팀 채팅 채널 설정: Mattermost 봇과 웹훅 기반 Nextcloud Talk 봇.
이 가이드는 Revka를 두 가지 자체 호스팅 팀 채팅 플랫폼인 Mattermost와 Nextcloud Talk에 연결하는 방법을 설명합니다. 두 플랫폼 모두 에이전트의 대화 기록을 사용자가 직접 관리하는 인프라 내에 보관하므로, 프라이버시가 중요하거나 규정 준수가 필요한 환경, 또는 에어갭 배포에 적합합니다. Mattermost 채널이나 Nextcloud Talk 룸에서 Revka 봇이 메시지를 읽고 응답하도록 하려면 이 페이지를 참고하세요.
두 통합 방식은 동작 방식이 서로 다릅니다:
- Mattermost는 봇 액세스 토큰을 사용하여 Mattermost REST API v4를 폴링합니다. 외부에서 접근 가능한 포트가 필요 없으며, Revka가 일정 주기로 새 게시물을 가져옵니다.
- Nextcloud Talk는 웹훅 모드로 동작합니다. Nextcloud가
POST /nextcloud-talk경로로 게이트웨이에 이벤트를 푸시하므로, 게이트웨이가 공개 HTTPS로 접근 가능해야 합니다.
채널 동작 방식에 대한 전체 개요는 채널 개요와 Matrix, Mattermost & Nextcloud Talk의 워크스페이스 채팅 레퍼런스를 참고하세요. 암호화된 룸 옵션에 대해서는 Telegram 및 Matrix 설정을 참고하세요.
두 채널 모두 ~/.revka/config.toml의 [channels_config] 아래에서 설정합니다. 파일을 직접 편집하거나 revka onboard --channels-only를 실행하여 대화형으로 설정할 수 있습니다. 변경 사항을 적용하려면 데몬을 재시작하세요.
Mattermost
섹션 제목: “Mattermost”Mattermost는 둘 중 더 간단한 방식입니다. 봇 계정을 생성하고, 채널 ID를 확인한 뒤, 두 값을 설정 파일에 입력하고 데몬을 실행하면 됩니다.
봇 계정 생성
섹션 제목: “봇 계정 생성”- Mattermost에서 메인 메뉴 → 통합 → 봇 계정을 엽니다.
- 봇 계정 추가를 클릭합니다.
- 사용자 이름을 설정합니다(예:
revka-bot). - 봇에게 게시 및 채널 읽기 권한을 부여합니다(예:
post:all및channel:read, 또는 서버에 맞는 동등한 스코프). - 생성된 액세스 토큰을 저장합니다. 이 값이
bot_token입니다. 토큰은 한 번만 표시됩니다.
채널 ID 찾기
섹션 제목: “채널 ID 찾기”- 봇이 모니터링할 채널을 엽니다.
- 헤더에서 채널 이름을 클릭하고 정보 보기를 선택합니다.
- ID 값(예:
7j8k9l...)을 복사합니다. 이 값이channel_id입니다.
channel_id는 리슨 모드에서 필수입니다. 생략하면 봇 계정이 접근할 수 있는 모든 채널을 리슨합니다.
Mattermost 설정
섹션 제목: “Mattermost 설정”~/.revka/config.toml에 다음 섹션을 추가합니다:
[channels_config.mattermost]url = "https://mm.your-domain.com"bot_token = "your-bot-access-token"channel_id = "your-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] 섹션이 설정되어 있으면 Mattermost에서도 오디오 첨부 파일을 텍스트로 변환합니다(오디오 파일 크기 제한 25 MB). 음성, TTS 및 텍스트 변환을 참고하세요.
스레딩 및 멘션 전용 동작
섹션 제목: “스레딩 및 멘션 전용 동작”- 사용자가 기존 스레드 내에서 답글을 보내면, Revka는 항상 해당 스레드에서 응답합니다.
thread_replies = true(기본값)이면 Revka가 최상위 메시지에 스레드로 답장합니다.thread_replies = false이면 채널 루트에서 답장합니다.mention_only = true이면 Revka는allowed_users확인 이후 추가 필터를 적용합니다. 봇 사용자 이름을@-멘션하지 않은 메시지는 무시되며, 멘션 토큰은 모델에 전달되기 전에 제거됩니다. 이 옵션은 사용량이 많은 공유 채널에서 불필요한 모델 호출을 줄이는 데 유용합니다.
채널 슈퍼바이저가 폴링을 시작하도록 전체 런타임을 실행합니다:
revka daemon대상 채널에 메시지를 보내고 봇이 응답하는지 확인합니다. 처음 테스트할 때는 allowed_users = ["*"]로 설정하고, 전달이 확인되면 명시적인 사용자 ID로 범위를 좁히세요.
Nextcloud Talk
섹션 제목: “Nextcloud Talk”Nextcloud Talk는 웹훅 봇 방식을 사용합니다. Nextcloud가 각 룸 이벤트를 게이트웨이로 전송하면, Revka가 서명을 검증하고 에이전트를 실행한 뒤 Nextcloud Talk OCS API를 통해 응답합니다. Nextcloud가 게이트웨이에 접근해야 하므로 공개 HTTPS URL이 필요합니다.
Nextcloud Talk 설정
섹션 제목: “Nextcloud Talk 설정”~/.revka/config.toml에 다음 섹션을 추가합니다:
[channels_config.nextcloud_talk]base_url = "https://cloud.example.com"app_token = "nextcloud-talk-app-token"bot_name = "revka"webhook_secret = "your-webhook-secret"allowed_users = ["*"]| 필드 | 타입 | 기본값 | 설명 |
|---|---|---|---|
base_url | string | — | Nextcloud 인스턴스 URL. 필수. 끝의 슬래시는 제거됩니다. |
app_token | string | — | 봇 앱 토큰. 아웃바운드 OCS 응답 시 Authorization: Bearer <token>으로 전송됩니다. 필수. |
bot_name | string | revka | 봇의 Talk 표시 이름. 셀프 에코 방지에 사용됩니다(아래 참고). |
webhook_secret | string | — | 인바운드 웹훅 서명 검증을 위한 공유 HMAC 시크릿. 권장. |
allowed_users | array | — | 허용된 Nextcloud 액터 ID 목록. []는 전체 거부, ["*"]는 전체 허용. |
proxy_url | string | — | 채널별 선택적 HTTP/SOCKS5 프록시. |
게이트웨이 노출 및 웹훅 등록
섹션 제목: “게이트웨이 노출 및 웹훅 등록”게이트웨이 또는 데몬을 실행한 다음, Nextcloud Talk 봇의 웹훅 URL을 게이트웨이의 인그레스 경로로 지정합니다:
revka daemonhttps://<your-public-url>/nextcloud-talk게이트웨이는 시작 시 등록된 라우트를 로그에 기록합니다(POST /nextcloud-talk — Nextcloud Talk bot webhook). Talk가 이벤트를 게이트웨이로 푸시하는 방식이므로, 게이트웨이는 공개 HTTPS로 접근 가능해야 합니다. 터널 설정은 터널로 게이트웨이 노출하기를, 공개 포트가 필요한 채널 목록은 네트워크 배포, Raspberry Pi 및 프록시를 참고하세요.
웹훅 인그레스 엔드포인트
섹션 제목: “웹훅 인그레스 엔드포인트”인바운드 웹훅은 게이트웨이의 공개 인그레스 서피스의 일부입니다(Bearer 토큰 없음 — 대신 서명으로 인증).
POST /nextcloud-talkContent-Type: application/jsonX-Nextcloud-Talk-Random: <random-seed>X-Nextcloud-Talk-Signature: <hmac-hex>| 응답 | 조건 |
|---|---|
404 | [channels_config.nextcloud_talk]가 설정되지 않은 경우. |
401 | 서명 검증 실패(시크릿이 설정된 경우에만 확인). |
200 | 수락됨. 페이로드에 처리 가능한 사용자 메시지가 없는 경우에도 반환됨(봇/시스템/허용되지 않은 이벤트는 자동으로 확인 응답). |
아웃바운드 응답은 웹훅 페이로드의 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 형식을 모두 처리하며, 밀리초 및 초 단위 타임스탬프를 모두 정규화합니다.
웹훅 서명 검증
섹션 제목: “웹훅 서명 검증”webhook_secret이 설정되면 모든 인바운드 요청은 HMAC-SHA256 서명으로 인증됩니다. Revka는 두 헤더를 읽고 다음을 계산합니다:
hex( hmac_sha256( secret, X-Nextcloud-Talk-Random + raw_request_body ) )결과는 X-Nextcloud-Talk-Signature 헤더와 상수 시간 비교를 통해 검증됩니다. 서명의 앞에 붙는 sha256= 접두사는 허용되며 제거됩니다. 대조는 재직렬화된 JSON 객체가 아니라 원시 요청 본문과 랜덤 시드를 기반으로 이루어지므로, Nextcloud와 게이트웨이 사이의 프록시에서 본문을 수정하지 마세요. 랜덤 헤더가 없거나 서명 형식이 잘못되었거나 다이제스트가 일치하지 않으면 게이트웨이는 401로 요청을 거부합니다.
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에 시크릿을 포함하지 않으려면 환경 변수를 사용하세요. 양쪽이 동일한 HMAC를 계산할 수 있도록 Nextcloud Talk 봇에도 동일한 시크릿을 설정해야 합니다.
bot_name 셀프 에코 방지
섹션 제목: “bot_name 셀프 에코 방지”웹훅 봇은 자신의 응답이 새 룸 이벤트로 다시 수신되는 에코 현상을 겪을 수 있습니다. 이를 방치하면 에이전트가 자기 자신에게 영원히 응답하는 피드백 루프가 발생합니다. Revka는 자기 발신 이벤트를 모델에 도달하기 전에 차단합니다:
- 액터 타입이
bots또는application인 이벤트는 무시됩니다. - 액터 ID에
bots/접두사가 있는 이벤트는 무시됩니다. - 액터 이름이 설정된
bot_name과 일치하는 이벤트는 무시됩니다(대소문자 구분 없음). 리터럴 이름revka는bot_name을 다르게 설정하더라도 항상 봇으로 처리됩니다.
이름 확인은 안전망 역할을 합니다. Nextcloud가 봇이 보낸 메시지에 대해 액터 타입을 항상 신뢰성 있게 설정하지는 않으므로, bot_name 매칭으로 타입 확인을 통과한 에코를 잡아냅니다. 이 필터가 정상 동작하려면 bot_name을 봇이 Talk에서 사용하는 정확한 표시 이름으로 설정하세요.
셀프 에코 및 이벤트 타입 필터 이후, allowed_users 허용 목록이 적용됩니다. 목록에 있는 액터 ID의 메시지만 처리됩니다(["*"]는 전체 허용). 액터 ID는 users/ 또는 bots/ 접두사를 제거한 후 비교됩니다.
- 첫 실행에서는
allowed_users = ["*"]로 설정합니다. - 대상 Talk 룸에 테스트 메시지를 보냅니다.
- Revka가 이벤트를 수신하고 같은 룸에서 응답하는지 확인합니다.
allowed_users를 명시적인 액터 ID로 좁힙니다.
트러블슈팅
섹션 제목: “트러블슈팅”- Mattermost: 응답 없음.
bot_token이 봇 계정의 액세스 토큰인지,url에 오타가 없는지, 발신자의 사용자 ID가allowed_users에 포함되어 있는지 확인하세요.mention_only = true이면@-멘션이 있는 메시지만 처리됩니다. - Nextcloud Talk:
404 Nextcloud Talk not configured.[channels_config.nextcloud_talk]섹션이 없거나 설정 파일 편집 후 데몬을 재시작하지 않은 경우입니다. - Nextcloud Talk:
401. 서명 검증 실패. 양쪽에 동일한 시크릿이 설정되어 있는지,X-Nextcloud-Talk-Random헤더가 전달되고 있는지, 전송 중 원시 요청 본문이 수정되지 않는지 확인하세요. - Nextcloud Talk: 웹훅이
200을 반환하지만 응답 없음. 이벤트가 필터링된 경우입니다. 봇/시스템 이벤트,Note타입이 아닌 객체, 파싱 불가능한 메시지, 또는allowed_users에 없는 발신자가 원인일 수 있습니다. 봇 자신의 메시지는 셀프 에코 필터에 의해 차단됩니다. - Nextcloud Talk: 봇이 자기 자신에게 응답함.
bot_name을 봇의 정확한 Talk 표시 이름으로 설정하여 셀프 에코 필터가 자신의 메시지를 인식할 수 있도록 하세요.
구조화된 진단은 revka doctor 또는 대시보드 Doctor 페이지를 사용하고, 채널 배선 확인은 revka channel doctor를 실행하세요.
관련 페이지
섹션 제목: “관련 페이지”- 메시징 채널 연결 — 일반적인 채널 설정 흐름 및 허용 목록 동작.
- Matrix, Mattermost & Nextcloud Talk — 워크스페이스 채팅 채널의 레퍼런스 상세.
- 웹훅 인그레스 — 모든 게이트웨이 웹훅 엔드포인트 및 요청 서명.
- 터널로 게이트웨이 노출하기 — Nextcloud Talk 웹훅에 공개 HTTPS URL 부여.
- revka channel & integrations —
revka channelCLI 명령어.