[Telegram]내 PC에서 돌리는 Telegram 알림 스케줄러 만들기 (Node.js + React + SQLite)

2026. 4. 7. 16:02·Programing
반응형
# 들어가며

"매일 아침 9시에 팀원들에게 데일리 스크럼 알림 보내기", "매주 금요일 주간보고 리마인더" — 이런 반복 알림, 어떻게 처리하고 계신가요?

별도 서버 없이, **내 PC에서 직접 돌리는 Telegram 알림 스케줄러**를 만들어 보았습니다. 클라우드 비용 0원, DB 서버 설치 0건. Node.js와 SQLite만으로 충분합니다.

---

## 이런 걸 만들었습니다

| 기능 | 설명 |
|------|------|
| 알림 CRUD | 등록 / 수정 / 삭제 / 테스트 발송 |
| 반복 유형 | 1회, 매시, 매일, 매주, 매월, 매년 |
| 캘린더 뷰 | 주간 / 월간 / 연간 시각화 |
| 실행 로그 | 발송 성공/실패 이력 조회 |
| 자동 복원 | 앱 재시작 시 활성 스케줄 자동 등록 |
| 다수 수신자 | Chat ID 콤마 구분으로 다중 전송 |
| 보안 헤더 | XSS, Clickjacking 등 기본 방어 적용 |

---

## 기술 스택

```
Frontend : React 19 + Vite
Backend  : Node.js + Express
Database : SQLite (better-sqlite3)
Scheduler: node-cron
API 통신  : axios
```

> SQLite를 선택한 이유 — MySQL이나 PostgreSQL 같은 외부 DB 없이 `.db` 파일 하나로 끝. 로컬 용도에는 이게 최고입니다.

---

## 프로젝트 구조

```
telegram-schedule/
├── server/
│   ├── index.js                    # 서버 진입점
│   ├── controllers/                # 요청 처리 (유효성 검증)
│   ├── routes/                     # REST API 라우팅
│   ├── services/
│   │   ├── telegramReminderService.js  # DB CRUD
│   │   └── telegramService.js          # Telegram API 연동
│   ├── scheduler/
│   │   └── telegramReminderScheduler.js # cron 기반 스케줄링
│   ├── db/sqlite.js                # SQLite 연결 & 테이블 초기화
│   └── lib/                        # 보안, 로깅, 에러코드 유틸
├── client/
│   ├── src/
│   │   ├── pages/
│   │   │   └── TelegramReminderAdminPage.jsx  # 메인 관리 화면
│   │   └── components/
│   │       ├── TelegramReminderForm.jsx   # 등록/수정 폼
│   │       ├── TelegramReminderList.jsx   # 목록 테이블
│   │       ├── CalendarView.jsx           # 캘린더 시각화
│   │       ├── LogModal.jsx               # 실행 로그 모달
│   │       └── Toast.jsx                  # 알림 토스트
│   └── dist/                       # 프로덕션 빌드
├── db/telegram_reminders.db        # SQLite DB 파일 (자동 생성)
├── logs/                           # 일별 로그 파일
└── .env                            # Bot Token 설정
```

---

## 핵심 설계 포인트

### 1. Cron 표현식 자동 생성

반복 유형에 따라 cron 표현식을 동적으로 빌드합니다.

```javascript
function buildCronExpression(reminder) {
  const [hour, minute] = reminder.time_value.split(':').map(Number);

  switch (reminder.repeat_type) {
    case 'hourly':
      // 매시 정각 ~ 지정 시간대까지
      return `${minute} ${startHour}-${endHour} * * *`;
    case 'daily':
      return `${minute} ${hour} * * *`;
    case 'weekly':
      return `${minute} ${hour} * * ${weekday}`;
    case 'monthly':
      return `${minute} ${hour} ${day} * *`;
    case 'yearly':
      return `${minute} ${hour} ${day} ${month} *`;
    case 'once':
      // 매일 체크하되, 날짜 일치 시에만 실행
      return `${minute} ${hour} * * *`;
  }
}
```

`once`(1회) 타입이 재미있는데요 — cron 자체는 매일 해당 시각에 트리거되지만, 실행 시점에 날짜를 비교해서 해당일에만 발송하고 자동 비활성화합니다.

### 2. 실패 시 지수 백오프 재시도

네트워크 불안정에 대비해 최대 3회 재시도하며, 대기 시간을 1초 → 2초 → 4초로 늘려갑니다.

```javascript
for (let attempt = 1; attempt <= maxRetries; attempt++) {
  const result = await sendTelegramMessage(chatId, formattedMsg);
  if (result.success) break;
 
  // 지수 백오프: 2^(attempt-1) * 1000ms
  const delayMs = Math.pow(2, attempt - 1) * 1000;
  await new Promise(resolve => setTimeout(resolve, delayMs));
}
```

### 3. 중복 실행 방지

`executingJobs` Set으로 동일 알림이 동시에 두 번 실행되는 것을 방지합니다. cron이 1분 간격이라 거의 발생하지 않지만, 전송 지연 시 다음 트리거와 겹칠 수 있어 방어 코드를 넣었습니다.

### 4. 앱 재시작 시 자동 복원

서버가 시작되면 DB에서 활성 상태인 알림을 모두 읽어와 cron job을 재등록합니다. 만료된 1회성 알림은 자동으로 비활성화 처리합니다.

