Skip to content

geeksbaek/daily-feed

Repository files navigation

Daily Feed

AI ๊ธฐ๋ฐ˜ RSS/Atom ํ”ผ๋“œ ์ˆ˜์ง‘ ๋ฐ ์š”์•ฝ ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค. Go ๋ฐฑ์—”๋“œ, Lit ๊ธฐ๋ฐ˜ ์›น UI, Firebase Functions FCM ํ‘ธ์‹œ ์•Œ๋ฆผ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๐ŸŒŸ ์ฃผ์š” ํŠน์ง•

  • 100% ๋ฌด๋ฃŒ: GitHub Actions + GitHub Pages + Firebase Functions
  • ์ž๋™ํ™”: ๋งค์ผ ์˜ค์ „ 7์‹œ ์ž๋™ ์‹คํ–‰ + FCM ํ‘ธ์‹œ ์•Œ๋ฆผ
  • 4๊ฐ€์ง€ ํ”„๋ฆฌ์…‹: ๐Ÿ“ฐ ์ผ๋ฐ˜, ๐Ÿ”ง ๊ฐœ๋ฐœ์ž, โ˜• ์บ์ฃผ์–ผ, ๐Ÿ’ฌ ์ปค๋ฎค๋‹ˆํ‹ฐ
  • ๋ชจ๋˜ ์›น UI: Lit 3.0 ์›น ์ปดํฌ๋„ŒํŠธ, ๋‹คํฌ๋ชจ๋“œ ์ง€์›
  • PWA ์ง€์›: ์˜คํ”„๋ผ์ธ ์บ์‹ฑ, ๋ชจ๋ฐ”์ผ ์ตœ์ ํ™”
  • ํ‘ธ์‹œ ์•Œ๋ฆผ: Firebase FCM ๊ธฐ๋ฐ˜ ์‹ค์‹œ๊ฐ„ ์•Œ๋ฆผ

๐Ÿ”” ํ‘ธ์‹œ ์•Œ๋ฆผ ์‹œ์Šคํ…œ

Firebase Functions ๊ธฐ๋ฐ˜ FCM

  • ๊ตฌ๋… ๊ด€๋ฆฌ: ์›น UI์—์„œ ์›ํด๋ฆญ ๊ตฌ๋…/ํ•ด์ œ
  • ์ž๋™ ์•Œ๋ฆผ: ์ƒˆ๋กœ์šด ํ”ผ๋“œ ์ƒ์„ฑ ์‹œ ์ž๋™ ๋ฐœ์†ก
  • ํ† ํ”ฝ ๊ธฐ๋ฐ˜: daily-feed ํ† ํ”ฝ์œผ๋กœ ๋ชจ๋“  ๊ตฌ๋…์ž์—๊ฒŒ ์ „์†ก

์•Œ๋ฆผ ๋ฐœ์†ก ๋ฐฉ์‹

  1. ์ž๋™ ๋ฐœ์†ก: ๋งค์ผ ์ƒˆ๋กœ์šด ์ฝ˜ํ…์ธ  ์ƒ์„ฑ ์‹œ
  2. ์ˆ˜๋™ ํ…Œ์ŠคํŠธ: GitHub Actions๋ฅผ ํ†ตํ•œ ํ…Œ์ŠคํŠธ ์•Œ๋ฆผ

๐Ÿ—๏ธ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

