🤔 또 다른 문제 발견!#
안녕하세요! Hugo 블로그 구축기 6편으로 돌아온 CoderRed입니다 😄
5편에서 드디어 댓글 시스템을 구축했잖아요? 이제 독자들이 댓글을 달 수 있게 되었어요! 🎉
그런데… 문제가 하나 더 있더라고요.
“언제 댓글이 달렸는지 어떻게 알지?” 🤦♂️
매번 https://comments.coderred.com 대시보드에 들어가서 확인할 수는 없잖아요. 특히 새벽에 댓글이 달렸는데 오후에 발견하면… 댓글 작성자분께 너무 죄송하죠.
그래서 오늘은 텔레그램으로 실시간 댓글 알림을 받는 시스템을 구축해봤어요! 진짜 이번엔 끝이라고 생각했는데… 또 4시간 넘게 삽질했네요 😅
📱 텔레그램 봇 만들기부터 시작!#
BotFather와의 첫 만남#
텔레그램에서 봇을 만들려면 @BotFather를 찾아가야 해요. 이름부터 뭔가 권위있어 보이죠? 😂
/newbot 명령어 입력
봇 이름: CoderRed Blog Bot
봇 사용자명: coderred_blog_bot
그러면 이런 식으로 봇 토큰을 받을 수 있어요:
123456789:ABCdefGHIjklMNOpqrsTUVwxyz
채팅 ID 찾기의 모험#
봇 토큰은 받았는데, 이제 어디로 메시지를 보낼지 알아야 하죠. 그게 바로 채팅 ID예요.
봇에게 아무 메시지나 보낸 다음, 이 URL에 접속하면 됩니다:
https://api.telegram.org/bot[봇토큰]/getUpdates
JSON 응답에서 chat.id
값을 찾으면 그게 제 채팅 ID! 간단하죠? 😊
🚀 웹훅 서버 구축 - Node.js의 힘#
이제 Cusdis에서 댓글이 달렸을 때 텔레그램으로 알림을 보내주는 웹훅 서버를 만들어야 해요.
프로젝트 구조 설계#
~/telegram-webhook/
├── Dockerfile
├── webhook-telegram.js
└── package.json (자동 생성)
Dockerfile 작성#
FROM node:18-alpine
WORKDIR /app
# package.json 생성 및 의존성 설치
RUN npm init -y && npm install express axios
# webhook 서버 파일 복사
COPY webhook-telegram.js .
EXPOSE 3001
CMD ["node", "webhook-telegram.js"]
웹훅 서버 코드의 핵심#
가장 중요한 webhook-telegram.js
파일이에요:
const express = require('express');
const axios = require('axios');
const app = express();
app.use(express.json());
const BOT_TOKEN = process.env.BOT_TOKEN;
const CHAT_ID = process.env.CHAT_ID;
app.post('/cusdis-telegram', async (req, res) => {
try {
console.log('📥 웹훅 요청 받음:', JSON.stringify(req.body, null, 2));
const { type, data } = req.body;
if (type === 'new_comment') {
const {
by_nickname,
by_email,
content,
page_title,
page_id,
approve_link
} = data;
// 댓글 URL 구성
const postUrl = `https://coderred.com/posts/${page_id}/`;
const message = `🔔 새 댓글 알림!
📝 **${page_title}**
👤 작성자: ${by_nickname}${by_email ? ` (${by_email})` : ''}
💬 댓글: ${content}
🔗 [포스트 보기](${postUrl})
⚡ [댓글 승인](${approve_link})
🎛️ [관리 대시보드](https://comments.coderred.com)`;
const telegramUrl = `https://api.telegram.org/bot${BOT_TOKEN}/sendMessage`;
await axios.post(telegramUrl, {
chat_id: CHAT_ID,
text: message,
parse_mode: 'Markdown',
disable_web_page_preview: false
});
console.log(`✅ 댓글 알림 전송 완료: ${by_nickname} → ${page_title}`);
}
res.status(200).send('OK');
} catch (error) {
console.error('❌ 텔레그램 알림 실패:', error);
res.status(500).send('Error');
}
});
app.listen(3001, '0.0.0.0', () => {
console.log('🤖 텔레그램 웹훅 서버 실행: http://0.0.0.0:3001');
});
🐳 Docker로 안전하게 배포하기#
보안을 고려한 컨테이너 실행#
여기서 중요한 건 포트를 외부에 노출하지 않는 것이에요! Cusdis와 같은 내부 네트워크에서만 통신하면 되거든요.
# 프로젝트 생성
mkdir -p ~/telegram-webhook && cd ~/telegram-webhook
# 파일들 생성 후...
# 빌드
docker build -t telegram-webhook .
# 포트 노출 없이 실행 (보안 강화!)
docker run -d \
--name telegram-webhook \
--restart unless-stopped \
--network npm_default \
-e BOT_TOKEN="123456789:ABCdefGHIjklMNOpqrsTUVwxyz" \
-e CHAT_ID="987654321" \
telegram-webhook
Cusdis 웹훅 설정#
Cusdis 대시보드(https://comments.coderred.com)에서:
- 사이트 선택 → Settings
- Webhook URL 입력:
http://telegram-webhook:3001/cusdis-telegram
여기서 localhost
가 아니라 telegram-webhook
를 쓰는 게 중요해요!
🎉 마법 같은 실시간 알림!#
이제 누군가 댓글을 달면 이런 알림이 바로 텔레그램으로 와요:
🔔 새 댓글 알림!
📝 Hugo 블로그 구축기 5편 - 댓글 시스템 구축 대작전
👤 작성자: 개발자김씨 ([email protected])
💬 댓글: CORS 에러 해결 과정이 너무 리얼하네요!
🔗 포스트 보기
⚡ 댓글 승인
🎛️ 관리 대시보드
💻 프로젝트: coderred.com
⚡ 댓글 승인 링크를 누르면 바로 댓글이 승인돼요! 원클릭이라니… 감동 😭
🔥 또 발생한 문제들과 해결책#
문제 1: BOT_TOKEN이 인식 안 됨#
처음엔 환경변수가 제대로 전달되지 않았어요.
# 환경변수 확인
docker exec telegram-webhook printenv | grep -E "(BOT_TOKEN|CHAT_ID)"
알고 보니 -e
옵션에서 따옴표 처리를 잘못했더라고요.
문제 2: 웹훅 URL 접근 실패#
Cusdis에서 http://localhost:3001/cusdis-telegram
으로 설정했는데 안 되더라고요.
해결: Docker 네트워크 내에서는 컨테이너 이름으로 접근해야 함!
http://telegram-webhook:3001/cusdis-telegram
문제 3: 텔레그램 API 에러#
가끔 텔레그램 API에서 메시지가 너무 길다고 에러가 나더라고요. 댓글 내용을 적절히 자르는 로직을 추가했어요.
🎨 추가로 개선한 것들#
iframe 높이 자동 조정#
5편에서 만든 댓글창이 고정 높이라 스크롤바가 생기는 게 거슬렸어요. JavaScript로 동적 조정 기능을 추가했습니다:
<script>
document.addEventListener('DOMContentLoaded', function() {
function adjustIframeHeight() {
const iframe = document.querySelector('#cusdis_thread iframe');
if (iframe) {
try {
const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
const height = iframeDoc.body.scrollHeight;
const adjustedHeight = Math.max(400, Math.min(height + 50, 1000));
iframe.style.height = adjustedHeight + 'px';
} catch (e) {
iframe.style.height = '500px';
}
}
}
// iframe 감지 및 주기적 조정
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.addedNodes.length > 0) {
const iframe = mutation.target.querySelector('iframe');
if (iframe) {
iframe.addEventListener('load', () => {
setTimeout(adjustIframeHeight, 500);
});
setInterval(adjustIframeHeight, 2000);
}
}
});
});
const cusdisContainer = document.getElementById("cusdis_thread");
if (cusdisContainer) {
observer.observe(cusdisContainer, {
childList: true,
subtree: true
});
}
});
</script>
이제 댓글 개수에 따라 iframe 높이가 자동으로 조정돼요! 😊
GitHub Actions 안정화#
또 하나 발견한 문제는 GitHub Actions에서 YAML multiline 때문에 Docker 명령어가 실패하는 거였어요.
# ❌ 문제 버전 (줄바꿈으로 분리됨)
docker run -d \
--name hugo-blog \
nginx:alpine
# ✅ 해결 버전 (한 줄로 작성)
docker run -d --name hugo-blog --restart unless-stopped --network npm_default -p 9572:80 -v ~/coderblog/public:/usr/share/nginx/html:ro nginx:alpine
이것 때문에 몇 번 배포가 실패했어요 😅
🔧 유용한 명령어들#
텔레그램 웹훅 관리#
# 컨테이너 재빌드
cd ~/telegram-webhook
docker stop telegram-webhook && docker rm telegram-webhook
docker build -t telegram-webhook .
docker run -d --name telegram-webhook --restart unless-stopped \
--network npm_default \
-e BOT_TOKEN="봇토큰" -e CHAT_ID="채팅ID" \
telegram-webhook
# 로그 실시간 모니터링
docker logs telegram-webhook --follow
# 직접 텔레그램 API 테스트
curl -X POST "https://api.telegram.org/bot[봇토큰]/sendMessage" \
-H "Content-Type: application/json" \
-d '{"chat_id": "[채팅ID]", "text": "테스트 메시지"}'
전체 시스템 상태 확인#
# 모든 컨테이너 확인
docker ps | grep -E "(hugo-blog|cusdis|npm|telegram)"
# 네트워크 연결 테스트
docker exec cusdis ping telegram-webhook
🚨 트러블슈팅 가이드#
텔레그램 알림이 안 올 때#
- 웹훅 컨테이너 확인:
docker ps | grep telegram-webhook
- 웹훅 로그 확인:
docker logs telegram-webhook --follow
- 환경변수 확인:
docker exec telegram-webhook printenv | grep -E "(BOT_TOKEN|CHAT_ID)"
- Cusdis 웹훅 URL 확인:
http://telegram-webhook:3001/cusdis-telegram
- 네트워크 연결 테스트:
docker exec cusdis ping telegram-webhook
봇 토큰이나 채팅 ID 문제#
# 직접 API 테스트로 확인
curl -X POST "https://api.telegram.org/bot[봇토큰]/sendMessage" \
-H "Content-Type: application/json" \
-d '{"chat_id": "[채팅ID]", "text": "테스트"}'
🎯 이제 정말 완전체!#
드디어 완성됐어요! 이제 블로그 운영이 이렇게 간단해졌답니다:
📝 포스트 작성 → 📤 Git 푸시 → 🚀 자동 배포
↓
💬 독자 댓글 작성 → 📱 텔레그램 알림 → ⚡ 원클릭 승인
정말로 포스트 쓰고 푸시만 하면 끝인 시스템이 완성되었어요! 🎉
달성한 것들#
- ✅ GitHub 계정 없이 댓글 작성 가능
- ✅ 실시간 텔레그램 알림
- ✅ 원클릭 댓글 승인
- ✅ iframe 높이 자동 조정
- ✅ 완전 자동화된 배포 시스템
- ✅ 안정적인 Docker 네트워킹
소요 시간 총 정리#
- 1편 (환경 설정): 3시간
- 2편 (삽질 해결): 2시간
- 3편 (GitHub Actions): 3시간
- 4편 (Google Analytics): 1시간
- 5편 (댓글 시스템): 4시간
- 6편 (텔레그램 알림): 4시간
총 17시간의 여정이었네요! 😅
📈 앞으로의 계획#
이제 정말 블로그 시스템은 완성됐으니, 앞으로는:
- 📊 더 많은 기술 글 쓰기
- 💰 주식 투자 경험담 공유
- 🔍 검색 기능 추가 (언젠가…)
- 🎨 디자인 개선 (CSS 공부 중…)
댓글로 어떤 주제를 더 다뤘으면 좋겠는지 알려주세요! 이제 실시간으로 알림이 와서 바로바로 답변드릴 수 있어요 😄
다음 편에서는 뭘 다룰까요? 아마 실제 블로그 운영 경험이나 새로운 기술 도전기가 될 것 같아요!
함께 성장해나가요! 🚀