Telegram Send
Telegram 봇을 통해 음성, 사진, 문서 파일을 전송합니다 — Bot API 우선 전송 정책, 자동 채팅 ID 확인, 텍스트 알림 및 재시도를 위한 로컬 엔드포인트 폴백을 지원합니다.
기본 활성 커뮤니케이션
telegram-send는 모든 세션에 자동으로 주입됩니다. 수동 로딩이 필요 없습니다. "send via Telegram" 또는 "텔레그램으로 보내줘"라고 말하면 스킬이 활성화되고 에이전트가 이 페이지에 설명된 전송 정책을 따릅니다.
빠른 참조
| 스킬 이름 | telegram-send |
| 카테고리 | 커뮤니케이션 |
| 기본 활성 | 예 — 세션 시작 시 주입됨 |
| SKILL.md 경로 | ~/.cli-jaw/skills/telegram-send/SKILL.md |
| 시스템 도구 | curl, jq |
| 설정 소스 | ~/.cli-jaw/settings.json (telegram.token, telegram.allowedChatIds) |
| 기본 API | Telegram Bot API (https://api.telegram.org/bot<TOKEN>/...) |
| 폴백 API | 로컬 엔드포인트 (http://localhost:3457/api/telegram/send) |
| 지원 유형 | photo, voice, document, text |
| 관련 스킬 | email-draft-polish, whatsapp, xurl |
| 관련 가이드 | Telegram 가이드 |
전송 정책 (Bot 우선)
이 스킬은 엄격한 2단계 전송 전략을 따릅니다. Telegram Bot API가 항상 먼저 시도됩니다. 로컬 CLI-JAW 엔드포인트는 텍스트 전송의 편의 레이어 및 Bot API 실패 시 폴백 역할을 합니다.
| 메시지 유형 | 기본 방법 | 폴백 |
|---|---|---|
photo | Telegram Bot API (sendPhoto) | 로컬 엔드포인트 (1회 재시도) |
voice | Telegram Bot API (sendVoice) | 로컬 엔드포인트 (1회 재시도) |
document | Telegram Bot API (sendDocument) | 로컬 엔드포인트 (1회 재시도) |
text | 로컬 엔드포인트 (편의용) | Telegram Bot API (sendMessage) |
photo, voice, document 유형의 경우, 에이전트는 항상 직접 Bot API를 먼저 시도합니다. 로컬 엔드포인트는 Bot API 호출이 실패한 경우에만 1회 재시도 폴백으로 사용됩니다. text 상태 알림의 경우, 편의를 위해 로컬 엔드포인트가 먼저 사용됩니다.
필수 입력값
| 입력값 | 소스 | 필수 대상 |
|---|---|---|
| 봇 토큰 | ~/.cli-jaw/settings.json → telegram.token | 모든 Bot API 호출 |
| 채팅 ID | ~/.cli-jaw/settings.json → telegram.allowedChatIds[-1] | 모든 Bot API 호출 |
| 파일 경로 | 사용자가 제공하거나 이전 작업에서 생성됨 | photo, voice, document |
| 캡션 / 텍스트 | 사용자가 제공 (미디어의 경우 선택 사항) | text; 미디어의 경우 선택적 캡션 |
단계별 워크플로우
1단계: 토큰 및 채팅 ID 읽기
에이전트가 CLI-JAW 설정 파일에서 자격 증명을 읽습니다. 토큰은 셸 변수에만 보관되며 — stdout이나 로그에는 절대 출력되지 않습니다.
TOKEN=$(jq -r '.telegram.token' ~/.cli-jaw/settings.json)
CHAT_ID=$(jq -r '.telegram.allowedChatIds[-1]' ~/.cli-jaw/settings.json)
CHAT_ID가 null로 확인되는 경우(이전 Telegram 메시지 기록이 없는 경우), 에이전트는 로컬 엔드포인트에 핑을 보내 복구합니다:
CHAT_ID=$(curl -sS -X POST http://localhost:3457/api/telegram/send \
-H "Content-Type: application/json" \
-d '{"type":"text","text":"chat_id check"}' | jq -r '.chat_id')
2단계: Bot API로 전송 (기본)
에이전트는 메시지 유형에 따라 적절한 Telegram Bot API 엔드포인트로 curl 멀티파트 폼 POST를 구성합니다.
사진 전송
curl -sS -X POST "https://api.telegram.org/bot${TOKEN}/sendPhoto" \
-F "chat_id=${CHAT_ID}" \
-F "photo=@/tmp/chart.png" \
-F "caption=Analysis chart"
음성 메시지 전송
curl -sS -X POST "https://api.telegram.org/bot${TOKEN}/sendVoice" \
-F "chat_id=${CHAT_ID}" \
-F "voice=@/tmp/reply.ogg" \
-F "caption=Voice response"
문서 전송
curl -sS -X POST "https://api.telegram.org/bot${TOKEN}/sendDocument" \
-F "chat_id=${CHAT_ID}" \
-F "document=@/tmp/report.pdf" \
-F "caption=Weekly report"
3단계: 로컬 엔드포인트 (보조 / 폴백)
로컬 CLI-JAW 서버는 다음 경로에 Telegram 전송 엔드포인트를 노출합니다:
POST http://localhost:3457/api/telegram/send
Content-Type: application/json
허용 필드: type, text, file_path, caption
텍스트 메시지 (로컬 엔드포인트의 주요 용도)
curl -sS -X POST http://localhost:3457/api/telegram/send \
-H "Content-Type: application/json" \
-d '{"type":"text","text":"Deployment complete!"}'
로컬 엔드포인트를 통한 미디어 폴백
curl -sS -X POST http://localhost:3457/api/telegram/send \
-H "Content-Type: application/json" \
-d '{"type":"photo","file_path":"/tmp/chart.png","caption":"Analysis chart"}'
4단계: 전송 확인
전송 성공 시 "ok": true가 포함된 JSON 응답이 반환됩니다:
{"ok":true,"chat_id":8231528245,"type":"text"}
에이전트는 사용자에게 성공을 보고하기 전에 이 응답을 확인합니다. 응답이 실패를 나타내고 기본 방법이 Bot API였다면, 로컬 엔드포인트를 통해 1회 재시도가 수행됩니다.
지원되는 메시지 유형
| 유형 | Bot API 메서드 | 필수 필드 | 선택적 필드 |
|---|---|---|---|
photo | sendPhoto | chat_id, photo (파일) | caption, parse_mode |
voice | sendVoice | chat_id, voice (파일, OGG 형식) | caption, duration |
document | sendDocument | chat_id, document (파일) | caption, parse_mode |
text | sendMessage / 로컬 엔드포인트 | chat_id, text | parse_mode, disable_notification |
설정
이 스킬은 모든 설정을 ~/.cli-jaw/settings.json에서 읽습니다. 별도의 설정 파일은 필요하지 않습니다.
// ~/.cli-jaw/settings.json (관련 키)
{
"telegram": {
"token": "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11",
"allowedChatIds": [8231528245]
}
}
| 키 | 유형 | 설명 |
|---|---|---|
telegram.token | string | @BotFather에서 발급받은 Telegram Bot API 토큰 |
telegram.allowedChatIds | number[] | 허용된 채팅 ID 배열. 스킬은 기본적으로 마지막 항목을 사용합니다. |
allowedChatIds가 비어 있을 수 있습니다. 스킬은 로컬 엔드포인트를 통해 탐색 메시지를 전송하고 응답의 chat_id 필드를 읽어 채팅 ID를 자동으로 검색합니다.
의존성
이 스킬은 macOS 및 대부분의 Linux 배포판에 사전 설치된 표준 Unix 도구만 필요합니다.
macOS 및 Linux에 사전 설치됨
brew install jq
의존성 확인
# curl 확인
curl --version
# jq 확인
jq --version
# jq가 없는 경우 설치 (macOS)
brew install jq
# jq가 없는 경우 설치 (Ubuntu/Debian)
sudo apt-get install -y jq
보안 규칙
이 스킬은 토큰 처리에 대해 엄격한 보안 관행을 적용합니다:
| 규칙 | 세부 사항 |
|---|---|
| 토큰 출력 금지 | 봇 토큰은 절대 echo, print 또는 에이전트 텍스트 출력에 포함되지 않습니다. 셸 변수에만 존재합니다. |
| 셸 전용 저장 | 토큰은 $TOKEN에 읽혀져 인라인으로 사용됩니다. 임시 파일에 기록되거나 환경 변수로 내보내지지 않습니다. |
| 로그 유출 방지 | 명령은 -sS 플래그를 사용하여 진행률 표시를 억제하면서 오류는 계속 표시하여, 상세 로그에서 토큰이 실수로 노출되는 것을 방지합니다. |
| 단일 재시도 제한 | Bot API가 실패하면 로컬 엔드포인트를 통한 폴백 시도는 1회만 허용됩니다. 무한 재시도 루프는 없습니다. |
| 허용된 채팅 ID | 스킬은 telegram.allowedChatIds에 나열된 채팅 ID로만 전송하여, 무단 채팅으로의 실수 전송을 방지합니다. |
빠른 확인
Telegram 연동이 정상적으로 작동하는지 테스트하려면 다음 핑 명령을 실행하세요:
curl -sS -X POST http://localhost:3457/api/telegram/send \
-H "Content-Type: application/json" \
-d '{"type":"text","text":"ping"}'
예상 응답:
{"ok":true,"chat_id":8231528245,"type":"text"}
오류가 발생하면 다음을 확인하세요:
- CLI-JAW 서버가 실행 중인지 확인 (
jaw server status) ~/.cli-jaw/settings.json에 봇 토큰이 설정되어 있는지 확인- Telegram에서 봇에 최소 한 번 이상 메시지를 보냈는지 확인 (채팅을 설정하기 위해)
"~해줘" 사용 예시
자연어로 telegram-send 스킬을 트리거하는 실제 사용 예시입니다. 한국어와 영어 모두 사용 가능합니다.
sendPhoto 엔드포인트를 통해 사진으로 전송합니다. 에이전트가 현재 작업 컨텍스트에서 차트 파일을 찾아 자동으로 첨부합니다.sendVoice를 통해 전송합니다. TTS 생성이 가능한 경우 에이전트가 먼저 오디오를 생성한 후 전달합니다.sendDocument를 통해 주간 보고서 PDF를 문서로 전송합니다. 캡션은 파일에 대한 간단한 설명으로 설정됩니다. 에이전트는 output/pdf/ 또는 사용자가 지정한 경로에서 파일을 확인합니다.screen-capture 스킬 출력과 telegram-send를 결합합니다.다른 스킬과의 통합
telegram-send 스킬은 다중 스킬 워크플로우의 마지막 단계로 자주 사용됩니다. 출력 파일이나 상태 업데이트를 생성하는 모든 스킬과 자연스럽게 결합됩니다.
| 워크플로우 | 관련 스킬 | 예시 |
|---|---|---|
| 보고서 생성 + 전달 | pdf + telegram-send | "보고서 PDF 만들어서 텔레그램으로 보내줘" |
| 차트 + 알림 | dev-data + telegram-send | "매출 차트 만들어서 텔레그램에 공유해줘" |
| 스크린샷 캡처 + 전송 | screen-capture + telegram-send | "화면 찍어서 텔레그램으로 바로 보내줘" |
| 음성 답장 | video (TTS) + telegram-send | "이 내용 음성으로 변환해서 텔레그램에 보내줘" |
| 멀티 채널 브로드캐스트 | telegram-send + whatsapp + xurl | "이 공지사항 텔레그램, 왓츠앱, X 전부 보내줘" |
| 배포 알림 | cloudflare + telegram-send | "Workers 배포하고 결과 텔레그램으로 알려줘" |
API 참조
사용되는 Bot API 엔드포인트
| 엔드포인트 | 메서드 | 용도 |
|---|---|---|
/bot<TOKEN>/sendPhoto | POST (multipart/form-data) | 이미지 파일 전송 |
/bot<TOKEN>/sendVoice | POST (multipart/form-data) | OGG 음성 메시지 전송 |
/bot<TOKEN>/sendDocument | POST (multipart/form-data) | 모든 파일을 문서로 전송 |
/bot<TOKEN>/sendMessage | POST (application/json) | 텍스트 메시지 전송 (text 유형의 폴백) |
로컬 엔드포인트
| 엔드포인트 | 메서드 | 본문 |
|---|---|---|
http://localhost:3457/api/telegram/send | POST | {"type": "photo|voice|document|text", "text": "...", "file_path": "...", "caption": "..."} |
응답 형식
// 성공
{"ok": true, "chat_id": 8231528245, "type": "text"}
// 실패 (예시)
{"ok": false, "error": "Bot token not configured"}
문제 해결
채팅 ID가 null인 경우
jq -r '.telegram.allowedChatIds[-1]'이 null을 반환하면 봇이 아직 사용자로부터 메시지를 받지 못한 것입니다. 먼저 Telegram에서 봇에 아무 메시지나 보내면 채팅 ID가 설정에 기록됩니다. 또는 에이전트가 로컬 엔드포인트를 탐색하여 자동으로 복구합니다.
Bot API가 401 Unauthorized를 반환하는 경우
봇 토큰이 유효하지 않거나 만료되었습니다. @BotFather에서 새 토큰을 생성하고 ~/.cli-jaw/settings.json을 업데이트하세요.
Bot API가 400 Bad Request를 반환하는 경우
일반적인 원인:
- 잘못된 chat_id: 채팅 ID가 봇과의 활성 대화에 해당하지 않습니다.
- 파일이 너무 큼: Telegram Bot API는 업로드 파일 크기를 50 MB로 제한합니다. 더 큰 파일의 경우 청크 업로드를 처리할 수 있는 로컬 엔드포인트를 사용하세요.
- 음성 파일 형식 오류: 음성 메시지는 OPUS 인코딩의 OGG 형식이어야 합니다. 다른 오디오 형식은
document로 전송해야 합니다.
로컬 엔드포인트 연결 거부
CLI-JAW 서버가 실행되고 있지 않습니다. 다음 명령으로 시작하세요:
jaw server start
# 또는 상태 확인
jaw server status
jq를 찾을 수 없는 경우
설정 파일을 파싱하려면 jq를 설치하세요:
# macOS
brew install jq
# Ubuntu/Debian
sudo apt-get install -y jq
# 확인
jq --version
Telegram 가이드와의 비교
CLI-JAW 문서에서 Telegram은 두 곳에서 다루어집니다. 각각 다른 목적을 가지고 있습니다:
| 이 페이지 (스킬 참조) | Telegram 가이드 | |
|---|---|---|
| 초점 | telegram-send 스킬의 기술적 세부 사항 — API 명령, 전송 정책, 보안 규칙 | Telegram을 CLI-JAW에 연결하기 위한 전체 설정 가이드 |
| 대상 독자 | Telegram으로 전송할 때 에이전트가 정확히 무엇을 하는지 이해하고 싶은 사용자 | 처음으로 Telegram 연동을 설정하는 새 사용자 |
| 다루는 내용 | SKILL.md 내부 구조, Bot API 호출, 폴백 로직, 문제 해결 | 봇 생성, 토큰 설정, 초기 메시지 페어링, 대시보드 설정 |