daily-feed/
โ”œโ”€โ”€ backend/                    # Go ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜
โ”‚   โ”œโ”€โ”€ cmd/
โ”‚   โ”‚   โ”œโ”€โ”€ generate/          # ํ”ผ๋“œ ์ƒ์„ฑ ๋ช…๋ น
โ”‚   โ”‚   โ”œโ”€โ”€ fcm-send/         # FCM ์•Œ๋ฆผ ๋ฐœ์†ก ๋„๊ตฌ
โ”‚   โ”‚   โ””โ”€โ”€ fcm-subscribe/    # FCM ๊ตฌ๋… ๊ด€๋ฆฌ ๋„๊ตฌ
โ”‚   โ”œโ”€โ”€ internal/              # ๋‚ด๋ถ€ ํŒจํ‚ค์ง€
โ”‚   โ”œโ”€โ”€ pkg/                   # ๊ณต์šฉ ํŒจํ‚ค์ง€ (FCM ํด๋ผ์ด์–ธํŠธ ํฌํ•จ)
โ”‚   โ”œโ”€โ”€ main.go               # CLI ์ง„์ž…์ 
โ”‚   โ”œโ”€โ”€ feeds.csv             # ํ”ผ๋“œ ๋ชฉ๋ก
โ”‚   โ””โ”€โ”€ samples/              # ์ƒ˜ํ”Œ ์ถœ๋ ฅ
โ”œโ”€โ”€ web/                       # ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜
โ”‚   โ”œโ”€โ”€ components/           # Lit ์›น ์ปดํฌ๋„ŒํŠธ
โ”‚   โ”‚   โ”œโ”€โ”€ daily-feed-app.js        # ๋ฉ”์ธ ์•ฑ ์ปดํฌ๋„ŒํŠธ
โ”‚   โ”‚   โ”œโ”€โ”€ content-viewer.js        # ์ฝ˜ํ…์ธ  ๋ทฐ์–ด (ํ”„๋กฌํ”„ํŠธ ๋ณด๊ธฐ ํฌํ•จ)
โ”‚   โ”‚   โ”œโ”€โ”€ notification-toggle.js   # FCM ์•Œ๋ฆผ ํ† ๊ธ€
โ”‚   โ”‚   โ””โ”€โ”€ firebase-push-manager.js # Firebase FCM ๊ด€๋ฆฌ์ž
โ”‚   โ”œโ”€โ”€ config.js             # Firebase ์„ค์ •
โ”‚   โ”œโ”€โ”€ index.html           # ๋ฉ”์ธ ํŽ˜์ด์ง€
โ”‚   โ”œโ”€โ”€ manifest.json        # PWA ๋งค๋‹ˆํŽ˜์ŠคํŠธ
โ”‚   โ”œโ”€โ”€ sw.js               # ์„œ๋น„์Šค ์›Œ์ปค
โ”‚   โ””โ”€โ”€ firebase-messaging-sw.js # FCM ์„œ๋น„์Šค ์›Œ์ปค
โ”œโ”€โ”€ functions/                 # Firebase Functions
โ”‚   โ”œโ”€โ”€ src/index.ts          # FCM ๊ตฌ๋…/ํ•ด์ œ ํ•จ์ˆ˜
โ”‚   โ”œโ”€โ”€ package.json
โ”‚   โ””โ”€โ”€ tsconfig.json
โ”œโ”€โ”€ data/summaries/           # ์ƒ์„ฑ๋œ JSON ๋ฐ์ดํ„ฐ
โ”œโ”€โ”€ .github/workflows/        # CI/CD ํŒŒ์ดํ”„๋ผ์ธ
โ”‚   โ”œโ”€โ”€ daily-feed.yml       # ํ”ผ๋“œ ์ƒ์„ฑ + FCM ์•Œ๋ฆผ
โ”‚   โ”œโ”€โ”€ pages.yml           # GitHub Pages ๋ฐฐํฌ
โ”‚   โ””โ”€โ”€ fcm-test.yml        # FCM ํ…Œ์ŠคํŠธ ์•Œ๋ฆผ
โ”œโ”€โ”€ .firebaserc              # Firebase ํ”„๋กœ์ ํŠธ ์„ค์ •
โ”œโ”€โ”€ firebase.json            # Firebase ๋ฐฐํฌ ์„ค์ •
โ””โ”€โ”€ README.md

๐Ÿš€ ๋ฐฐํฌ ๋ฐฉ๋ฒ•

1. ์ €์žฅ์†Œ ์„ค์ •

  1. ์ด ์ €์žฅ์†Œ๋ฅผ GitHub์— ํ‘ธ์‹œ
  2. GitHub Secrets์— ๋‹ค์Œ ์ถ”๊ฐ€:
    • GEMINI_API_KEY: Google Gemini API ํ‚ค
    • FIREBASE_SERVICE_ACCOUNT_KEY: Firebase Service Account JSON
  3. GitHub Pages ์„ค์ •: Settings > Pages > Source๋ฅผ "GitHub Actions"๋กœ ์„ค์ •

