| 텔레그램 포럼 토픽에 대한 1급 지원을 갖춘 Discourse Chat과 텔레그램 간의 실시간 양방향 브리지 | |
| GitHub - babylai/discourse-telegram-chat-bridge: Real-time two-way bridge between Discourse Chat and Telegram (design phase / POC) · GitHub | |
| Discourse에서 플러그인 설치 방법 |
기능
각 Discourse 채팅 채널은 텔레그램 채팅으로 매핑됩니다 — 일반 그룹이거나 토픽이 활성화된 슈퍼그룹의 특정 토픽일 수 있습니다. 한 쪽에 게시된 메시지는 1~2초 안에 다른 쪽에 표시됩니다.
| Discourse → Telegram | Telegram → Discourse | |
|---|---|---|
| 텍스트 (서식 포함) | ||
| 이모지 | ||
| 답장 | ||
| 수정 | ||
| 삭제 | ||
| 사진 | ||
| 기타 파일 | ||
| 스티커 | — |
- 작성자 표시: 봇은 어느 플랫폼에서도 사용자를 사칭할 수 없으므로, 메시지는 작성자를 굵은 글씨 접두사로 표시합니다 — Discourse에서는
**Maria:** hello, 텔레그램에서는 maria: 입니다. - 루프 안전: 브리지 자체에 의해 게시된 메시지는 다시 전송되지 않습니다.
- 멱등성 작업: 재시도와 웹훅 재전송으로 인해 중복 메시지가 생성되지 않습니다.
- レート 제한 인식: HTTP 429 발생 시 텔레그램이 요청한 대기 시간만큼 정확히 대기한 후 작업을 다시 큐에 넣습니다.
- 우아한 열화(Graceful degradation): Bot API 제한(다운로드 20MB / 업로드 50MB)을 초과한 파일은
[file omitted: name (size)]메모로 대체되며, 지원되지 않는 서식은 일반 텍스트로 열화됩니다. /id설정 명령: 봇이 볼 수 있는 어떤 그룹이나 토픽에서든/id를 입력하면 ID와 복사해서 바로 사용할 수 있는 매핑 행이 응답으로 표시됩니다.
알려진 제한 사항
- 텔레그램의 삭제는 Discourse로 동기화되지 않습니다 — 텔레그램 Bot API에는 삭제 이벤트가 없습니다. 이는 플랫폼의 제한 사항이며, 구성 문제가 아닙니다.
- 텔레그램은 봇이 자신의 메시지를 48시간 동안만 수정할 수 있도록 허용합니다; Discourse에서 오래된 메시지에 대한 수정은 텔레그램 쪽에 반영되지 않습니다.
- 리액션은 브리지되지 않습니다.
- Discourse 채팅 스레드는 텔레그램 토픽으로 매핑되지 않으며, 스레드 답장은 평탄하게(flat) 브리지됩니다.
구성
1. 텔레그램 봇 생성
- @BotFather를 통해 봇을 생성하고 토큰을 복사합니다.
- 개인 정보 모드 비활성화(
/setprivacy→ Disable)를 하십시오. 그렇지 않으면 봇은/commands만 볼 수 있습니다.
봇이 이미 그룹에 있는 경우, 제거하고 다시 추가해야 합니다 — 그렇지 않으면 기존 멤버십에는 변경 사항이 적용되지 않습니다. - 봇을 그룹에 관리자로 추가하십시오(삭제 동기화를 위해 메시지 삭제 권한이 필요합니다).
- 특정 토픽으로 브리지하려면 그룹 설정에서 토픽을 활성화하십시오.
2. 사이트 설정 구성 (관리자 → 플러그인 → Telegram Bridge): 플러그인을 활성화하고, 봇 토큰을 붙여넣으며, 무작위 웹훅 시크릿(예: openssl rand -hex 24)을 설정합니다.
3. 웹훅 등록 — 플러그인 자체의 클라이언트를 통해 가장 쉽습니다. 이 클라이언트는 올바른 allowed_updates를 설정해 줍니다:
cd /var/discourse
./launcher enter app
rails runner "puts DiscourseTelegramChatBridge::TelegramClient.new.set_webhook(
url: 'https://YOUR-SITE/telegram-bridge/webhook',
secret_token: SiteSetting.telegram_bridge_webhook_secret)"
allowed_updates는 플러그인 코드가 아니라 텔레그램에 저장된 웹훅 등록에 있습니다. 수동으로 등록할 때 edited_message를 생략하면 텔레그램은 수정 사항을 조용히 전달하지 않습니다.
4. 채널 매핑 — 각 그룹/토픽에서 /id를 입력한 후, 브리지할 채널별로 telegram_bridge_mappings에 한 줄씩 추가합니다:
chat_channel_id:telegram_chat_id:telegram_thread_id
Discourse 채널 ID는 채널 URL 끝에 있는 숫자입니다(/chat/c/<slug>/<id>); General 토픽이나 일반 그룹의 경우 톱 ID는 비워 두십시오. 모든 부팅 및 매핑 변경 시 플러그인은 브리지되는 내용을 확인하기 위해 grep할 수 있는 active mappings 요약 행을 하나 기록합니다.
5. 검증 — 각 방향으로 메시지를 보내십시오. 아무런 반응이 없다면 순서대로 확인하십시오: active mappings 로그 행, 웹훅 정보(get_webhook_info), 개인 정보 모드.
설정
| 이름 | 설명 |
|---|---|
telegram_bridge_enabled |
브리지의 마스터 온/오프 스위치. |
telegram_bridge_bot_token |
@BotFather가 발급한 텔레그램 Bot API 토큰 (비밀). |
telegram_bridge_webhook_secret |
수신 웹훅 요청에서 텔레그램의 X-Telegram-Bot-Api-Secret-Token 헤더와 대조하여 검증되는 시크릿 (비밀). |
telegram_bridge_mappings |
채널 매핑, 한 줄 하나: chat_channel_id:telegram_chat_id:telegram_thread_id (토픽 ID는 선택 사항). |
개인 정보 관련 참고: 브리지된 채널의 콘텐츠는 Discourse 인스턴스를 벗어나 텔레그램에 저장됩니다(그리고 그 반대도 마찬가지). 명시적으로 매핑 목록에 포함된 채널만 브리지되지만 — 해당 채널의 멤버들에게 이를 알려주십시오.
