MINARA
Minara 사용하기클라이언트 및 인터페이스메시징 플랫폼

Telegram

권장 시작 지점. 3분 설정, 스트리밍 지원 게이트웨이, 가장 많이 검증된 공급자.

🟢 런타임 준비 완료. 이 게이트웨이는 스트리밍 편집 기능을 갖추고 출시되었습니다(아직 프로덕션 호출자가 연결되지 않은 상태입니다. 아래를 참조하세요). 대부분의 Minara 운영자가 처음 시작하는 공급자이며, 외부 바이너리나 비즈니스 계정 승인 없이 봇 토큰과 채팅 id만 있으면 됩니다.

제공 기능

  • 스트리밍 편집(게이트웨이 준비 완료). TelegramGateway는 플레이스홀더를 게시한 뒤 텍스트가 도착할 때마다 750ms 간격으로 편집합니다. apps/agent/src/messaging/stream-helpers.tscreateStreamSink를 통해 구동하세요. send_message 도구 자체는 단발성입니다.
  • 리치 텍스트(기본 켜짐). Markdown 응답이 Telegram 서식(굵게, 제목, 표, 작업 목록, 코드 블록)으로 렌더링됩니다. 일반 텍스트로 보내려면 TELEGRAM_RICH_TEXT=false로 설정하세요.
  • 첨부 파일. 이미지(sendPhoto), 파일(sendDocument), 음성 메모(sendVoice, OGG/Opus 필수), 오디오(sendAudio)를 지원합니다. 소스는 Agent가 샌드박스 내에서 생성한 파일이어야 합니다(자세한 내용은 개요 페이지를 참조하세요).
  • 그룹 및 1:1 채팅. 두 경우 모두 동일한 흐름을 사용합니다. 그룹 채팅 id는 음수입니다.
  • 메시지당 4,096자 제한. send_message는 도구 경계에서 더 긴 텍스트를 거부하며, 스트림 싱크는 스트리밍 도중 … (truncated) 표시와 함께 텍스트를 자릅니다.

설정

1. 봇 생성

  1. Telegram을 열고 @BotFather를 찾습니다.
  2. /newbot을 전송하고 안내에 따라 이름과 사용자명을 입력합니다.
  3. BotFather가 제공하는 토큰을 저장합니다(예: 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11).

2. 채팅 id 확인

  1. 새 봇과 채팅을 시작하고 메시지를 전송합니다. 채팅이 먼저 연락을 시작하지 않으면 Telegram이 봇의 메시지를 차단합니다.
  2. 브라우저에서 https://api.telegram.org/bot<TOKEN>/getUpdates를 열고 응답에서 "chat":{"id":...}를 찾습니다.

그룹의 경우, 봇을 그룹에 추가하고 그룹에서 메시지를 전송한 뒤 getUpdates를 확인합니다. 그룹 id는 음수입니다(예: -1001234567890).

3. Minara 설정

간편한 방법. 채팅에서 Agent에게 요청합니다.

"set up Telegram notifications"

Minara가 토큰과 채팅 id를 묻고, ~/.minara/credentials.json(messaging 슬롯)에 기록한 뒤 테스트 핑을 실행합니다.

수동 방법:

minara auth messaging add telegram

또는 프로젝트 루트의 .env 파일에 환경 변수를 직접 설정합니다.

TELEGRAM_BOT_TOKEN=123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
TELEGRAM_CHAT_ID=-1001234567890

4. 테스트

minara auth messaging test telegram

1~2초 내에 핑 메시지가 수신되어야 합니다.

스트리밍 동작

Telegram의 editMessageText 엔드포인트는 속도 제한에 걸리지 않고 메시지당 최대 약 30회 편집을 허용합니다. TelegramGateway는 플레이스홀더를 게시하고 새 텍스트가 도착할 때마다 편집하는 startStream() 세션을 제공합니다. createStreamSink는 해당 편집을 750ms 간격으로 조절합니다. 이는 실시간처럼 느껴질 만큼 빠르면서도 채팅별 제한을 충분히 여유 있게 유지합니다. 누적 텍스트가 4,096자를 초과하면 스트리밍 도중 … (truncated) 표시와 함께 잘립니다.

