별책부록 10편
별책부록 10편
TSV 봇 적용 가이드
TotalSportsView 운영자를 위한 4가지 봇 — 발행·B2B·Position C·사용자 응대
📑 이 챕터에서 다룰 내용

TSV(TotalSportsView)는 19리그 × 4 페르소나 = 일 76 articles 자동 발행 미디어입니다. 1인 운영자가 모든 것을 화면 앞에서 확인할 수 없어요. 봇이 24/7 모니터링하면서 중요한 변화만 알려주면, 운영자는 다른 일에 집중할 수 있습니다.

📘 이 편에서 만들 봇 4가지
  1. TSV 모니터링 봇 — 매일 발행·에러·매출 알림
  2. B2B 고객 응답 봇 — 분기 리포트·갱신 시점 알림
  3. Position C 검증 봇 — 베팅 키워드 자동 검출
  4. 사용자 문의 봇 — Discord 사용자 질문 응답

각 봇은 별책부록 1~9편의 인프라(Contabo + systemd + pm2 + Sentry)를 그대로 사용하고, 시스템 프롬프트와 알림 로직만 도메인에 맞춰 바꿉니다.

10-1 TSV 모니터링 봇 — 매일 발행 + 에러 + 매출 🔗

본질

매일 09:00에 운영자에게 "어제 무엇이 일어났는지" 알려주는 봇입니다. 매출 변화·발행 실패·사용자 추세 등 운영자가 알아야 할 핵심만 추려서 Discord/Telegram으로 전송합니다.

알림 형식

💻 매일 리포트 예시
🌅 TSV 매일 리포트 — 2026-05-09

[발행]
✅ 76 / 76 articles 발행 완료
   - 한국어: 76 (4 페르소나 × 19리그)
   - 영문: 76 (자동 번역)

[사용자]
👥 일별 활성 사용자: 1,247명 (+8% vs 어제)
🔔 신규 가입: 23명
💰 신규 구독자: 4명 ($4.99/월)

[B2B]
📊 분기 리포트 다운로드: 3건 (TalkSports·KBS·KBO Insight)
🔔 갱신 임박 (7일 이내): 2 고객

[매출]
💵 어제 매출: $128 (광고 $15 + 구독 $20 + B2B $93)
📈 5월 누적: $2,340 / 목표 $3,500

[알림]
⚠️ 에러: 0건
🎯 Position C 차단: 12건 (정상)

시스템 프롬프트 (Discord 봇)

💻 시스템 프롬프트
당신은 "TSV 모니터링 봇"입니다. TotalSportsView 운영자 Junho의 일일 리포트를 작성합니다.

[역할]
- 매일 09:00 KST에 어제(00:00~23:59 KST) 데이터 종합
- 핵심만 간결하게 (3~5분 안에 읽을 수 있게)
- 변화·이상 징후 강조

[데이터 소스]
다음 함수로 데이터 조회:
- get_articles_published(date) → 발행 통계
- get_user_metrics(date) → 사용자 활성·신규·구독
- get_b2b_status() → B2B 고객·다운로드·갱신
- get_revenue(date) → 광고·구독·B2B 매출
- get_errors(date) → Sentry 에러 종합
- get_position_c_blocks(date) → 베팅 키워드 차단 수

[응답 형식]
이모지 + 카테고리별 구분 + 숫자 명확히
변화율 표시 (+/- vs 어제)
이상 징후 ⚠️ 강조

데이터 함수 예시 (Python)

💻 tsv_monitoring/data_sources.py
# tsv_monitoring/data_sources.py
from datetime import date, timedelta
from sqlalchemy import create_engine, text
import os

engine = create_engine(os.getenv("DATABASE_URL"))

def get_articles_published(target_date: date) -> dict:
    """어제 발행된 articles 종합"""
    with engine.connect() as conn:
        result = conn.execute(text("""
            SELECT
                language,
                persona,
                COUNT(*) as count,
                SUM(CASE WHEN status = 'published' THEN 1 ELSE 0 END) as success,
                SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed
            FROM articles
            WHERE DATE(published_at) = :date
            GROUP BY language, persona
        """), {"date": target_date})

        return {
            "total": sum(r.count for r in result),
            "success": sum(r.success for r in result),
            "failed": sum(r.failed for r in result),
            "by_language": {...},
            "by_persona": {...}
        }