2. Firebase ์„ค์ •

  1. Firebase ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ ๋ฐ Blaze ํ”Œ๋žœ ์—…๊ทธ๋ ˆ์ด๋“œ
  2. Firebase Functions ๋ฐฐํฌ:
    cd functions
    npm install
    npm run build
    firebase deploy --only functions
  3. FCM ์„ค์ •:
    • Firebase Console > Project settings > Cloud Messaging
    • ์›น ํ‘ธ์‹œ ์ธ์ฆ์„œ ์ƒ์„ฑ ๋ฐ VAPID ํ‚ค ํ™•์ธ
    • web/config.js์— Firebase ์„ค์ • ์ถ”๊ฐ€

3. GitHub Actions ์›Œํฌํ”Œ๋กœ์šฐ

๋งค์ผ ์˜ค์ „ 7์‹œ(ํ•œ๊ตญ ์‹œ๊ฐ„)์— ์ž๋™์œผ๋กœ ์‹คํ–‰๋˜์–ด:

  1. 4๊ฐ€์ง€ ํ”„๋ฆฌ์…‹์œผ๋กœ ํ”ผ๋“œ ์ˆ˜์ง‘ ๋ฐ AI ์š”์•ฝ ์ƒ์„ฑ
  2. JSON ํŒŒ์ผ๋กœ ์ €์žฅ ๋ฐ ์ปค๋ฐ‹
  3. FCM ํ‘ธ์‹œ ์•Œ๋ฆผ ์ž๋™ ๋ฐœ์†ก (์ƒˆ ์ฝ˜ํ…์ธ  ์ƒ์„ฑ ์‹œ๋งŒ)
  4. GitHub Pages์— ์ž๋™ ๋ฐฐํฌ

4. ์ˆ˜๋™ ์‹คํ–‰

  • ํ”ผ๋“œ ์ƒ์„ฑ: "Daily Feed Generation" ์›Œํฌํ”Œ๋กœ์šฐ
  • FCM ํ…Œ์ŠคํŠธ: "FCM Test Notification" ์›Œํฌํ”Œ๋กœ์šฐ

๐Ÿ“ฑ ์›น ์ธํ„ฐํŽ˜์ด์Šค

  • URL: https://geeksbaek.github.io/daily-feed/
  • ๊ธฐ๋Šฅ:
    • ๋‚ ์งœ๋ณ„ ์š”์•ฝ ์กฐํšŒ
    • ํ”„๋ฆฌ์…‹๋ณ„ ํ•„ํ„ฐ๋ง
    • ํ‚ค์›Œ๋“œ ๊ฒ€์ƒ‰
    • GitHub Flavored Markdown ๋ Œ๋”๋ง
    • ๊ด€๋ จ ๊ธฐ์‚ฌ ๋งํฌ
    • ๐Ÿ”” FCM ํ‘ธ์‹œ ์•Œ๋ฆผ ๊ตฌ๋…/ํ•ด์ œ
    • ๐Ÿค– AI ํ”„๋กฌํ”„ํŠธ ๋ณด๊ธฐ (์ƒ์„ฑ์— ์‚ฌ์šฉ๋œ ์‹ค์ œ ํ”„๋กฌํ”„ํŠธ ํ™•์ธ)
    • ๋ธŒ๋ผ์šฐ์ € ์ƒˆ๋กœ๊ณ ์นจ ์‹œ ์ž๋™ ์บ์‹œ ๊ฐฑ์‹ 

๐Ÿ”” FCM ํ‘ธ์‹œ ์•Œ๋ฆผ ์‚ฌ์šฉ๋ฒ•

๊ตฌ๋…ํ•˜๊ธฐ

  1. ์›น์‚ฌ์ดํŠธ ๋ฐฉ๋ฌธ
  2. ์šฐ์ƒ๋‹จ ๐Ÿ”” ์•Œ๋ฆผ ๋ฒ„ํŠผ ํด๋ฆญ
  3. ๋ธŒ๋ผ์šฐ์ € ์•Œ๋ฆผ ๊ถŒํ•œ ํ—ˆ์šฉ
  4. ์ž๋™์œผ๋กœ daily-feed ํ† ํ”ฝ ๊ตฌ๋…