조절 간격 및 길이 재정의는 createStreamSink(gw, msg, { intervalMs, maxLength })의 호출자 측 옵션이며, send_message의 인수가 아닙니다. 도구 경로 자체는 단발성입니다. LLM은 완전히 구성된 메시지를 전송하며, 스트리밍은 워크플로/Autopilot 코드에 존재합니다(아직 프로덕션에 연결되지 않았습니다).

리치 텍스트

응답은 기본적으로 Telegram 리치 텍스트로 렌더링됩니다. Agent가 Markdown을 생성하면 게이트웨이가 전송 전에 이를 Telegram이 지원하는 HTML 하위 집합으로 변환합니다.

  • 제목은 굵게 표시되고, 목록은 글머리 기호를 유지하며, 작업 목록은 ☐ / ☑로, 표는 고정폭 정렬로, 코드 블록은 언어 라벨을 유지합니다.
  • Telegram이 HTML을 거부하면(드묾) 게이트웨이가 같은 내용을 MarkdownV2로 재시도한 뒤 일반 텍스트로 폴백합니다. 서식 오류로 메시지가 사라지지 않습니다.
  • 스트리밍 중에는 각 편집이 닫힌 서식만 표시하므로, 확정되기 전에 **bold 같은 미완성 서식이 깜빡이지 않습니다.

끄면 Agent의 텍스트를 그대로 보냅니다.

TELEGRAM_RICH_TEXT=false

"끄기"로 인식하는 값은 0, false, no, off이며, 설정하지 않으면 켜진 상태입니다. 이 설정은 시작 시 한 번만 읽으므로 변경 후 게이트웨이를 재시작하세요. 웹 UI의 설정 → 메시징 동작 → Telegram 리치 텍스트에서도 전환할 수 있습니다.

첨부 파일

첨부 파일은 Agent가 샌드박스 내에서 이미 생성한 파일을 참조합니다(image_generate, audio_generate, write_file, 코드 실행 등을 통해 생성). LLM은 샌드박스 상대 경로를 전달합니다.

send_message({
  provider: "telegram",
  text: "BTC/USD daily, key levels marked",
  attachments: [
    { kind: "image", sandbox_path: "images/btc-2026-04-19.png" },
  ],
})

종류별 라우팅:

kindTelegram 엔드포인트비고
imagesendPhoto캡션 지원
filesendDocument임의 파일 형식
voicesendVoiceOGG/Opus 필수, OGG가 아닌 형식은 거부됨
audiosendAudiomp3 / m4a / flac, 음악 스타일 플레이어 UI

여러 첨부 파일은 순차 메시지로 전송됩니다. 첫 번째 메시지는 msg.text가 충분히 짧으면(1,024자 이하) 캡션으로 포함됩니다. 그렇지 않으면 텍스트가 별도의 선행 메시지로 전송되고 첨부 파일이 그 아래에 연결됩니다. 자세한 내용은 apps/agent/src/messaging/telegram.ts를 참조하세요.

채널 재정의

긴급 알림은 다른 채팅으로 라우팅하면서 일반 알림은 기본값을 유지할 수 있습니다.

send_message({
  provider: "telegram",
  channel: "-1009876543210",
  text: "Critical: position liquidation imminent",
})

문제 해결

"테스트 메시지가 수신되지 않음"

  • 봇에게 먼저 메시지를 보냈습니까? 채팅이 먼저 연락을 시작하지 않으면 Telegram이 메시지를 차단합니다.
  • TELEGRAM_CHAT_ID의 부호를 확인하세요. 그룹 채팅은 음수입니다.
  • 봇이 그룹에 여전히 있는지 확인하세요. BotFather에서 해당 봇을 선택한 뒤 Bot SettingsGroup Privacy를 확인합니다.

"스트리밍이 느리거나 끊김"

  • 예상된 동작입니다. TelegramGateway 내부의 기본 조절 간격은 750ms입니다. 호출자 코드에서 createStreamSink(gw, msg, { intervalMs: 500 })으로 재정의할 수 있습니다. 이는 호출자 측 옵션이며 send_message 도구 인수가 아닙니다.
  • 매우 긴 응답은 4,096자에서 잘립니다. 워크플로를 여러 메시지로 분할하는 것을 고려하세요.

"Chat not found (400)"

  • 봇이 그룹에서 제거되었거나 채팅 id가 잘못된 경우입니다.
  • 대상 채팅에서 새 메시지를 전송한 뒤 getUpdates 단계를 다시 실행하세요.

참조

목차