```javascript
function restoreAllJobs() {
  const activeReminders = reminderService.getActiveReminders();
  for (const reminder of activeReminders) {
    if (reminder.repeat_type === 'once' && reminder.date_value < today) {
      reminderService.deactivateReminder(reminder.id);
      continue;
    }
    registerJob(reminder);
  }
}
```

---

## API 설계

RESTful하게 구성했습니다.

| Method | Endpoint | 설명 |
|--------|----------|------|
| GET | `/api/telegram-reminders` | 전체 목록 조회 |
| POST | `/api/telegram-reminders` | 알림 등록 |
| GET | `/api/telegram-reminders/:id` | 단건 조회 |
| PUT | `/api/telegram-reminders/:id` | 수정 |
| DELETE | `/api/telegram-reminders/:id` | 삭제 |
| PATCH | `/api/telegram-reminders/:id/active` | 활성/비활성 토글 |
| POST | `/api/telegram-reminders/test-send` | 테스트 발송 |
| GET | `/api/telegram-reminders/:id/logs` | 실행 로그 조회 |

---

## 실행 방법

### 사전 준비

- **Node.js 18+** 설치
- Telegram에서 [@BotFather](https://t.me/BotFather)로 봇 생성 → Bot Token 발급
- [@userinfobot](https://t.me/userinfobot)에게 메시지 → 내 Chat ID 확인

### 설치 & 실행

```bash
# 1. 의존성 설치 (서버 + 클라이언트 한 번에)
npm run setup

# 2. 환경 설정
# .env 파일에 Bot Token 입력
TELEGRAM_BOT_TOKEN=your_bot_token_here
PORT=3001

# 3-A. 프로덕션 모드
npm run build
npm start
# → http://localhost:3001

# 3-B. 개발 모드 (핫 리로드)
npm run dev
# → http://localhost:5173
```

---

## Google 캘린더에서 영감을 받다

반복 유형 설계 시 Google 캘린더의 일정 반복 옵션을 참고했습니다.

> 1회 / 매시 / 매일 / 매주 / 매월 / 매년 — 실무에서 쓰이는 대부분의 반복 패턴을 커버합니다.

캘린더 뷰도 주간·월간·연간 모드를 제공해서, 등록된 알림을 시각적으로 확인할 수 있습니다.

---

## 주의사항

- **로컬 전용**입니다. PC가 켜져 있고 앱이 실행 중일 때만 알림이 발송됩니다.
- PC 종료 시 알림이 밀리지만, 재시작하면 활성 스케줄이 자동 복원됩니다.
- 보안상 `.env` 파일의 Bot Token은 절대 외부에 노출하지 마세요.

---

## 마치며

"서버 없이 내 PC에서 Telegram 알림을 자동화하고 싶다"는 단순한 니즈에서 시작한 프로젝트입니다. SQLite 덕분에 별도 DB 설치가 필요 없고, `npm run setup` 한 줄이면 바로 사용할 수 있습니다.

개인 리마인더, 팀 알림, 정기 보고 리마인더 등 다양하게 활용해 보세요.

소스 코드는 GitHub에서 확인할 수 있습니다.
반응형
저작자표시 비영리 (새창열림)

'Programing' 카테고리의 다른 글

[framework]Express vs NestJS 비교 정리  (0) 2026.03.11
[IT 지식] Express.js란 무엇일까? 웹 개발의 핵심 구조 이해하기  (0) 2026.03.09
[날짜]공공데이터포털 API 키 발급 방법 (한국천문연구원 특일 정보)  (0) 2026.03.09
[Claude]실무에서 자주 보는 TypeScript 코드 작성 기준 정리  (0) 2026.03.03
[Python]파이썬 설치  (0) 2026.02.20
'Programing' 카테고리의 다른 글
  • [framework]Express vs NestJS 비교 정리
  • [IT 지식] Express.js란 무엇일까? 웹 개발의 핵심 구조 이해하기
  • [날짜]공공데이터포털 API 키 발급 방법 (한국천문연구원 특일 정보)
  • [Claude]실무에서 자주 보는 TypeScript 코드 작성 기준 정리
애플자라
애플자라
    반응형
  • 애플자라
    애플자라
    애플자라
  • 전체
    오늘
    어제
    • 분류 전체보기 (679)
      • 업무효율화★ (7)
      • Linux (93)
      • Programing (98)
      • Flex, Laszlo (15)
      • Database (170)
      • Network (19)
      • Data (14)
      • Tips (123)
      • 여행★ (1)
      • Board (116)
      • 맛집탐방 (3)
      • 아이원츄 (12)
  • 블로그 메뉴

    • 홈
    • 태그
    • 미디어로그
    • 위치로그
    • 방명록
  • 링크

    • Love&Smile
    • Husk's repository
    • StartUp
    • DSDSTUDIO Experimentals
    • 신선
    • DEV.SEULKI.KR[이슬기]
    • Live Bit Block
  • 공지사항

  • 인기 글

  • 태그

    Toad
    Linux
    Windows
    백업
    테이블
    server
    DB
    table
    sql
    select
    파일
    설정
    tomcat
    Excel
    mssql
    서버
    IP
    데이터
    엑셀
    apache
    날짜
    eclipse
    오라클
    Oracle
    delete
    윈도우
    MySQL
    DATABASE
    java
    리눅스
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
애플자라
[Telegram]내 PC에서 돌리는 Telegram 알림 스케줄러 만들기 (Node.js + React + SQLite)
상단으로

티스토리툴바