def get_revenue(target_date: date) -> dict:
    """매출 종합 — 광고·구독·B2B"""
    with engine.connect() as conn:
        ad = conn.execute(text("""
            SELECT SUM(amount) as total FROM ad_revenue
            WHERE DATE(date) = :date
        """), {"date": target_date}).scalar() or 0

        sub = conn.execute(text("""
            SELECT SUM(amount) as total FROM subscription_payments
            WHERE DATE(charged_at) = :date
        """), {"date": target_date}).scalar() or 0

        b2b = conn.execute(text("""
            SELECT SUM(amount) as total FROM b2b_invoices
            WHERE DATE(paid_at) = :date
        """), {"date": target_date}).scalar() or 0

        return {"ad": ad, "subscription": sub, "b2b": b2b, "total": ad + sub + b2b}

cron 등록

💻 터미널에 입력하세요
# 매일 09:00 KST 실행
crontab -e

0 9 * * * cd /home/ubuntu/tsv-monitoring && /usr/bin/python3 daily_report.py
10-2 B2B 고객 응답 봇 🔗

본질

B2B 고객(분석 미디어·마케팅 회사 등)의 문의·다운로드·갱신을 추적하는 봇입니다. 운영자에게 즉시 알림 + 자동으로 처리할 수 있는 항목은 자동 처리합니다.

알림 시점

📘 알림 분류

[즉시 알림]

  • B2B 고객이 분기 리포트 다운로드 시
  • 신규 B2B 문의 들어올 때
  • 갱신 결제 실패 시

[7일 전 알림]

  • 분기 갱신 시점 임박
  • 연간 리포트 출시 임박

[월별 알림]

  • B2B 고객별 사용 통계
  • 갱신율·만족도 추이

Discord 알림 예시

💻 B2B 알림 예시
🔔 [B2B 알림] TalkSports 분기 리포트 다운로드

고객: TalkSports (계정 코드: ts2026)
다운로드 자료: 2026-Q2 리포트 (한국어, 87 페이지)
다운로드 시간: 2026-05-09 14:23 KST
다음 갱신일: 2026-07-15 (D-67일)

[본인 확인]
이메일 검증: ✅
IP 검증: 한국 (이상 없음)

[추가 안내]
- /b2b TalkSports 입력 시 상세 정보
- 만족도 조사 자동 발송 가능

시스템 프롬프트

💻 시스템 프롬프트
당신은 "TSV B2B 응답 봇"입니다. B2B 고객 활동을 추적하고 운영자에게 알립니다.

[역할]
- B2B 14~20 고객 (분석 미디어·마케팅 회사·미디어 그룹)
- 분기당 $299 결제 추적
- 갱신율 100% 유지 목표

[알림 우선순위]
1. 갱신 결제 실패 → 즉시 (운영자 응답 필수)
2. 갱신 임박 7일 → 알림 + 자동 메일
3. 신규 다운로드 → 알림 (30분 안에 운영자 응답 권장)
4. 신규 문의 → 알림 + 24h 안에 응답 권장

[자동 처리 가능 항목]
- 표준 FAQ 답변 (가격·다운로드 방법·언어 옵션)
- 영수증 재발송
- 자료 링크 재전송

[수동 처리 필수 항목]
- 새로운 요구사항
- 갱신 협상
- 환불 문의
- 불만·불평 (Position C 준수 — 단정적 약속 X)
10-3 Position C 검증 봇 🔗

본질

TSV의 핵심 가치는 ⚖️ Position C — "분석 미디어 vs 베팅"입니다. 봇이 매일 발행되는 76 articles를 자동 검사해서 베팅 키워드·단정 표현이 있으면 즉시 알립니다.

검출 로직 (별책부록 7편 확장)

💻 tsv_position_c/validator.py
# tsv_position_c/validator.py

POSITION_C_FORBIDDEN = [
    # 베팅 직접 키워드
    "베팅", "도박", "내기", "픽", "오즈", "배당",
    # 영문
    "betting", "gambling", "pick", "odds", "wager",
    # 일본어 (Phase 3)
    "賭け", "ベット", "予想",
    # 중국어 (Phase 3)
    "投注", "赌博", "下注",

    # 단정 표현 (확률 100% 등)
    "100% 확실", "반드시 이긴다", "무조건",
    "guaranteed", "definitely will win",

    # 추천 표현
    "이번 경기 추천", "여기에 걸어라",
    "bet on", "place your bet on",
]

POSITION_C_WARN = [
    # 회색지대 (경고만)
    "예측", "예상", "유리하다",
    "favored", "likely to win",
]

def check_article(article_text: str, language: str) -> dict:
    """기사 본문 Position C 검증"""
    forbidden_hits = []
    warn_hits = []

    for keyword in POSITION_C_FORBIDDEN:
        if keyword.lower() in article_text.lower():
            forbidden_hits.append(keyword)

    for keyword in POSITION_C_WARN:
        if keyword.lower() in article_text.lower():
            warn_hits.append(keyword)

    return {
        "language": language,
        "forbidden_count": len(forbidden_hits),
        "forbidden_hits": forbidden_hits,
        "warn_count": len(warn_hits),
        "warn_hits": warn_hits,
        "passed": len(forbidden_hits) == 0
    }

알림 형식 (위반 발견 시)

⚠️ Position C 위반 알림 예시
🚨 [Position C 위반!] 즉시 검토 필요

기사: "맨유 vs 첼시 — 통계학자 페르소나 분석"
URL: https://tsv.com/article/12345
페르소나: STAT
언어: 한국어

[위반 키워드]
❌ "100% 확실" (단정 표현)
❌ "여기에 걸어라" (베팅 추천)

[조치]
1. 즉시 자동 unpublish (게시 취소)
2. 운영자에게 알림 (Discord + 이메일)
3. Sentry 로그 기록

[권장 액션]
- 5분 안에 운영자 검토
- 콘텐츠 정정 후 재발행
- 또는 영구 삭제

발행 파이프라인 통합

💻 tsv_articles/publish.py
# tsv_articles/publish.py
from tsv_position_c import validator

def publish_article(article):
    # 1. Position C 검증 (필수)
    result = validator.check_article(article.body, article.language)

    if not result["passed"]:
        # 자동 차단 + 알림
        article.status = "blocked_position_c"
        article.save()

        send_discord_alert(
            title=f"🚨 Position C 위반!",
            article=article,
            violations=result["forbidden_hits"]
        )
        return False

    # 2. 정상 → 발행
    article.status = "published"
    article.save()
    return True
10-4 사용자 문의 응대 봇 🔗

본질

TSV Discord 서버에 들어온 사용자 질문을 자동 응답합니다. FAQ 처리 + 복잡한 항목은 운영자에게 escalate합니다.

자동 응답 가능 항목

📘 자동 응답 분류

[가격·구독]

  • "구독료가 얼마예요?" → "$4.99/월입니다. /subscribe로 가입하세요."
  • "환불 가능해요?" → "구독 후 7일 안에 환불 가능합니다."

[기능]

  • "어떤 리그를 다뤄요?" → "EPL·라리가·세리에A·분데스리가 등 19리그입니다."
  • "영문판도 있어요?" → "네, 자동 번역으로 영문 콘텐츠도 제공합니다."

[기술]

  • "기사가 안 보여요" → "캐시 삭제 + 재로그인을 시도해보세요."
  • "결제가 안 돼요" → (즉시 운영자 escalate)

[Position C 관련]

  • "이 경기 누가 이길까요?" → "TSV는 베팅·픽 추천을 제공하지 않습니다. 분석 미디어로서 통계와 맥락만 제공합니다."

시스템 프롬프트

💻 시스템 프롬프트
당신은 "TSV 사용자 응대 봇"입니다.

[톤]
- 친근하고 도움이 되도록
- 한국어 (사용자가 영어로 묻으면 영어)
- 짧고 명확하게 (3문장 이내)

[Position C 원칙]
- 베팅·픽·예측 추천 절대 X
- "이 경기 누가 이길까?" 같은 질문에는:
  "TSV는 분석 미디어입니다. 통계와 맥락은 제공하지만,
   특정 결과 예측이나 베팅 추천은 하지 않습니다."

[escalate 항목]
다음은 운영자에게 즉시 전달:
- 결제 문제
- 환불 요청
- 콘텐츠 오류 보고
- 불만 표현
- 법적 문의
- "운영자와 통화하고 싶어요" 같은 요청

[응답 후]
- 답변 만족도 1~5 별점 요청 (선택)
- 추가 질문 권장 ("더 궁금한 점 있으세요?")
10-5 4 봇 통합 운영 — pm2 ecosystem 🔗
💻 /home/ubuntu/tsv-bots/ecosystem.config.js
// /home/ubuntu/tsv-bots/ecosystem.config.js
module.exports = {
  apps: [
    {
      name: "tsv-monitoring",
      script: "tsv_monitoring/main.py",
      interpreter: "/home/ubuntu/.venv/bin/python3",
      env: {
        DATABASE_URL: process.env.DATABASE_URL,
        DISCORD_TOKEN_MONITORING: process.env.DISCORD_TOKEN_MONITORING,
        ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY,
      },
      max_memory_restart: "300M",
      autorestart: true,
    },
    {
      name: "tsv-b2b",
      script: "tsv_b2b/main.py",
      interpreter: "/home/ubuntu/.venv/bin/python3",
      env: {
        DATABASE_URL: process.env.DATABASE_URL,
        DISCORD_TOKEN_B2B: process.env.DISCORD_TOKEN_B2B,
      },
      max_memory_restart: "200M",
      autorestart: true,
    },
    {
      name: "tsv-position-c",
      script: "tsv_position_c/main.py",
      interpreter: "/home/ubuntu/.venv/bin/python3",
      cron_restart: "0 0 * * *",  // 매일 자정 재시작
      max_memory_restart: "200M",
    },
    {
      name: "tsv-faq",
      script: "tsv_faq/main.js",
      env: {
        DISCORD_TOKEN_FAQ: process.env.DISCORD_TOKEN_FAQ,
        ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY,
      },
      max_memory_restart: "300M",
      autorestart: true,
    },
  ],
};
💻 pm2 시작 + 상태 확인
# 시작
cd /home/ubuntu/tsv-bots
pm2 start ecosystem.config.js
pm2 save
pm2 startup  # 부팅 시 자동 시작

# 상태 확인
pm2 status
pm2 logs tsv-monitoring
10-6 비용 + 운영 계획 🔗

봇 4개 추가 시 자원

📘 메모리 사용량
  • 모니터링 봇: ~250MB
  • B2B 봇: ~200MB
  • Position C 봇: ~200MB
  • FAQ 봇: ~250MB
  • 합계: ~900MB

기존 TSV (1.7GB) + 봇 4개 (0.9GB) = 2.6GB
Cloud VPS 10 (8GB) 안에 충분합니다 (32% 사용).

Anthropic API 비용

일별 호출토큰 (추정)
모니터링 봇1회 (매일 09:00)약 5,000 토큰
B2B 봇약 30회약 90,000 토큰
Position C 봇자동 검출 (API 없음)
FAQ 봇약 100회약 200,000 토큰
합계약 295K 토큰/일
💡 prompt caching으로 비용 절약

Sonnet 4.6 기준 약 $1.50/일 = 월 약 $45입니다.

시스템 프롬프트에 prompt caching을 적용하면 → 월 약 $5~10으로 90% 절약됩니다.

prompt caching 적용 방법은 1탄 28장(cache_control)을 참고하세요.

10-7 검증 체크리스트 — Day 14 🔗
📘 Day 14 검증 항목
  • ☑ 4 봇 모두 안정 작동 (재시작 0번)
  • ☑ 매일 09:00 리포트 정상 도착
  • ☑ B2B 고객 활동 즉시 알림
  • ☑ Position C 위반 검출 0건 (또는 정상 차단)
  • ☑ FAQ 만족도 4.0/5 이상
  • ☑ Anthropic 비용 예상 범위 안 ($45 또는 캐싱 시 $10)
  • ☑ TSV 운영 시간 절약: 일 30분 → 5분
📌 10편 정리
  • 1️⃣ 모니터링 봇: 매일 09:00 발행·에러·매출 리포트 자동 전송
  • 2️⃣ B2B 봇: 고객 활동 즉시 알림 + 갱신 7일 전 자동 안내
  • 3️⃣ Position C 봇: 76 articles 자동 검증 + 위반 즉시 unpublish
  • 4️⃣ FAQ 봇: 사용자 문의 자동 응대 + 복잡한 항목은 운영자 escalate
  • 5️⃣ 인프라: 별책부록 1~9편 그대로 (Contabo + systemd + pm2 + Sentry)
  • 6️⃣ 비용: 약 $45/월 → prompt caching 시 $5~10/월
  • 7️⃣ 핵심 가치: 운영자 일 30분~1시간 → 5분으로 단축
🎉 핵심 한 줄

봇이 24/7 모니터링 — 운영자는 중요한 일에 집중합니다.

TSV 운영자에게 봇이 주는 가치는 시간입니다. 일 30분~1시간을 5분으로 줄여줍니다.

📘
별책부록 도우미
질문하기 OK
안녕하세요! TSV 봇 적용에 대해 무엇이든 물어보세요. 본문에서 찾아 답변해드릴게요. 👇