๋ฐ›๋Š” ์•Œ๋ฆผ

  • ์ œ๋ชฉ: ๐Ÿ—ž๏ธ Daily Feed
  • ๋‚ด์šฉ: ์ƒˆ๋กœ์šด ๊ธฐ์ˆ  ๋‰ด์Šค ์š”์•ฝ์ด ์ค€๋น„๋˜์—ˆ์Šต๋‹ˆ๋‹ค!
  • ํด๋ฆญ ์‹œ: ์›น์‚ฌ์ดํŠธ๋กœ ์ž๋™ ์ด๋™

๊ตฌ๋… ํ•ด์ œ

  • ์•Œ๋ฆผ ๋ฒ„ํŠผ์„ ๋‹ค์‹œ ํด๋ฆญํ•˜์—ฌ ํ•ด์ œ

๐Ÿ’ฐ ๋น„์šฉ

  • GitHub Actions: ์›” 2,000๋ถ„ ๋ฌด๋ฃŒ (์‹ค์ œ ์‚ฌ์šฉ๋Ÿ‰: ~200๋ถ„/์›”)
  • GitHub Pages: 100GB ๋Œ€์—ญํญ ๋ฌด๋ฃŒ
  • Firebase Functions: ์›” 2๋ฐฑ๋งŒ ํ˜ธ์ถœ ๋ฌด๋ฃŒ (์‹ค์ œ ์‚ฌ์šฉ๋Ÿ‰: ~1,000ํšŒ/์›”)
  • Firebase Cloud Messaging: ๋ฌด์ œํ•œ ๋ฌด๋ฃŒ
  • ์ด ๋น„์šฉ: $0/์›”

๐Ÿ”ง ๊ฐœ๋ฐœ

Go ๋ฐฑ์—”๋“œ

# ๋ฐฑ์—”๋“œ ๋””๋ ‰ํ† ๋ฆฌ๋กœ ์ด๋™
cd backend

# ํ”ผ๋“œ ์ƒ์„ฑ (๋กœ์ปฌ ํ…Œ์ŠคํŠธ)
export GEMINI_API_KEY="your-key"
go run cmd/generate/main.go

# FCM ์•Œ๋ฆผ ๋ฐœ์†ก ํ…Œ์ŠคํŠธ
export FIREBASE_PROJECT_ID="your-project-id"
export FIREBASE_SERVICE_ACCOUNT_KEY="path/to/serviceAccountKey.json"
go run cmd/fcm-send/main.go -topic "daily-feed" -title "ํ…Œ์ŠคํŠธ" -body "ํ…Œ์ŠคํŠธ ๋ฉ”์‹œ์ง€"

# CLI ๋„๊ตฌ ๋นŒ๋“œ ๋ฐ ์‹คํ–‰
go build -o daily-feed
./daily-feed --preset developer --feeds feeds.csv

์›น UI

# ์›น ๋””๋ ‰ํ† ๋ฆฌ๋กœ ์ด๋™
cd web

# ๋กœ์ปฌ ๊ฐœ๋ฐœ ์„œ๋ฒ„ ์‹คํ–‰
python -m http.server 8000
# ๋˜๋Š”
npx serve .

Firebase Functions

# Functions ๋””๋ ‰ํ† ๋ฆฌ๋กœ ์ด๋™
cd functions

# ์˜์กด์„ฑ ์„ค์น˜ ๋ฐ ๋นŒ๋“œ
npm install
npm run build

# ๋กœ์ปฌ ์—๋ฎฌ๋ ˆ์ดํ„ฐ ์‹คํ–‰
npm run serve

# ๋ฐฐํฌ
firebase deploy --only functions

๐Ÿ“Š ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ

{
  "date": "2025-01-15",
  "preset": "developer", 
  "summary": "๋งˆํฌ๋‹ค์šด ํ˜•์‹์˜ AI ์š”์•ฝ...",
  "prompt": {
    "system": "์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ...",
    "user": "์‚ฌ์šฉ์ž ํ”„๋กฌํ”„ํŠธ..."
  },
  "articles": [
    {
      "title": "๊ธฐ์‚ฌ ์ œ๋ชฉ",
      "link": "https://...",
      "source": "์ถœ์ฒ˜",
      "category": "์นดํ…Œ๊ณ ๋ฆฌ", 
      "publishedAt": "2025-01-15T10:00:00Z",
      "description": "๊ธฐ์‚ฌ ์„ค๋ช…"
    }
  ],
  "generatedAt": "2025-01-15T02:00:00Z"
}

