업비트 알림봇 만들기 4편 - 텔레그램 연동
텔레그램 봇 토큰이랑 챗 ID를 실수로 깃허브에 올려서 낭패 본 적 있어요. 봇이 스팸 메시지 보내는 데 악용당했더라고요. 그 이후로 환경 변수 관리 진짜 철저하게 하고 있어요.
3편에서 업비트 API로 가격 데이터를 가져오고 알림 조건까지 체크하는 로직을 만들었죠? 이번 편에서는 진짜 텔레그램으로 알림을 보내고, 스케줄러로 자동 실행되게 만들 거예요.
텔레그램 Bot API 이해하기
텔레그램 봇은 HTTP API로 동작해요. 메시지를 보내려면 이 URL로 POST 요청을 보내면 돼요:
https://api.telegram.org/bot{토큰}/sendMessage
필요한 파라미터는 두 개예요:
chat_id: 메시지 받을 채팅방 IDtext: 보낼 메시지 내용
Chat ID 알아내기
1편에서 봇을 만들었다면 이제 Chat ID를 알아내야 해요.
1. 봇에게 먼저 말 걸기
텔레그램에서 내가 만든 봇을 찾아서 /start를 보내세요. 봇이 먼저 연락할 수는 없거든요.
2. getUpdates로 Chat ID 확인
브라우저에서 이 URL을 열어보세요 (토큰은 본인 걸로):
https://api.telegram.org/bot123456789:ABCdefGHI.../getUpdates
저기 나오는 chat.id 값을 메모해두세요. 이게 메시지 보낼 때 필요한 Chat ID예요.
테스트 메시지 보내기
Chat ID를 알았으면 코드로 메시지를 보내볼게요. src/index.js를 수정하세요:
// 텔레그램 메시지 전송 함수
async function sendTelegramMessage(botToken, chatId, message) {
const url = `https://api.telegram.org/bot${botToken}/sendMessage`;
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
chat_id: chatId,
text: message,
parse_mode: 'HTML',
}),
});
return response.json();
}
export default {
async fetch(request, env, ctx) {
// 테스트 메시지 전송
const result = await sendTelegramMessage(
env.TELEGRAM_BOT_TOKEN,
env.TELEGRAM_CHAT_ID,
'🔔 <b>테스트 알림</b>\n업비트 알림봇이 정상 작동 중입니다!'
);
return new Response(JSON.stringify(result, null, 2), {
headers: { 'Content-Type': 'application/json' },
});
},
};
환경 변수 설정하기
토큰이랑 Chat ID를 코드에 직접 넣으면 안 되겠죠? 환경 변수로 관리할 거예요.
로컬 개발용: .dev.vars 파일
프로젝트 루트에 .dev.vars 파일을 만드세요:
TELEGRAM_BOT_TOKEN=123456789:ABCdefGHIjklMNOpqrSTUvwxYZ
TELEGRAM_CHAT_ID=987654321
이 파일은 절대 git에 올리면 안 돼요! .gitignore에 추가하세요:
.dev.vars
배포용: Cloudflare 대시보드
실제 배포할 때는 Cloudflare 대시보드에서 설정해야 해요.
- dash.cloudflare.com 접속
- Workers & Pages → 프로젝트 선택
- Settings → Variables → Add variable
또는 wrangler CLI로도 가능해요:
wrangler secret put TELEGRAM_BOT_TOKEN
wrangler secret put TELEGRAM_CHAT_ID

