Supabase와 React를 활용한 매일 Python 레슨 텔레그램 봇 구축

발행: (2025년 12월 17일 오후 05:45 GMT+9)
8 min read
원문: Dev.to

Source: Dev.to

위에 있는 Source 라인은 그대로 두고, 번역하고 싶은 본문 내용을 알려주시면 한국어로 번역해 드리겠습니다.

Introduction

매일 텔레그램을 통해 사용자에게 짧은 파이썬 레슨을 보내는 웹 애플리케이션을 상상해 보세요.
SupabaseReact 같은 최신 도구를 사용하면 프론트엔드, 백엔드, 텔레그램 봇을 결합하여 이를 손쉽게 만들 수 있습니다. 이번 튜토리얼에서는 다음을 단계별로 살펴봅니다:

  1. 애플리케이션 설계
  2. 봇 만들기
  3. Supabase와 통합하기
  4. React 프론트엔드와 연결하기

1단계: 애플리케이션 설계

기능

  • 텔레그램을 통해 매일 파이썬 레슨 제공.
  • 사용자는 앱에서 레슨 진행 상황을 추적합니다.
  • 사용자는 알림을 설정할 수 있습니다(활성화/비활성화, 전송 시간, 텔레그램 사용자명).

데이터베이스 테이블

lessons

create table public.lessons (
    id uuid primary key default gen_random_uuid(),
    day_index int not null unique,
    title text not null,
    content text,
    example_code text,
    challenge text,
    created_at timestamptz default now()
);

user_progress

create table public.user_progress (
    id uuid primary key default gen_random_uuid(),
    user_id uuid references auth.users(id) on delete cascade,
    lesson_id uuid references lessons(id) on delete cascade,
    completed boolean default false,
    completed_at timestamptz
);

user_notifications

create table public.user_notifications (
    id uuid primary key default gen_random_uuid(),
    user_id uuid references auth.users(id) on delete cascade,
    channel text not null,               -- 'telegram', 'email'
    enabled boolean default true,
    delivery_time time not null,
    timezone text default 'UTC',
    created_at timestamptz default now(),
    updated_at timestamptz default now()
);

user_telegram

create table public.user_telegram (
    id uuid primary key default gen_random_uuid(),
    user_id uuid references auth.users(id) on delete cascade unique,
    telegram_chat_id bigint,
    activation_code int not null,
    status text default 'pending',        -- pending | connected
    created_at timestamptz default now(),
    updated_at timestamptz default now()
);

단계 2: 텔레그램 봇 만들기

  1. 텔레그램을 열고 BotFather를 검색합니다.
  2. /newbot을 전송하고 안내에 따라 진행합니다.
  3. 이름과 사용자명을 선택하면 BotFather가 봇 토큰을 제공합니다.
  4. 이 토큰을 안전하게 보관하세요 — 텔레그램 API를 통해 메시지를 보내려면 필요합니다.

봇 테스트

curl -X POST https://api.telegram.org/bot/sendMessage \
     -d chat_id= \
     -d text="Hello from PyDaily!"

팁: 테스트용 텔레그램 채팅 ID를 얻으려면 @userinfobot을 사용하세요.

단계 3: Supabase 백엔드 설정

Supabase가 담당할 내용:

  • 인증
  • 데이터베이스 저장
  • Edge Functions (서버리스 백엔드)

1. 레슨 저장

insert into public.lessons (day_index, title, content, example_code, challenge)
values
  (1, 'Variables & Types', 'Introduction to Python variables',
   'x = 5\ny = "Hello"', 'Write a program to swap two variables'),
  (2, 'Control Flow', 'If, elif, else',
   'if x > 5:\n    print("x is greater")',
   'Write a function to check even/odd');

2. 사용자 알림 설정

  • 사용자는 전달 채널(텔레그램)과 시간을 선택할 수 있습니다.
  • 각 사용자에 대해 생성된 활성화 코드를 포함한 user_telegram 행을 추가합니다.

3. 텔레그램용 Edge Function

