Repository navigation
Services
๊ฐ fetcher๋ ํน์ ๋ด์ค ์์ค์์ ๊ธฐ์ฌ๋ฅผ ์์งํ์ฌ Article ๊ฐ์ฒด ๋ฆฌ์คํธ๋ก ๋ฐํํฉ๋๋ค.
Hacker News API์์ ์์ ๊ธฐ์ ๋ด์ค๋ฅผ ์์งํฉ๋๋ค.
๋ฐ์ดํฐ ์์ค: hacker-news.firebaseio.com/v0
๋์ ํ๋ฆ:
-
/topstories์๋ํฌ์ธํธ์์ ์์ ์คํ ๋ฆฌ ID ๋ชฉ๋ก ๊ฐ์ ธ์ค๊ธฐ - ์์ 50๊ฐ ์คํ ๋ฆฌ์ ์์ธ ์ ๋ณด fetch (๋ณ๋ ฌ ์๋, ์์ฐจ + ์ฌ์๋)
- ๋น๊ธฐ์ ํค์๋ ํํฐ๋ง (์ ์น, ์คํฌ์ธ , ์ ๋ช ์ธ ๋ฑ)
- ์ ์์ ์ ๋ ฌ ํ ์์ 5๊ฐ ๋ฐํ
ํํฐ๋ง ๊ท์น:
NON_TECH_PATTERNS = re.compile(
r"\b(politics|election|president|congress|senate|democrat|republican|"
r"nfl|nba|mlb|fifa|olympics|weight loss|diet pill|celebrity|...)\\b",
re.IGNORECASE,
)์ฃผ์ ์์ฅ ๋ด์ค๋ฅผ ์ธ์ด๋ณ๋ก ๋ค๋ฅธ ์์ค์์ ์์งํฉ๋๋ค.
์์ด ์์ค: Yahoo Finance RSS (finance.yahoo.com/news/rssurl)
ํ๊ตญ์ด ์์ค: Google News Korea RSS (news.google.com/rss/search?q=์ฃผ์+์ฝ์คํผ)
ํค์๋ ํํฐ๋ง:
- ์์ด: stock, market, S&P, NASDAQ, earnings, dividend, IPO, bitcoin ๋ฑ
- ํ๊ตญ์ด: ์ฃผ์, ์ฝ์คํผ, ์ฝ์ค๋ฅ, ์ฆ์, ์ฃผ๊ฐ, ์์ฅ, ๋ฐฐ๋น, ETF ๋ฑ
๋ถ๋์ฐ ๋ด์ค๋ฅผ ์ธ์ด๋ณ๋ก ๋ค๋ฅธ ์์ค์์ ์์งํฉ๋๋ค.
์์ด ์์ค:
- Zillow Research (
zillow.com/research/feed/) - HousingWire (
housingwire.com/feed/) - CNBC Real Estate (
search.cnbc.com/rs/...)
ํ๊ตญ์ด ์์ค: Google News Korea RSS
๊ธฐ์ฌ ๋ณธ๋ฌธ์ ์ถ์ถํ๊ณ AI๋ก ์์ฝํฉ๋๋ค.
๋ณธ๋ฌธ ์ถ์ถ:
-
trafilatura.extract()โ ๋ฉ์ธ ์ฝํ ์ธ ์ถ์ถ - Hacker News
textํ๋ โ HN ์์ฒด ๊ฒ์๊ธ์ธ ๊ฒฝ์ฐ - HN ๋๊ธ ๋ณธ๋ฌธ โ URL ์๋ Ask HN/Show HN ๋ฑ
์์ฝ ์์ง:
-
์ฃผ ์์ง: Groq API (
qwen/qwen3.8-27b) - ํด๋ฐฑ: Google Translate (๋ฌด๋ฃ API)
์ธ์ด๋ณ ํ๋กฌํํธ:
ํ๊ตญ์ด: "ํ๊ตญ ํ
ํฌ ๋ธ๋ก๊ฑฐ๊ฐ ๊ฐ๋ฐ์ ์น๊ตฌ์๊ฒ ์ค๋ช
ํ๋ ๋๋์ผ๋ก 3๋ฌธ์ฅ ์์ฝ.
๋ฑ๋ฑํ '~ํ์ต๋๋ค' ๋์ '~ํ์ด์', '~์ธ ์
์ด์ฃ ' ๋ฑ ์ฌ์ฉ."
์์ด: "Summarize in 3 sentences in English. Casual, friendly tone."
์ฌ์๋ ๋ก์ง:
- Rate limit ์ ์ง์ ๋ฐฑ์คํ: 5์ด โ 10์ด โ 20์ด
- ์ต๋ 3ํ ์ฌ์๋
- ์คํจ ์ ๋น ๋ฌธ์์ด ๋ฐํ (์์ฝ ์์ด ๊ธฐ์ฌ ์ ๋ชฉ๋ง ๋ฐ์ก)
HTML ์ด๋ฉ์ผ์ ์์ฑํ์ฌ Gmail SMTP๋ก ๋ฐ์กํฉ๋๋ค.
์ด๋ฉ์ผ ๊ตฌ์ฑ:
- ๋ชจ๋ฐ์ผ ์นํ์ HTML ํ ํ๋ฆฟ
- ๊ธฐ์ฌ๋ณ: ์๋ฒ, ์ ๋ชฉ (๋งํฌ), AI ์์ฝ, HN ๋๊ธ ๋งํฌ
- ํ๋จ: ๊ตฌ๋ ํด์ง ๋งํฌ
- ํ ํฝ๋ณ ์ด๋ชจ์ง ํค๋ (๐ป Tech, ๐ Stocks, ๐ Real Estate)
๋ณด์:
- URL sanitization:
http://,https://์คํด๋ง ํ์ฉ - HTML escape: ๋ชจ๋ ์ฌ์ฉ์ ์ ๋ ฅ๊ฐ
- ์ด๋ฉ์ผ ์ฃผ์ HTML escape
๋ฐ์ก ๋ฐฉ์:
- ๋จ์ผ SMTP SSL ์ฐ๊ฒฐ๋ก ๋ชจ๋ ์ด๋ฉ์ผ ์ฒ๋ฆฌ
- SMTP_SSL (465) ์๋ โ ์คํจ ์ STARTTLS (587) ํด๋ฐฑ
- ๋ฐ์ก ์คํจ ์ ๋ก๊ทธ ํ ๋ค์ ๊ตฌ๋ ์๋ก ๊ณ์
subscribers.json ํ์ผ ๊ธฐ๋ฐ์ ๊ตฌ๋
์ CRUD ๊ด๋ฆฌ์
๋๋ค.
๋ฐ์ดํฐ ๋ชจ๋ธ:
[
{
"email": "user@example.com",
"language": "ko",
"topics": ["tech", "stocks"]
}
]์ ๊ณต ํจ์:
| ํจ์ | ์ค๋ช |
|---|---|
load_subscribers() |
JSON์์ ๊ตฌ๋ ์ ๋ชฉ๋ก ๋ก๋ |
save_subscribers() |
๊ตฌ๋ ์ ๋ชฉ๋ก์ JSON์ผ๋ก ์ ์ฅ |
add_subscriber() |
์ ๊ตฌ๋ ์ ์ถ๊ฐ (์ค๋ณต ๊ฒ์ฌ, ์ต๋ 500๋ช ) |
remove_subscriber() |
์ด๋ฉ์ผ๋ก ๊ตฌ๋ ์ ์ ๊ฑฐ |
update_subscriber() |
์ธ์ด/ํ ํฝ ๋ณ๊ฒฝ |
๊ตฌ๋
ํ์ด์ง์์์ ์์ฒญ์ GitHub Actions repository_dispatch๋ก ํ๋ก์ํฉ๋๋ค.
์ญํ :
- GitHub PAT ํ ํฐ์ ์๋ฒ ์ฌ์ด๋์ ์์ ํ๊ฒ ๋ณด๊ด
- CORS origin ๊ฒ์ฆ (ํ๋ก๋์ ๋๋ฉ์ธ๋ง ํ์ฉ)
- Rate limiting (IP๋ณ ๋ถ๋น 5๊ฑด, ์๊ฐ๋น 20๊ฑด)
- ์ ๋ ฅ ๊ฒ์ฆ ๋ฐ ํํฐ๋ง
๋ณด์ ์กฐ์น:
โ
CORS: https://minjungsung.github.io๋ง ํ์ฉ
โ
ํ๋ ํ์ดํธ๋ฆฌ์คํธ: email, language, topics, action๋ง
โ
์ธ์ด/ํ ํฝ ๊ฐ ๊ฒ์ฆ: ํ์ฉ๋ ๊ฐ๋ง
โ
Request body ํฌ๊ธฐ ์ ํ: 1KB
โ
์ด๋ฉ์ผ ๊ธธ์ด ์ ํ: 254์
โ
IP ๊ธฐ๋ฐ Rate limiting
GitHub Actions Cache๋ฅผ ํ์ฉํ ์ผ๊ฐ ์บ์ฑ ์์คํ ์ ๋๋ค.
์บ์ ํ์ผ:
-
data/cache/articles_{topic}.jsonโ ํ ํฝ๋ณ ๊ธฐ์ฌ ์บ์ -
data/cache/summaries_{language}.jsonโ ์ธ์ด๋ณ ์์ฝ ์บ์
์บ์ ์ ๋ต:
- ๊ฐ์ ๊ธฐ์ฌ๋ฅผ ์ฌ๋ฌ ๊ตฌ๋ ์์๊ฒ ๋ฐ์กํ ๋ ์ค๋ณต Groq API ํธ์ถ ๋ฐฉ์ง
- ๊ธฐ์ฌ URL์ ํค๋ก ์ฌ์ฉํ์ฌ ์์ฝ ๊ฒฐ๊ณผ ์ ์ฅ
- ์คํ๋ง๋ค ์ ์บ์ ์์ฑ, ์ด์ ์คํ์ ์บ์์์ ๋ณต์ (
hackdigest-v2-prefix)