전체 코드 합치기
지난 편의 가격 체크 로직과 텔레그램 전송을 합쳐볼게요:
// 텔레그램 메시지 전송
async function sendTelegramMessage(botToken, chatId, message) {
const url = `https://api.telegram.org/bot${botToken}/sendMessage`;
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
chat_id: chatId,
text: message,
parse_mode: 'HTML',
}),
});
return response.json();
}
// 알림 조건 체크
function checkAlertConditions(ticker) {
const alerts = [];
const changeRate = ticker.change_rate * 100;
if (ticker.change === 'RISE' && changeRate >= 5) {
alerts.push(`🚀 <b>${ticker.market}</b> 급등! +${changeRate.toFixed(2)}%`);
}
if (ticker.change === 'FALL' && changeRate >= 5) {
alerts.push(`📉 <b>${ticker.market}</b> 급락! -${changeRate.toFixed(2)}%`);
}
return alerts;
}
// 코인 가격 조회 및 알림 전송
async function checkAndNotify(env) {
const markets = 'KRW-BTC,KRW-ETH,KRW-XRP,KRW-DOGE';
const response = await fetch(
`https://api.upbit.com/v1/ticker?markets=${markets}`
);
const tickers = await response.json();
const allAlerts = [];
for (const ticker of tickers) {
const alerts = checkAlertConditions(ticker);
allAlerts.push(...alerts);
}
// 알림이 있으면 텔레그램으로 전송
if (allAlerts.length > 0) {
const message = `⏰ ${new Date().toLocaleString('ko-KR')}\n\n${allAlerts.join('\n')}`;
await sendTelegramMessage(
env.TELEGRAM_BOT_TOKEN,
env.TELEGRAM_CHAT_ID,
message
);
}
return {
checked_at: new Date().toISOString(),
alerts_count: allAlerts.length,
alerts: allAlerts,
};
}
export default {
// HTTP 요청 핸들러
async fetch(request, env, ctx) {
try {
const result = await checkAndNotify(env);
return new Response(JSON.stringify(result, null, 2), {
headers: { 'Content-Type': 'application/json' },
});
} catch (error) {
return new Response(JSON.stringify({ error: error.message }), {
status: 500,
headers: { 'Content-Type': 'application/json' },
});
}
},
// 스케줄러 핸들러 (나중에 추가)
async scheduled(event, env, ctx) {
await checkAndNotify(env);
},
};
로컬에서 테스트해보세요:
npm run dev
브라우저에서 http://localhost:8787 열면 체크 결과가 나오고, 조건에 맞으면 텔레그램으로 메시지가 와요.
스케줄러 설정하기
지금은 URL에 접속해야 체크가 되잖아요. 자동으로 돌아가게 Cron Trigger를 설정해볼게요.
wrangler.toml 수정
name = "upbit-telegram-bot"
main = "src/index.js"
compatibility_date = "2024-01-01"
[triggers]
crons = ["*/5 * * * *"]
*/5 * * * *는 5분마다 실행한다는 뜻이에요. Cron 표현식인데요:
| 표현식 | 의미 |
|---|---|
*/5 * * * * | 5분마다 |
*/10 * * * * | 10분마다 |
0 * * * * | 매시 정각 |
0 9 * * * | 매일 오전 9시 (UTC) |
주의: Cloudflare Workers는 UTC 기준이에요. 한국 시간으로 오전 9시에 실행하려면 0 0 * * *로 설정해야 해요 (UTC 0시 = KST 9시).
로컬에서 스케줄러 테스트
wrangler dev --test-scheduled
다른 터미널에서:
curl "http://localhost:8787/__scheduled?cron=*/5+*+*+*+*"
스케줄러가 실행되는 걸 확인할 수 있어요.
최종 배포
모든 게 준비됐으면 배포할게요:
npm run deploy
배포 후 환경 변수 설정 잊지 마세요:
wrangler secret put TELEGRAM_BOT_TOKEN
# 토큰 입력
wrangler secret put TELEGRAM_CHAT_ID
# Chat ID 입력
동작 확인
배포가 끝나면:
- 즉시 테스트: 배포된 URL에 접속해서 응답 확인
- 스케줄러 확인: Cloudflare 대시보드 → Workers → Logs에서 Cron 실행 기록 확인
- 텔레그램 확인: 조건 만족 시 메시지가 오는지 확인
알림 메시지 꾸미기
텔레그램은 HTML 태그를 일부 지원해요. 메시지를 좀 더 예쁘게 만들 수 있어요:
const message = `
⏰ <b>업비트 알림</b>
${new Date().toLocaleString('ko-KR')}
🚀 <b>KRW-BTC</b> 급등!
현재가: 140,500,000원
변동률: +5.23%
<i>5분 간격 자동 체크 중</i>
`;
지원하는 태그:
<b>굵게</b><i>기울임</i><u>밑줄</u><code>코드</code><a href="URL">링크</a>
정리
이번 편에서 한 것:
- 텔레그램 Bot API로 메시지 전송
- Chat ID 알아내기
- 환경 변수로 토큰 관리
- 전체 코드 통합
- Cron Trigger로 자동 실행
- Cloudflare Workers 배포
이제 진짜 24시간 자동으로 돌아가는 알림봇이 완성됐다. 다음 편에서는 보너스로 간단한 대시보드를 만들어서 현재 가격을 웹에서 볼 수 있게 해본다.
운영자 실전 노트
실제 프로젝트 진행하며 겪은 문제
- 텔레그램 봇 토큰 보안 → .dev.vars 파일 git 제외, Cloudflare 환경 변수 활용
- 메시지 포맷팅 오류 → HTML 태그 사용 시 닫는 태그 누락 주의
이 경험을 통해 알게 된 점
- Cron 표현식은 UTC 기준이라 한국 시간 -9시간 계산 필요
- 환경 변수 누출은 토큰 재발급으로 즉시 대응해야 한다