텔레그램을 위한 Supabase Edge Function을 생성하고 다음을 수행합니다:

  1. 텔레그램이 활성화된 사용자를 가져옵니다.
  2. 오늘의 레슨을 결정합니다.
  3. user_progress를 확인하여 중복 전송을 방지합니다.
  4. Telegram Bot API를 통해 레슨을 전송합니다.
  5. user_progress를 업데이트합니다.

단계 4: React 프론트엔드

알림 설정 컴포넌트

function NotificationSettings({ user }) {
  const [telegramUsername, setTelegramUsername] = useState('');
  const [activationCode, setActivationCode] = useState('');
  const [status, setStatus] = useState('pending');

  const generateCode = async () => {
    const { data } = await supabase.rpc('generate_telegram_activation_code');
    setActivationCode(data);
  };

  return (
    <div>
      <input
        placeholder="Telegram username"
        value={telegramUsername}
        onChange={e => setTelegramUsername(e.target.value)}
      />
      <button onClick={generateCode}>Generate Activation Code</button>

      <p>Status: {status}</p>

      {status === 'pending' && (
        <div>
          Send this code to the bot: {activationCode}
        </div>
      )}
    </div>
  );
}
  • 제출 시, Supabase 클라이언트를 통해 user_notificationsuser_telegram에 데이터를 저장합니다.
  • React는 레슨 기록을 가져와 사용자 진행 상황을 표시합니다.

Step 5: 모든 연결하기

  1. User가 프론트엔드에서 텔레그램 사용자명을 입력합니다.
  2. Backend가 활성화 코드를 생성합니다 (RPC를 통해).
  3. User가 코드를 봇에 전송합니다 → 백엔드 웹훅이 이를 검증하고 → status = connected 로 업데이트합니다.
  4. Daily lesson scheduler Edge Function이 실행됩니다:
// Pseudocode
for (const user of usersWithTelegramEnabled) {
  const lesson = await getTodaysLesson();
  const alreadySent = await checkUserProgress(user.id, lesson.id);
  if (!alreadySent) {
    await sendTelegramMessage(user.telegram_chat_id, formatLesson(lesson));
    await markLessonSent(user.id, lesson.id);
  }
}
son = getLessonForToday(user)
if !user_progress.completed:
    sendTelegram(user.telegram_chat_id, lesson.content)
    markLessonCompleted(user, lesson)

이러한 구성 요소가 준비되면, PyDaily는 텔레그램을 통해 사용자에게 매일 파이썬 레슨을 자동으로 전달하고, 사용자는 React 대시보드에서 진행 상황을 추적하고 알림 설정을 제어할 수 있습니다. 🚀

스케줄링

  • Supabase cron 또는 외부 서비스를 통해 스케줄링할 수 있습니다.
  • 레슨에는 Markdown 형식이나 코드 블록이 포함됩니다.

Step 6: Testing & Going Live

  • 활성화 코드 흐름을 테스트합니다.
  • user_telegram.status = connected인지 확인합니다.
  • Edge Function을 수동으로 실행하여 메시지를 확인합니다.
  • Edge Function을 매일 실행되도록 스케줄링합니다.

결론

Supabase와 React를 사용하면 다음을 할 수 있습니다:

  • 사용자, 레슨, 알림을 원활하게 관리합니다.
  • 맞춤형 메시징 서비스를 구축하지 않고도 일일 참여를 위한 텔레그램 봇을 사용합니다.
  • 아키텍처를 이메일, WhatsApp, 또는 기타 채널로 확장합니다.

다음 단계

  • 텔레그램 sendPhoto를 통해 레슨 첨부 파일(이미지, 다이어그램)을 추가합니다.
  • 레슨 타임라인 및 진행 차트를 포함하도록 React UI를 확장합니다.
  • 안정적인 전달을 위해 Edge Functions에 재시도 로직을 추가합니다.

이 게시물은 Supabase를 백엔드로 사용하여 React 프런트엔드와 통합된 일일 Python 레슨 텔레그램 봇을 구현하기 위한 완전한 엔드‑투‑엔드 계획을 제공합니다.

Back to Blog

관련 글

더 보기 »

Drupal: Canvas 탐색 (파트 2)

Components 탐색 이전 포스트에서 나는 새로운 module을 익혔고, 좋은 시작을 보였다. 이번 포스트에서는 component를 탐구할 것이다.