๐ŸŽฏ ์™„๋ฃŒ๋œ ๊ธฐ๋Šฅ

์›น UI

  • Lit 3.0 ์›น ์ปดํฌ๋„ŒํŠธ ์ „ํ™˜
  • ๋‹คํฌ ๋ชจ๋“œ ์™„์ „ ์ง€์›
  • PWA ๊ธฐ๋Šฅ (์˜คํ”„๋ผ์ธ ์บ์‹ฑ, ๋ชจ๋ฐ”์ผ ์ตœ์ ํ™”)
  • ํ•œ๊ตญ์–ด UI ๋ฐ ์ด๋ชจ์ง€ ํƒญ ๋ ˆ์ด๋ธ”
  • ์ฐธ๊ณ  ์ž๋ฃŒ ๋งํฌ ์ƒˆ ์ฐฝ ์—ด๊ธฐ
  • ์ฝ”๋“œ ๋ธ”๋ก ๋‹คํฌ๋ชจ๋“œ ์ƒ‰์ƒ ์ง€์›
  • ๊ฐœ์„ ๋œ ๋กœ๋”ฉ UI (์Šคํ”ผ๋„ˆ ์• ๋‹ˆ๋ฉ”์ด์…˜)
  • ๋ธŒ๋ผ์šฐ์ € ์ƒˆ๋กœ๊ณ ์นจ ๊ฐ์ง€ ๋ฐ ์ž๋™ ์บ์‹œ ๊ฐฑ์‹ 
  • AI ํ”„๋กฌํ”„ํŠธ ๋ณด๊ธฐ ๊ธฐ๋Šฅ

ํ‘ธ์‹œ ์•Œ๋ฆผ ์‹œ์Šคํ…œ

  • Firebase Functions ๊ธฐ๋ฐ˜ FCM ๊ตฌ๋…/ํ•ด์ œ API
  • ์›น UI FCM ์•Œ๋ฆผ ํ† ๊ธ€ ์ปดํฌ๋„ŒํŠธ
  • ์ž๋™ ํ‘ธ์‹œ ์•Œ๋ฆผ ๋ฐœ์†ก (์ƒˆ ์ฝ˜ํ…์ธ  ์ƒ์„ฑ ์‹œ)
  • GitHub Actions FCM ํ…Œ์ŠคํŠธ ์›Œํฌํ”Œ๋กœ์šฐ
  • Service Worker ๊ธฐ๋ฐ˜ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์•Œ๋ฆผ ์ฒ˜๋ฆฌ

๋ฐฑ์—”๋“œ & ์ธํ”„๋ผ

  • Go ๊ธฐ๋ฐ˜ FCM ํด๋ผ์ด์–ธํŠธ ๋ฐ CLI ๋„๊ตฌ
  • GitHub Actions ์ž๋™ํ™” ํŒŒ์ดํ”„๋ผ์ธ
  • Firebase Functions ๊ณต๊ฐœ API ๋ฐฐํฌ
  • ๋ณด์•ˆ ๊ฐ•ํ™” (ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ๊ธฐ๋ฐ˜ ์„ค์ •)

๐ŸŽฏ ํ–ฅํ›„ ๊ณ„ํš

  • RSS ํ”ผ๋“œ ์ƒ์„ฑ
  • ์ปค์Šคํ…€ ๋„๋ฉ”์ธ ์„ค์ •
  • ๋ถ๋งˆํฌ ๊ธฐ๋Šฅ
  • ์ด๋ฉ”์ผ ๊ตฌ๋…
  • ์‚ฌ์šฉ์ž๋ณ„ ๋งž์ถค ํ† ํ”ฝ ๊ตฌ๋…
  • ์•Œ๋ฆผ ์„ค์ • ์„ธ๋ถ€ ์˜ต์…˜

๐Ÿ“„ ๋ผ์ด์„ ์Šค

MIT License

About

Resources

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •