with one click
korea-apt-alert
// 한국 청약 공고를 개인 프로필 기반으로 조회·분석하고 Slack/Telegram으로 알림을 보낸다. 공공데이터포털 6개 API를 프록시 경유로 통합 조회하며, 사용자 API 키 없이 동작한다.
// 한국 청약 공고를 개인 프로필 기반으로 조회·분석하고 Slack/Telegram으로 알림을 보낸다. 공공데이터포털 6개 API를 프록시 경유로 통합 조회하며, 사용자 API 키 없이 동작한다.
[HINT] Download the complete skill directory including SKILL.md and all related files
| name | korea-apt-alert |
| description | 한국 청약 공고를 개인 프로필 기반으로 조회·분석하고 Slack/Telegram으로 알림을 보낸다. 공공데이터포털 6개 API를 프록시 경유로 통합 조회하며, 사용자 API 키 없이 동작한다. |
| license | MIT |
| metadata | {"category":"real-estate","locale":"ko-KR","phase":"v2.7","homepage":"https://github.com/tkddnjs-dlqslek/k-apt-alert","k_skill_family":"NomaDamas/k-skill"} |
이 파일만 받으셨나요? 설치 방법 · 사전 조건 · 실제 출력 예시는 GitHub 레포 README를 먼저 확인하세요. 이 SKILL.md는 스킬 폴더(Claude Code:
~/.claude/skills/korea-apt-alert// Codex:~/.agents/skills/korea-apt-alert/)에 배치된 뒤 런타임이 로드할 때 사용되는 지시문입니다. Claude Code와 OpenAI Codex 모두에서 동일하게 동작합니다.
공공데이터포털의 청약홈 분양정보 API를 프록시 경유로 조회하여 사용자 프로필 기반으로 최신 청약 공고를 필터링·분석·알림한다.
기본은 간결하게, 상세는 요청 시에만. 아래 규칙을 반드시 지킨다.
💡 더 보려면: '내 조건에 맞는 추천' / '내 가점' / '청약 가이드'| 사용자 말 | 출력 모드 |
|---|---|
/korea-apt-alert 단독, "공고 보여줘", "청약 공고" | 간결 (테이블만) |
| "내 조건에 맞는", "맞춤 추천", "Top 3" | 프로필 매칭 + Top 3 + 테이블 |
| "내 가점", "가점 계산" | 가점 계산 + 가점대별 전략 |
| "특별공급", "신혼부부·다자녀 자격" | 특별공급 판정만 |
| "청약이 뭐야", "초보", "가이드", "설명해줘" | 청약 입문 가이드 |
| "0건 나왔어, 인접 지역" | 인접 지역 확장 제안 |
| "이 공고 분석해줘", "공고 해석해줘", "자격 요건 알려줘" | 모집공고 해석자 — 원문 추출 + LLM 요약 |
| "이 공고 신청 가능해?", "내 자격 확인", "매칭 확인" | /v1/apt/match 적합도 판정 |
| "1순위 돼?", "납입횟수 충분해?", "1순위 자격" | /v1/apt/score + announcements 배열 → priority_checks |
| "캘린더에 추가해줘", "일정 저장", ".ics" | GET /v1/apt/announcements/{id}/ics → 다운로드 링크 안내 |
| "경쟁률 어때?", "몇 대 일이야?", "예상 경쟁률" | GET /v1/apt/announcements/{id}/competition 통계 추정 |
| "새로 뜬 공고", "변동 사항", "어제 대비", "최근 추가된" | GET /v1/apt/changes 변동 이력 조회 |
| "입지 분석", "주변 시설", "역세권 인지", "학군 어때" | 입지 분석 워크플로 — Apify Google Maps + WebSearch |
타임아웃
/v1/apt/announcements 호출은 반드시 --max-time 180 이상 (cold cache + apt 크롤링은 60~120초 소요 가능)/health는 --max-time 15면 충분 (하지만 기본적으로 호출 금지)URL 형식
"..."로 감싸 단일 스트링으로 전달&&로 체이닝하지 말고 curl 1개만 실행 (셸이 &를 background 연산자로 오해하거나 앞 명령 출력이 다음 요청에 섞일 수 있음)invalid request line 또는 mojibake+0건 응답 발생-G --data-urlencode "region=서울"도 이미 깨진 바이트를 받으므로 무력 — 반드시 사전 인코딩된 문자열을 URL 쿼리에 직접 박을 것서울=%EC%84%9C%EC%9A%B8 · 경기=%EA%B2%BD%EA%B8%B0 · 인천=%EC%9D%B8%EC%B2%9C부산=%EB%B6%80%EC%82%B0 · 대구=%EB%8C%80%EA%B5%AC · 광주=%EA%B4%91%EC%A3%BC대전=%EB%8C%80%EC%A0%84 · 울산=%EC%9A%B8%EC%82%B0 · 세종=%EC%84%B8%EC%A2%85python -c "import urllib.parse; print(urllib.parse.quote('강남구'))"-G --data-urlencode는 Linux/macOS UTF-8 환경에서만 허용 (Windows 금지)빈 응답 처리
{"count": 0, "announcements": []}이고 errors 필드에 특정 카테고리만 실패 기록이 있다면 → apt 등 느린 카테고리가 아직 적재 중일 가능성. 15~30초 대기 후 1회 재시도count: 0 + errors: null이면 진짜 0건 → 인접 지역 확장 제안웜업
/health 사전 호출 금지 (GitHub Actions가 12분마다 핑 중 — 단 free cron은 5~30분 지연될 수 있어 100% 보장은 아님)가점·자격 계산 규칙 (중요)
/v1/apt/score 엔드포인트를 호출할 것 (특히 통장 가점, 미성년 인정 한도)years × 2로 계산하면 틀린다{"profile": {"no_house_years": 3, "dependents": 0, "subscription_account": {"years": 7, "minor_years_post_2024": 0}, "no_house": true, "ever_owned_house": false}}{"scores": {"no_house": 8, "family": 5, "account": 9, "total": 22, "max_total": 84}, "specials": {...}}중복 알림 방지
/v1/apt/notify는 기본적으로 서버 측 7일 dedup이 켜져 있음 (dedup=true)notified.json을 읽고 exclude_ids를 채우는 작업은 불필요 (dedup이 자동 처리)dedup=false 추가공고 원문 해석 (/v1/apt/notice/{id}/raw)
id로 캐시에서 URL 자동 조회 (캐시 miss 시 ?url=<applyhome_url|lh_url> 폴백)?force_refresh=trueapplyhome.co.kr / apply.lh.or.kr / i-sh.co.kr / gh.or.krcurl -s --max-time 30 "https://k-apt-alert-proxy.onrender.com/v1/apt/notice/2026000123/raw"text·sections 필드를 LLM 컨텍스트에 포함해 분석; truncated: true이면 원문 링크 안내 필수공고 적합도 판정 (/v1/apt/match)
{"profile": {"preferred_categories": ["APT"], "preferred_regions": ["서울","경기"], "min_units": 300}, "announcements": [{"id": "...", "house_category": "APT", "region": "서울", "total_units": "641"}]}{"matches": [{"id": "...", "category_match": true, "region_match": true, "min_units_ok": true, "needs_account": true, "fit_level": "high"}], "count": N}fit_level: "high" (3/3 충족) · "medium" (2/3) · "low" (1/3 이하)1순위 자격 판정 (/v1/apt/score + announcements 배열)
/v1/apt/score POST body에 "announcements": [...] 추가 → 응답에 priority_checks 배열 포함{"profile": {"subscription_account": {"deposit_count": 18}, "no_house": true, "previous_win": "없음"},
"announcements": [{"id": "apt_001", "speculative_zone": "N", "region": "서울"}]}
{"scores": {...}, "specials": {...}, "priority_checks": [{"id": "apt_001", "eligible": true, "reason": "수도권 1순위 충족 (납입 18회 ≥ 12회)", "required_count": 12, "user_count": 18, "zone": "수도권", "warnings": [...]}]}청약 일정 캘린더 다운로드 (/v1/apt/announcements/{id}/ics)
"캘린더에 추가하려면 이 링크를 브라우저에서 열거나 구글 캘린더 → 다른 캘린더 → URL로 구독하세요: https://k-apt-alert-proxy.onrender.com/v1/apt/announcements/{id}/ics"경쟁률 조회 (/v1/apt/announcements/{id}/competition) — 3단 폴백
?history=true 추가 시, 공공데이터포털 결과 API 기반 같은 지역 최근 12개월 실제 경쟁률 평균# 기본 (실제 결과 → 통계 추정 폴백)
curl -s --max-time 15 "https://k-apt-alert-proxy.onrender.com/v1/apt/announcements/{id}/competition"
# 지역 이력 활용 (마감 전 공고에 권장)
curl -s --max-time 15 "https://k-apt-alert-proxy.onrender.com/v1/apt/announcements/{id}/competition?history=true"
source 필드로 어느 단계가 응답했는지 식별:
source: "applyhome" — 실제 결과 (가장 정확)source: "regional_history" — 같은 지역 실제 평균 (history, avg_rate, avg_cutoff_score, most_recent, history_count)source: "statistical_estimate" + data_type: "통계 추정치" — 폴백 추정 (avg_rate, avg_cutoff_score, note)disclaimer 그대로 노출 (실제 vs 추정 여부 구분 명시)공고 변동 추적 (/v1/apt/changes)
since=YYYY-MM-DD — 이 날짜 이후 변경만change_type=new|updated|removed — 종류 필터limit=N (기본 50, 최대 200)# 최근 7일 신규 공고만
curl -s --max-time 15 "https://k-apt-alert-proxy.onrender.com/v1/apt/changes?since=2026-04-29&change_type=new"
# 어제 갱신 모두
curl -s --max-time 15 "https://k-apt-alert-proxy.onrender.com/v1/apt/changes?since=2026-05-05"
tracking_status 분기:
"ready" + count>0 → 정상. 변경 항목 출력"ready" + count=0 → 진짜 변동 없음 → "어제 대비 신규 공고 없습니다" 안내"bootstrap_no_diff_yet" → 추적 막 시작 → "📅 변동 추적이 막 시작됐어요. {first_diff_date}부터 변경사항이 표시됩니다" 안내status: "not_yet_initialized" → data 브랜치 자체가 없는 초기 상태new — 어제 없던 공고. id·이름·지역·url 표시updated — field_changes 객체로 어떤 필드가 어떻게 바뀌었는지 ({before, after})removed — 마감 또는 삭제된 공고최소 호출 원칙
category와 region만 지정해서 단일 호출실패 메시지
Exit code 28 (timeout): "프록시가 기동 중이거나 첫 조회라 시간이 걸립니다. 1~2분 후 다시 시도해주세요.""Invalid HTTP request": 셸 인용 문제 — URL을 "..."로 다시 감싸 재시도🟢·🟡·🔴·⚪는 의미가 용도별로 다르므로 반드시 범례와 함께 사용한다. 혼자 나열하면 사용자가 뭔 뜻인지 모른다.
| 용도 | 위치 | 범례 표기 방식 |
|---|---|---|
| 당첨 가능성 | Top 3 번호 옆 | ※ 항목 옆 이모지 = 당첨 가능성 (🟢 높음 · 🟡 보통 · 🔴 낮음 · ⚪ 판정불가) |
| D-day 긴급도 | 테이블 D-day 컬럼 | ※ D-day 색: 🔴 ≤D-1 · 🟡 ≤D-3 · 🟢 ≥D-4 |
| 프로필 매칭도 | 테이블 매칭 컬럼 | ※ 매칭: 🟢 강력 추천 · 🟡 조건부 · 🔴 제외 |
📋 프로필: 만 28세 / 서울·경기·인천 / 무주택 / 통장 3년
📢 접수 중 공고 (3건):
| 이름 | 지역 | D-day | 세대수 | 타입 |
|---------------------|-----------|-------|-------|--------|
| 인천가정2지구 B2블록 | 인천 서구 | D-13 | 308 | APT |
| 동탄 그웬 160 | 경기 화성 | D-12 | 160 | APT |
| 용인 고림 동문 디 이스트 | 경기 처인구 | D-5 | 350 | APT |
💡 더 보려면: '내 조건에 맞는 추천' / '내 가점' / '청약 가이드'
이 원칙이 아래 상세 규칙들보다 우선한다. 아래 규칙은 사용자가 명시 요청했을 때만 적용.
/korea-apt-alert setup적용 시점: 사용자가 "청약이 뭐야", "처음", "초보", "모르겠", "설명해줘", "가이드" 등의 키워드를 명시적으로 사용할 때만. 공고 조회 요청에는 이 섹션을 출력하지 않는다.
새로 짓는 아파트(신축)를 분양받기 위해 신청하는 제도입니다. 추첨 또는 가점(점수) 방식으로 당첨자를 선정하며, 당첨되면 시세보다 저렴하게 내 집을 마련할 수 있습니다.
| 용어 | 뜻 |
|---|---|
| 청약통장 (주택청약종합저축) | 청약 신청에 필요한 전용 저축 통장. 대부분의 APT 청약에 필수. 가입 기간과 납입 횟수가 가점에 반영됨 |
| 가점제 | 무주택 기간 + 부양가족 수 + 통장 가입기간을 점수화(최대 84점)하여 높은 점수 순으로 당첨자 선정 |
| 추첨제 | 자격을 갖춘 신청자 중 무작위 추첨. 가점이 낮아도 당첨 가능. 85m² 초과 타입에 주로 적용 |
| 특별공급 | 신혼부부, 다자녀, 생애최초 구매자 등에게 별도 물량을 배정하는 제도. 일반공급보다 경쟁률이 낮은 경우가 많음 |
| 일반공급 | 특별공급 이후 남은 물량을 1순위·2순위로 나눠 모집 |
| 무주택세대구성원 | 세대원 전원이 주택을 소유하지 않은 상태. 대부분의 청약 자격 요건 |
| 투기과열지구 | 정부가 지정한 부동산 과열 지역. 가점제 비율 100%, 전매 제한, 거주의무 등 규제 강화 |
| 분양가상한제 | 정부가 분양가를 제한하는 제도. 시세 대비 저렴하지만 거주의무기간(2~5년)이 부여됨 |
| 전용면적 | 실제 거주 공간 면적. 소형(<60m²/ |
통장이 있나요?
├── YES → 무주택인가요?
│ ├── YES → APT 일반분양, LH 공공분양 가능!
│ │ (+ 특별공급 자격도 확인해보세요)
│ └── NO → 갈아타기: 일부 조건부 청약 가능
│ (+ 오피스텔, 잔여세대는 무주택 불문)
└── NO → 걱정 마세요! 통장 없이도 가능한 유형이 있어요
→ 오피스텔/도시형, 잔여세대, 임의공급 (선착순)
이 스킬은 아래 항목을 로컬에만 저장하며, 프록시 서버나 외부로 전송하지 않습니다.
~/.config/k-skill/apt-alert-profile.json / favorites.json / notified.json/korea-apt-alert profile --delete 또는 파일 직접 삭제파일 권한 설정 (권장) — 프로필 저장 직후 본인만 읽기·쓰기 가능하도록:
chmod 600 ~/.config/k-skill/*.json
Windows 사용자는 파일 속성 → 보안 탭에서 본인 계정만 권한 부여.
~/.config/k-skill/apt-alert-profile.json
프로필(또는 favorites/notified) 파일을 작성/갱신할 때마다 Unix 계열 OS는 권한을 600으로 자동 설정한다. Windows는 기본 사용자 프로필 폴더가 이미 본인 한정이므로 별도 조치 불필요.
Claude 실행 책임 (자동):
# Unix/macOS/WSL
chmod 600 ~/.config/k-skill/*.json 2>/dev/null || true
# Windows: %USERPROFILE%\.config\k-skill\ 폴더가 이미 사용자 한정이므로 skip
프로필을 편집한 모든 작업(설치·setup·부분 업데이트·favorites 추가) 끝에 이 명령을 실행한다.
profile --delete)사용자가 "프로필 삭제", "내 정보 지워", profile --delete 등을 요청하면:
~/.config/k-skill/apt-alert-profile.json 삭제favorites.json / notified.json도 함께 삭제 여부 확인setup)사용자가 "프로필 설정", "setup", "내 정보 등록" 등을 요청하면 아래 항목을 대화형으로 하나씩 물어본다. 모르거나 건너뛰고 싶은 항목은 null로 저장한다.
답변 형식 일반 규칙:
(a) ~ (e) 목록은 기본 단일 선택. "복수 선택 가능" 명시된 항목만 다중 응답 허용질문 표시 형식 (필수 통일):
**질문 N/12.** [질문 내용] 형식으로 출력**질문 1/12.** 출생연도를 알려주세요 (예: 1998)**질문 10/12.** 과거 청약 당첨 이력이 있으신가요?1. 출생연도
age 필드에 저장2. 선호 지역 (복수 선택)
3. 가구 구성
4. 무주택 여부
참고: "무주택"은 본인뿐 아니라 배우자·세대원 전원의 주택 소유 여부를 포함합니다.
5. 청약통장
6. 연소득 구간 (세대 합산)
7. 선호 평형 (복수 선택 가능)
예시 답변: "소형, 중형" / "a,b" / "전부"
8. 혼인신고 연월 (가구 구성이 신혼부부/기혼인 경우만)
9. 현재 거주 지역 + 거주 기간
10. 과거 청약 당첨 이력
11. 부양가족 수 (가점 계산용)
12. 임신 여부 (다자녀 판정 보정)
기존 프로필이 있는 상태에서 "혼인신고일만 수정", "자녀 수 업데이트" 같은 부분 변경을 요청하면:
~/.config/k-skill/apt-alert-profile.json 로드updated_at을 오늘 날짜로 갱신setup --reset으로 초기화트리거 키워드: "프로필 업데이트", "수정", "변경", "바꿔줘", setup --field=X
{
"birth_year": 1995,
"age": 31,
"regions": ["서울", "경기", "인천"],
"household": {
"type": "newlywed",
"children_count": 0
},
"homeless": true,
"housing_count": 0,
"subscription_account": {
"has_account": true,
"years": 5,
"deposit_count": 60
},
"annual_income": "5천~7천만원",
"income_bracket": "mid",
"preferred_size": ["소형", "중형"],
"marriage_date": "2023-03",
"residence_region": "서울",
"residence_years": 5,
"previous_win": "없음",
"dependents_count": 1,
"pregnant": false,
"updated_at": "2026-04-16"
}
필드 값 참조:
household.type: "single" | "newlywed" | "married_no_child" | "married_with_child" | "single_parent"income_bracket: "low" (≤3천) | "mid_low" (3천"mid" (5천"mid_high" (7천~1억) | "high" (>1억) | nullhousing_count: 0 (무주택) | 1 (1주택) | 2+ (다주택)previous_win: "없음" | "5년이내" | "5년초과"프로필 로드 시 updated_at을 확인한다.
프로필이 있으면 아래 로직으로 추천 유형을 자동 판정한다.
| 카테고리 | 청약통장 | 무주택 | 소득 기준 | 추천 대상 |
|---|---|---|---|---|
| APT 일반분양 | 필수 (가입 2년+, 지역별 상이) | 필수 | 없음 | 통장 보유 + 무주택 |
| 오피스텔/도시형 | 불필요 | 불필요 | 없음 | 누구나 (만 19세+) |
| LH 공공분양 | 필수 (가입 6개월+) | 필수 | 가구원수별 소득 기준 | 통장 보유 + 무주택 + 소득 충족 |
| APT 잔여세대 | 불필요 | 불필요 | 없음 | 누구나 |
| 공공지원민간임대 | 불필요 | 필수 | 가구원수별 소득 기준 | 무주택 + 소득 충족 |
| 임의공급 | 불필요 | 불필요 | 없음 | 누구나 (선착순) |
housing_count >= 1인 사용자를 완전 배제하지 않는다. 대신:
소득 기준 판정 시 가구원 수에 따라 기준이 다름을 반드시 안내한다:
| 가구원 수 | 도시근로자 평균소득 기준 |
|---|---|
| 3인 이하 | 월평균 소득의 100% |
| 4인 | 월평균 소득의 110% (일부 120%) |
| 5인 이상 | 월평균 소득의 120% (일부 130%) |
프로필의 income_bracket과 household.children_count + 배우자 포함 세대원 수를 기반으로 대략적 판정 후, 반드시 아래 경고를 추가:
⚠️ 소득 자격은 자동 확인이 불가합니다. 정확한 도시근로자 평균소득 기준(연도별·가구원수별)은 공고 원문에서 확인하세요.
가구원 수 자동 계산 공식:
본인 1명
+ 배우자 (household.type이 newlywed/married_*인 경우 +1)
+ 자녀 수 (children_count)
+ 태아 (pregnant=true이면 +1)
= 총 가구원 수
정성적 공공분양 통과 판정:
| income_bracket | 3인 이하 | 4인 | 5인 이상 |
|---|---|---|---|
| low / mid_low / mid | ✓ | ✓ | ✓ |
| mid_high (7천~1억) | ✗ | ✓ | ✓ |
| high (1억+) | ✗ | ✗ | ✗ (일부 ✓) |
⚠️ 정성 판정입니다. 공고별 실제 기준금액은 가구원수 × 도시근로자 월평균소득으로 계산하세요.
도시근로자 월평균소득 기준 원화 (2024년 공시 기준, 세전)
| 가구원수 | 100% (월) | 120% (월) | 140% (월) |
|---|---|---|---|
| 3인 이하 | 약 6,530,602 | 약 7,836,722 | 약 9,142,843 |
| 4인 | 약 7,620,056 | 약 9,144,067 | 약 10,668,078 |
| 5인 | 약 7,954,359 | 약 9,545,231 | 약 11,136,103 |
| 6인 | 약 8,715,780 | 약 10,458,936 | 약 12,202,092 |
적용 기준 유형별:
연봉(income_bracket)을 12로 나눠 월 소득으로 변환 후 위 표와 비교. 예: mid_high(7천1억) → 월 583만833만 → 4인 이상 가구 기준 100%/120% 통과 가능.
⚠️ 2024년 공시 수치이며 2026년 공고에는 갱신된 기준이 적용됩니다. 실제 당첨 자격은 공고문에 명시된 해당 연도 기준표를 반드시 확인하세요.
프로필 기반으로 해당하는 특별공급 유형을 안내한다.
| 특별공급 | 판정 로직 | 추가 안내 |
|---|---|---|
| 신혼부부 | marriage_date 존재 + 혼인 7년 이내 계산 + 무주택 + 소득 기준 | ⚠️ 혼인신고일 기준. 예혼·사실혼은 별도 확인 필요 |
| 생애최초 | 무주택 + 소득 기준 + previous_win = "없음" + 청약통장 보유 + 가입기간 ≥ 2년 | ⚠️ 5년 이상 소득세 납부 여부는 자동 확인 불가. 통장 미보유/2년 미만이면 자격 없음 |
| 다자녀 | (children_count + pregnant) >= 2 + 무주택 | 미성년 자녀 기준. pregnant=true면 태아 1명 가산 |
| 한부모(기관추천) | household.type = single_parent + 무주택 | ⚠️ 한부모가족지원법 보호 대상 증명 필요. 증빙은 공고문 확인 |
| 노부모 부양 | age >= 25 | ⚠️ 만 65세 이상 직계존속 3년 이상 부양 요건은 프로필로 확인 불가 |
| 기관 추천 (기타) | 해당 여부 확인 불가 | 국가유공자, 장애인, 이주민 등 해당 시 공고문 확인 |
특별공급 자격 판정 후 반드시:
⚠️ 특별공급 자격은 추정입니다. 세부 요건(증빙서류, 소득세 납부 이력, 자산 기준 등)은 공고문에서 확인하세요.
프로필 기반으로 추정 가점을 계산하여 안내한다.
가점 산정 기준 (최대 84점):
| 항목 | 점수 | 프로필 기반 계산 |
|---|---|---|
| 무주택 기간 (최대 32점) | 1년당 2점, 최초 1년 미만 2점 | 만 30세 도달연도 ↔ 혼인신고연도 중 늦은 해부터 기산. 만 30세 이전 미혼자는 0점, 만 30세 이전 결혼자도 30세 전까지는 0점 |
| 부양가족 수 (최대 35점) | 0명=5점, 1명=10점, 2명=15점 ... 6명+=35점 | dependents_count 기반. ⚠️ 직계존속(부모·조부모)은 3년 이상 동일 세대 등록된 경우에만 인정되며, 자동 확인 불가 — 공고문 확인 필수 |
| 통장 가입기간 (최대 17점) | 6개월 미만=1점, 6개월~1년=2점, 그 이후 1년당 1점 | subscription_account.years 기반. 5년→7점, 10년→12점, 15년+=17점. ⚠️ 만 19세 미만 가입분은 최대 5년만 인정 (2024.7.1. 시행, 그 이전엔 2년) — 미성년자 조기가입자는 19세 이전 기간 중 5년 초과분 차감 |
가점 안내 메시지 예시:
📊 추정 가점: 약 47점 / 84점
- 무주택 기간: 약 22점 (만 41세, 11년 추정)
- 부양가족: 15점 (2명)
- 통장 가입기간: 10점 (5년)
ℹ️ 실제 가점은 청약홈에서 정확히 조회 가능합니다.
적용 시점: "내 가점", "가점 계산", "맞춤 추천" 등을 명시 요청했을 때만. 기본 간결 응답에는 포함하지 않는다.
추정 가점에 따라 현실적 전략 메시지를 함께 출력한다.
| 추정 가점 | 전략 메시지 |
|---|---|
| 0~20점 | "⚠️ 가점이 낮아 수도권 APT 가점제 당첨은 현실적으로 어렵습니다. 오피스텔·잔여세대·임의공급(무순위/선착순), 지방 중소도시 APT, 특별공급(신혼·생애최초·다자녀)이 더 유리합니다." |
| 20~40점 | "ℹ️ 지방 중소도시 APT 가점제는 가능권. 수도권은 추첨제 비중 높은 85m² 초과 대형 타입이나 특별공급을 노리세요." |
| 40~60점 | "✅ 수도권 일반 지역 APT 가점제 당첨 가능권. 서울·1군 브랜드·주요 입지는 여전히 어려울 수 있습니다." |
| 60~75점 | "🎯 수도권 주요 입지도 도전 가능. 투기과열지구 가점 커트라인(보통 60~70점) 근처입니다." |
| 75점+ | "🏆 서울 강남·서초 등 최상위 입지도 가능. 가점제 경쟁에서 상위권입니다." |
이 메시지는 프로필이 있고 APT 일반분양이 Top 3에 포함된 경우에 반드시 포함한다.
가점 관련 추가 안내:
적용 시점: 사용자가 "당첨 가능성", "내가 될 가능성", "경쟁률" 등을 명시 요청할 때만. 기본 응답에는 포함하지 않는다.
각 공고에 대해 프로필 + 공고 정보를 조합하여 정성적 당첨 가능성을 판정한다.
판정 기준:
| 요소 | 데이터 출처 | 판정 로직 |
|---|---|---|
| 투기과열지구 | speculative_zone | "Y"이면 가점제 100% → 가점 낮으면 "낮음" |
| 평형 (가점/추첨) | size | 85m² 이하=가점 우선, 초과=추첨 비중 높음 |
| 세대수 | total_units | 500세대+ = 물량 많아 경쟁 분산 |
| 내 가점 | 프로필 기반 | 추정 가점과 지역 평균 비교 |
| 1군 건설사 | constructor | 1군이면 경쟁 치열 → 가점 커트라인 상승 |
판정 결과 (공고별 표시):
🟢 당첨 가능성 높음
- 비투기과열지구 + 추첨제 비율 높음 (85m²+)
- 또는 내 가점이 지역 평균 이상 + 대단지
🟡 당첨 가능성 보통
- 가점제 비율 높지만 내 가점이 지역 평균 근처
- 또는 1군 건설사이지만 비수도권
🔴 당첨 가능성 낮음
- 투기과열지구 + 가점제 100% + 내 가점 낮음
- 또는 수도권 + 1군 건설사 + 소형 (경쟁 치열)
⚪ 판정 불가
- 프로필 없음, 또는 가점 불필요 유형 (오피스텔, 잔여세대, 임의공급)
가점 불필요 유형(오피스텔, 잔여세대, 임의공급)은 판정 대신:
지역별 참고 가점 범위 (경험적 가이드라인):
| 지역 | 소형(~60m²) | 중형(60~85m²) | 대형(85m²+) |
|---|---|---|---|
| 서울 | 55~70점 | 50~65점 | 추첨 위주 |
| 경기 (과천/판교 등) | 50~65점 | 45~60점 | 추첨 위주 |
| 경기 (기타) | 35~50점 | 30~45점 | 추첨 위주 |
| 인천 | 30~45점 | 25~40점 | 추첨 위주 |
| 부산/대구/광주 | 25~40점 | 20~35점 | 추첨 위주 |
| 기타 지방 | 15~30점 | 10~25점 | 추첨 위주 |
⚠️ 위 가점 범위는 경험적 참고치입니다. 실제 커트라인은 공고마다 크게 다를 수 있습니다.
프록시 API가 각 공고에 d_day(마감까지 남은 일수)와 d_day_label(표시 문자열)을 자동 포함한다.
| d_day | d_day_label | 의미 |
|---|---|---|
| 음수 | "마감" | 이미 마감된 공고 |
| 0 | "D-Day (오늘 마감)" | 오늘이 마감일 |
| 1~3 | "D-1" ~ "D-3" | 마감 임박 |
| 4+ | "D-N" | 여유 있음 |
결과 출력 시:
예상 일정 안내 (공고 하단에 포함):
📌 참고 일정 (일반적 기준):
- 특별공급 접수 → 다음 날 1순위 → 그 다음 날 2순위
- 당첨자 발표: 접수 마감 후 약 7~10일
- 계약: 당첨자 발표 후 약 1~2주 내
- 입주: 공고문에 명시된 입주 예정 시기 확인
적용 시점: 사용자가 특정 공고를 지목하며 "이 공고 분석해줘", "자격 요건 알려줘", "공고 해석해줘", "이 공고 신청 가능해?" 등을 명시 요청할 때. 기본 공고 목록 조회에는 이 워크플로우를 실행하지 않는다.
1. 공고 ID 확인
- 테이블의 id 필드 또는 사용자가 언급한 공고명/ID 사용
- id 모를 경우: 먼저 /v1/apt/announcements로 조회해서 id 확보
2. 원문 텍스트 추출
curl -s --max-time 30 \
"https://k-apt-alert-proxy.onrender.com/v1/apt/notice/{id}/raw"
# 캐시 miss 시 url 폴백:
curl -s --max-time 30 \
"https://k-apt-alert-proxy.onrender.com/v1/apt/notice/{id}/raw?url=https://www.applyhome.co.kr/..."
3. 응답 구조
{
"id": "2026000123",
"title": "래미안 원펜타스 입주자모집공고",
"text": "...(최대 30,000자)...",
"sections": {
"자격": "...",
"공급일정": "...",
"공급금액": "...",
"유의사항": "..."
},
"truncated": false,
"char_count": 12345
}
4. LLM 분석
- 자격 요건: sections["자격"] 위주
- 일정 확인: sections["공급일정"]
- 가격대: sections["공급금액"]
- 유의사항: sections["유의사항"]
- sections가 비어있으면 text 전체에서 관련 부분 발췌
truncated: true이면 반드시 → "공고 원문이 길어 일부만 추출됐습니다. 전체는 응답의 url 필드 링크에서 확인하세요."id 조회 실패) 시 → 사용자에게 url 직접 전달 요청ℹ️ 자동 추출 텍스트 기반 요약입니다. 정확한 내용은 원문에서 확인하세요.📄 [래미안 원펜타스] 공고 분석
📌 자격 요건
- 무주택세대구성원 (세대원 전원 무주택)
- 청약통장 가입 2년 이상 / 납입 24회 이상
- 서울 2년 이상 거주자 우선
📅 공급일정
- 특별공급: 2026-04-15 / 일반 1순위: 2026-04-16
- 당첨자 발표: 2026-04-25 / 계약: 2026-05-09 ~ 2026-05-11
💰 공급금액
- 84m² 기준 약 12억 (분양가상한제 적용)
⚠️ 유의사항
- 거주의무기간 3년 / 전매 제한 5년
ℹ️ 자동 추출 텍스트 기반 요약입니다. 정확한 내용은 [청약홈 원문 →](url)에서 확인하세요.
적용 시점: 사용자가 특정 단지에 대해 "입지 분석", "주변 시설", "역세권인지", "학군 어때", "이 동네 괜찮아?" 등을 명시 요청할 때.
청약 공고의 주소를 바탕으로 주변 인프라(지하철·학교·마트·병원·공원)와 지역 호재를 종합 보고한다. 외부 지도 API 도구가 필요하며, Apify Google Maps Scraper(MCP 커넥터)가 가장 정확하다.
런타임별 설치 방법이 다르지만 원리는 동일.
Claude Desktop:
compass/crawler-google-places 추가Claude Code:
claude mcp add apify --scope user --transport sse \
"https://mcp.apify.com/sse?actors=compass/crawler-google-places" \
--header "Authorization: Bearer <YOUR_APIFY_TOKEN>"
claude mcp list → apify: ... ✓ Connected 보이면 끝Codex CLI:
~/.codex/config.toml에 [mcp_servers.apify] 블록 추가 (TOML 형식, headers는 별도 섹션)설정 안 된 경우 → WebSearch와 LLM 일반 지식으로 추정 보고 (정확도 ↓, "추정" 명시 필수).
1. 분석 대상 확인
- 사용자가 단지명 또는 공고 ID를 지정
- "강남자이르네" 또는 "id 2026000123 입지 분석"
2. 주소 추출
- 캐시된 공고면: GET /v1/apt/announcements 응답의 address 필드
- 캐시 미스면: GET /v1/apt/notice/{id}/raw 본문에서 주소 추출
3. 좌표·주변 시설 검색 (Apify 사용 가능 시)
도구: compass/crawler-google-places
**권장: 2-step 방식 (정확도 높음)**
- Step 3a — 단지 좌표 확보:
`searchStringsArray: ["{단지명}"]`, `maxCrawledPlacesPerSearch: 1`
→ 응답의 `location.lat / location.lng` 추출
- Step 3b — 좌표 기준 주변 검색:
`searchStringsArray: ["{단지명} 주변 지하철역", "{단지명} 주변 초등학교", ...]`
→ 각 카테고리당 3~5건
→ 결과의 lat/lng로 단지 좌표와 Haversine 거리 계산 → 도보 시간 추정 (1분당 80m)
**간단: 1-step 자연어 검색 (빠름, 정확도 ↓)**
- `searchStringsArray: ["{주소} 주변 지하철역", "{주소} 주변 초등학교", ...]`
- 결과는 lat/lng만 와서 거리 정보 별도 계산 필요
**주의:**
- "지하철역" 검색에 "버스정류장"이 섞일 수 있음 → `categoryName` 필드로 후필터링
- 신축 단지는 Google Maps에 없을 수 있음 → 그럼 주소만으로 검색
- 응답 시간: 카테고리당 30~60초, 5개 카테고리면 2~5분 소요
4. 지역 호재 (WebSearch)
- "{지역명} 교통 호재 2026"
- "{지역명} 개발 계획 산업단지"
- "{학교명} 학군"
5. 종합 보고서 작성 (아래 출력 형식 참고)
🏠 [단지명] 입지 분석
📍 주소: [전체 주소]
좌표: [lat, lng]
🚇 교통
- [역명] · [호선] · 도보 X분 (M)
- [역명] · [호선] · 도보 Y분 (M)
※ 도보 시간은 1분당 80m 기준 추정
🏫 학군
- 초: [학교명] (도보 X분)
- 중: [학교명] (도보 Y분)
- 고: [학교명] (도보 Z분)
※ 학교 등급·평판은 별도 확인 필요
🛒 편의시설 (반경 1.5km)
- 대형마트: [이름] (X분)
- 병원: [이름] (Y분)
- 공원: [이름] (Z분)
📈 지역 호재 (WebSearch 기반)
- 교통: [예: GTX-A 노선 2027 개통]
- 개발: [예: ○○ 산업단지 조성]
- 학군: [평판 정보]
🎯 종합 평가
- 강점: [역세권/학군/대단지 등]
- 약점: [상권 거리/노후 여부 등]
⚠️ 자동 추출·검색 결과 기반 추정입니다. 실제 입주 결정은 현장 답사·전문가 자문 필수.
(추정 보고서 — 외부 지도 도구 미사용) 명시관심 공고를 로컬에 저장하여 변동 추적·중복 조회 방지에 활용한다.
~/.config/k-skill/favorites.json
{
"ids": ["2026000123", "2026000456"],
"added_at": {
"2026000123": "2026-04-17",
"2026000456": "2026-04-20"
},
"notes": {
"2026000123": "신혼부부 특공 관심"
}
}
| 트리거 | 동작 |
|---|---|
"즐겨찾기에 추가", fav add <ID> | ids에 추가, added_at 오늘 날짜 저장 |
"즐겨찾기 목록", fav list | 저장된 모든 공고 → 프록시에서 현재 상태 조회 → D-day·마감 여부 갱신 |
"즐겨찾기 제거", fav remove <ID> | ids에서 제거 |
"관심 공고 변동 체크", fav diff | 저장된 ID 중 마감 임박/마감/당첨발표 등 상태 변동 공고 하이라이트 |
구현 힌트: fav list는 GET /v1/apt/announcements?category=all&active_only=false 호출 후 ids와 교집합.
v2.7 이후:
/v1/apt/notify의 서버 측 7일 dedup (dedup=true기본)이 자동으로 중복 발송을 차단합니다. 아래 로컬notified.json관리는 선택 사항이며, Render 서버 재시작 시 서버 dedup 기록이 초기화될 수 있으므로 중요 알림은 병행 관리를 권장합니다.
같은 공고를 여러 번 발송하지 않도록 로컬에서 발송 이력을 관리한다.
~/.config/k-skill/notified.json
{
"2026000123": "2026-04-17",
"2026000456": "2026-04-15"
}
키 = 공고 ID, 값 = 마지막 발송 날짜 (YYYY-MM-DD)
notified.json 로드notified.json에 해당 ID가 있고, 발송일 기준 7일 이내면 제외d_day == 0(D-Day) 공고는 재발송 허용 (긴급)notified.json 갱신프록시의 exclude_ids 파라미터에 7일 이내 발송 완료된 ID 목록을 넘기면 서버 사이드에서도 사전 제외 가능:
POST /v1/apt/notify?...&exclude_ids=2026000123,2026000456
⚠️ 기본 동작은 1회성입니다.
/korea-apt-alert 알림 보내줘는 그 시점에 한 번만 Slack/Telegram으로 발송합니다. 매일 자동 발송하려면 아래 3가지 방법 중 하나를 별도 설정해야 합니다.
| 상황 | 권장 방법 |
|---|---|
| 가끔 생각날 때마다 조회·알림 | 매번 /korea-apt-alert 알림 보내줘 (자동화 불필요) |
| 매일 아침 체크하고 싶음 | 방법 2 (GitHub Actions) — 가장 견고 |
| Claude Code 세션 항상 열어두는 편 | 방법 1 (/loop) — 간단하지만 세션 꺼지면 중단 |
| 로컬 PC 항상 켜둠 | 방법 3 (cron / Task Scheduler) — 로컬 스케줄러 |
사용자가 "매일", "자동", "정기", "스케줄" 등을 언급하면 위 선택지 표를 먼저 보여주고 어떤 방법 원하는지 확인한다.
/loop (세션 내 반복)Claude Code 터미널에서:
/loop 24h /korea-apt-alert 내 조건에 맞는 청약 알림 보내줘
매 24시간마다 자동 조회 + Slack/Telegram 발송. Claude Code 세션이 열려 있어야 동작.
프록시 서버의 /v1/apt/notify 엔드포인트를 외부 스케줄러에서 호출:
# cron, GitHub Actions, n8n 등에서 매일 아침 호출
curl -X POST "https://k-apt-alert-proxy.onrender.com/v1/apt/notify?webhook_url=https://hooks.slack.com/services/T.../B.../xxx®ion=서울,경기,인천&active_only=true"
GitHub Actions 예시 (.github/workflows/apt-notify.yml):
name: Daily Apt Alert
on:
schedule:
- cron: '0 22 * * *' # 매일 오전 7시 (KST)
workflow_dispatch:
jobs:
notify:
runs-on: ubuntu-latest
steps:
- name: Send notification
run: |
curl -X POST "${{ secrets.PROXY_URL }}/v1/apt/notify?webhook_url=${{ secrets.SLACK_WEBHOOK }}®ion=서울,경기,인천&active_only=true"
파라미터:
| 파라미터 | 설명 |
|---|---|
webhook_url | Slack Webhook URL — 전체 fallback (지역별 미매핑 공고는 이걸로) |
webhook_seoul | 서울 공고 전용 Slack Webhook (옵션) |
webhook_gyeonggi | 경기 공고 전용 Slack Webhook (옵션) |
webhook_incheon | 인천 공고 전용 Slack Webhook (옵션) |
webhook_busan | 부산 공고 전용 Slack Webhook (옵션) |
webhook_highlight | 긴급(d_day≤1) 공고 별도 채널 — 지역 채널과 추가로 한 번 더 발송 |
telegram_token | Telegram Bot Token (Telegram 발송 시) |
telegram_chat_id | Telegram Chat ID (Telegram 발송 시, token과 세트) |
category | 카테고리 필터 (기본: all, 8종: apt/officetell/lh/remndr/pbl_pvt_rent/opt/sh/gh) |
region | 지역 필터 (쉼표 구분) |
district | 세부 지역 필터 (쉼표 구분) |
months_back | 조회 기간 (개월, 기본: 2, 최대: 12) — 최근 N개월 이내 공고만 |
active_only | 접수 중인 공고만 (기본: true) |
min_units | 최소 세대수 (대단지만 필터, 기본 0) |
constructor_contains | 시공사 키워드 필터 (쉼표 구분) |
exclude_ids | 제외할 공고 ID (중복 알림 방지) |
reminder | 리마인더 타입: d3 / d1 / winners / contract |
채널 선택:
webhook_url 단독 → 모든 공고가 한 채널로 (가장 간단)webhook_seoul/webhook_gyeonggi 등 + webhook_url → 지역별 라우팅 + 외 지역은 fallbackwebhook_highlight 추가 → d_day≤1 공고는 지역 채널 + highlight 채널 양쪽 발송telegram_token + telegram_chat_id → Telegram (채널 라우팅 없이 단일 chat_id)multi-channel 발송 응답 예시:
{
"sent": 7,
"channels": ["slack:ABC123", "slack:DEF456", "slack:HIGHLT", "telegram"],
"sent_counts": {"slack:ABC123": 3, "slack:DEF456": 2, "slack:HIGHLT": 1, "telegram": 1}
}
응답의 slack:XXXXXX 라벨은 webhook URL의 마지막 6자로 식별 (전체 URL 노출 방지).
400 Bad Request응답 예:
{"sent": 5, "channels": ["slack", "telegram"], "errors": null, "message": "Sent to slack, telegram"}
한쪽 실패 시 errors에 사유 기록되고 성공한 채널만 channels에 남음.
D-day 기준 마감 임박순 정렬, 최대 10건 발송. D-1 이하는 🔴, D-3 이하는 🟡 표시.
로컬 PC에서 주기적으로 프록시 notify 엔드포인트를 호출.
macOS / Linux (cron) — crontab -e에 추가:
0 7 * * * curl -sS --max-time 60 -X POST "https://k-apt-alert-proxy.onrender.com/v1/apt/notify?webhook_url=$(grep ^KSKILL_APT_SLACK_WEBHOOK= ~/.config/k-skill/secrets.env | cut -d= -f2-)®ion=서울,경기,인천&reminder=d3" >> ~/.config/k-skill/apt-alert.log 2>&1
Windows Task Scheduler:
powershell.exe -Command "Invoke-RestMethod -Uri 'https://k-apt-alert-proxy.onrender.com/v1/apt/notify?webhook_url=...®ion=...&reminder=d3' -Method Post"PC 꺼진 시간엔 발송 안 됨. 항상 돌아가는 환경 필요.
reminder | 의미 | 추천 cron |
|---|---|---|
d3 | 마감 D-3 이하 임박 공고 | 매일 오전 7시 |
d1 | 마감 D-1 이하 초긴급 공고 | 매일 오전·오후 2회 |
winners | 접수 마감 후 7~10일 (당첨자 발표 예정) | 매일 오후 6시 |
contract | 접수 마감 후 14~21일 (계약 체결 예정) | 주 1회 |
예시: 매일 오전 7시 D-3 임박 공고 알림
curl -X POST ".../v1/apt/notify?webhook_url=...®ion=서울&reminder=d3"
없음. 프록시 서버가 공공데이터포털 API 키를 관리하므로 사용자는 별도 키가 불필요하다.
Slack 또는 Telegram으로 알림을 받으려면 ~/.config/k-skill/secrets.env에 설정:
KSKILL_APT_SLACK_WEBHOOK=https://hooks.slack.com/services/T.../B.../xxx
KSKILL_APT_TELEGRAM_TOKEN=123456789:ABCdefGHIjklMNOpqrsTUVwxyz
KSKILL_APT_TELEGRAM_CHAT_ID=-1001234567890
사용자가 채팅창에 Slack Webhook URL 또는 Telegram Bot Token/Chat ID를 그대로 붙여넣으면 Claude는 무조건 자동 감지하여 secrets.env에 저장한다. "직접 파일에 넣으세요" 같은 수동 안내는 금지.
패턴 감지 (최우선 적용):
| 패턴 | 저장 키 | 후속 동작 |
|---|---|---|
https://hooks.slack.com/services/... | KSKILL_APT_SLACK_WEBHOOK | 확인 후 저장 종료 |
\d{8,10}:[A-Za-z0-9_-]{30,} (Bot Token 형식) | KSKILL_APT_TELEGRAM_TOKEN | 즉시 chat_id 추가 질문 |
-100\d{10} 또는 단독 숫자 ID | KSKILL_APT_TELEGRAM_CHAT_ID | 확인 후 저장 종료 |
동작 순서 (모든 패턴 공통):
Slack Webhook 감지 / Telegram Bot Token 감지 / Telegram Chat ID 감지~/.config/k-skill/secrets.env에 저장할까요? (yes/no)"secrets.env의 해당 키만 덮어쓰기 (다른 키 보존), 없으면 새로 생성chmod 600 자동 실행 (Unix 계열, Windows는 스킵)-1001234567890, 숫자 그대로 붙여넣기 OK)"자동 저장 예시 (Bash):
# 기존 라인 제거 후 새 값 추가 (key-safe)
save_secret() {
local KEY="$1"
local VAL="$2"
local FILE="$HOME/.config/k-skill/secrets.env"
mkdir -p "$(dirname "$FILE")"
touch "$FILE"
grep -v "^${KEY}=" "$FILE" > "$FILE.tmp" 2>/dev/null && mv "$FILE.tmp" "$FILE" || true
echo "${KEY}=${VAL}" >> "$FILE"
chmod 600 "$FILE" 2>/dev/null || true
}
# Slack
save_secret "KSKILL_APT_SLACK_WEBHOOK" "https://hooks.slack.com/services/T.../B.../xxx"
# Telegram (2개 키 세트)
save_secret "KSKILL_APT_TELEGRAM_TOKEN" "123456789:ABCdef..."
save_secret "KSKILL_APT_TELEGRAM_CHAT_ID" "-1001234567890"
Windows PowerShell 등가 명령:
$FILE = "$env:USERPROFILE\.config\k-skill\secrets.env"
New-Item -ItemType Directory -Force -Path (Split-Path $FILE) | Out-Null
if (!(Test-Path $FILE)) { New-Item -ItemType File -Path $FILE | Out-Null }
(Get-Content $FILE | Where-Object { $_ -notmatch "^KSKILL_APT_SLACK_WEBHOOK=" }) + "KSKILL_APT_SLACK_WEBHOOK=https://hooks.slack.com/services/T.../B.../xxx" | Set-Content $FILE
금지 사항:
| ID | 이름 | 설명 | 데이터 소스 |
|---|---|---|---|
apt | APT 일반분양 | 아파트 일반분양 (월 25일 배치 업데이트) | 공공데이터포털 |
officetell | 오피스텔/도시형 | 오피스텔, 도시형생활주택, 민간임대 (실시간) | 공공데이터포털 |
lh | LH 공공분양 | 뉴홈, 행복주택 등 공공주택 (실시간) | 공공데이터포털 |
remndr | APT 잔여세대 | 미계약/미분양 재공급 — 청약통장 불필요 | 공공데이터포털 |
pbl_pvt_rent | 공공지원민간임대 | 시세 대비 저렴, 최대 10년 거주 | 공공데이터포털 |
opt | 임의공급 | 사업주체 자율 공급 — 선착순 계약 | 공공데이터포털 |
sh | SH 공공주택 | 서울주택도시공사 — 장기전세·청년안심·매입임대 | i-sh.co.kr HTML 크롤링 |
gh | GH 공공주택 | 경기주택도시공사 — 경기행복주택·매입임대 | gh.or.kr HTML 크롤링 |
v2.7 추가: sh·gh 카테고리는 공식 OpenAPI 부재로 각 공사 게시판 HTML 크롤링. 일정 필드(rcept_end·period)는 상세 페이지에서 별도 파싱 필요 — 현재는 schedule_source="unavailable"로 기본 표기. 사용자가 url을 클릭해 공식 사이트에서 일정 직접 확인 권장.
GitHub Actions가 12분마다 /health ping을 보내 Render 슬립을 방지하지만, GitHub Actions free cron은 부하 시 5~30분 지연되어 일부 시간대에 슬립이 발생할 수 있습니다. 일반적으로는 불필요하지만, 공고 조회가 30초 이상 지연되면 수동 웜업:
curl -s --max-time 60 "https://k-apt-alert-proxy.onrender.com/health"
그 외에는 바로 1단계로 진행한다.
1. ~/.config/k-skill/apt-alert-profile.json 파일 존재 확인
2. 있으면 → 로드 + updated_at 경과일 체크 (90일/365일 경고)
3. 없으면 → 프로필 없이 전체 조회 + "프로필을 설정하면 맞춤 추천이 가능합니다" 안내
프록시 서버에서 공고를 가져온다. 프로필이 있으면 추천 카테고리와 지역으로 필터링.
# 전체 조회 — 반드시 --max-time 180 이상, URL은 "..." 단일 스트링
curl -s --max-time 180 "https://k-apt-alert-proxy.onrender.com/v1/apt/announcements?category=all&active_only=true"
# 특정 카테고리
curl -s --max-time 180 "https://k-apt-alert-proxy.onrender.com/v1/apt/announcements?category=apt&active_only=true"
# 지역 필터 (복수 가능, 쉼표 구분)
curl -s --max-time 180 "https://k-apt-alert-proxy.onrender.com/v1/apt/announcements?region=서울,경기,인천"
# 세부 지역(구/군) 필터
curl -s --max-time 180 "https://k-apt-alert-proxy.onrender.com/v1/apt/announcements?region=서울&district=강남구,서초구"
중요: && 체이닝 금지, URL은 항상 "..."로 감싸 단일 스트링. 자세한 규칙은 상단 "빠른 응답 원칙 > 3. 프록시 호출 규칙" 참고.
응답 형식:
{
"count": 15,
"announcements": [
{
"id": "2026000123",
"name": "래미안 원펜타스",
"region": "서울",
"district": "서초구",
"address": "서울특별시 서초구 ...",
"period": "2026-04-15 ~ 2026-04-20",
"rcept_end": "20260420",
"notice_date": "2026-04-10",
"winner_date": "2026-04-27",
"contract_start": "2026-05-11",
"contract_end": "2026-05-13",
"total_units": "641",
"house_type": "민영",
"constructor": "삼성물산(주)",
"url": "https://www.applyhome.co.kr/...",
"speculative_zone": "Y",
"price_controlled": "N",
"house_category": "APT",
"size": "중형/대형",
"schedule_source": "api"
}
]
}
schedule_source 필드 (v2.5 신규):
"api" — 공공데이터포털 API 응답에서 바로 얻은 일정 (APT 일반분양 대부분)"html_scraped" — 청약홈 공고 상세 페이지 HTML 파싱으로 보강 (오피스텔·잔여세대 등 API 누락분)"unavailable" — 두 경로 모두 실패, 일정 미확인 (원문 URL 직접 확인 필요)관련 필드 (html_scraped 시 추가 제공):
notice_date — 모집공고일winner_date — 당첨자 발표일 (reminder=winners 기반)contract_start, contract_end — 계약 체결 기간 (reminder=contract 기반)조회된 공고를 프로필 기준으로 분석한다. 분류는 에이전트가 직접 수행한다.
분류 필드:
region: 지역district: 세부 지역 (구/군 — API 응답의 district 필드 또는 주소에서 추출)type: 민영 / 공공 / 재건축 / 재개발size: 소형 / 중형 / 대형priority: HIGH / MEDIUM / LOWeligibility: 자격 해당 여부 (프로필 기반)special_supply: 해당 특별공급 유형우선순위 판정 기준 (프로필 반영):
기본은 간결 모드. 상단 "빠른 응답 원칙"의 템플릿을 따른다. 상세 모드는 사용자가 명시 요청했을 때만 확장한다.
📋 프로필: 만 31세 / 서울·경기·인천 / 무주택 / 통장 5년
📢 접수 중 공고 (N건):
| 이름 | 지역 | D-day | 세대수 | 타입 | 링크 |
| ... | ... | D-5 | 350 | 민영 | [청약홈 →](url) |
⏱️ {N}분 전 갱신 · 💡 더 보려면: '내 조건에 맞는 추천' / '내 가점' / '청약 가이드'
url 필드를 [청약홈 →](url) 형식으로 출력. 터미널 마크다운 렌더러가 링크로 표시해서 원클릭 이동 가능data_age_seconds를 분 단위로 환산해 맨 아래 ⏱️ N분 전 갱신 표시. 60분 넘으면 "N시간 전"📢 접수 중 공고 (N건):로 바꾸고 맨 아래 "프로필 설정하면 맞춤 추천 가능" 추가D-5), 세대수·타입도 텍스트만. 색·판정은 상세 모드에서만사용자가 "맞춤 추천", "내 조건에 맞는", "Top 3" 등을 명시하면 아래 확장:
📋 프로필: 만 31세 / 서울·경기·인천 / 신혼부부 / 무주택 / 통장 5년
📊 추정 가점: 약 32점 / 84점
⭐ 특별공급: 신혼부부 (추정)
🎯 추천 Top 3
※ 항목 옆 이모지 = 당첨 가능성 (🟢 높음 · 🟡 보통 · 🔴 낮음 · ⚪ 판정불가)
1. 🟢 [공고명] — [지역], D-day
📅 접수 YYYY-MM-DD~YYYY-MM-DD | 발표 YYYY-MM-DD | 계약 YYYY-MM-DD
[청약홈 원문 →](url)
- 핵심 이유 1~2줄 (소득·가점·평형 적합성)
(2·3번도 동일 포맷)
📢 접수 중 공고 (N건): [테이블]
※ D-day 컬럼 색: 🔴 D-1 이하 · 🟡 D-2~3 · 🟢 D-4 이상
※ 매칭 컬럼: 🟢 강력 추천 · 🟡 조건부 · 🔴 제외(프로필 불일치)
⏱️ N분 전 갱신
Top 3 세부 정보 필수 출력:
winner_date 있으면 "발표 YYYY-MM-DD", 없으면 생략contract_start 있으면 "계약 YYYY-MM-DD", contract_end가 다르면 "~ YYYY-MM-DD" 병기url 마크다운 링크 [청약홈 원문 →](url) — 원클릭 이동 가능중복 표시 금지:
Top 3 선정 규칙: 자격 엄격한 순(APT > LH > 오피스텔), 프로필 특공 포함, 1주택자는 갈아타기 가능 유형 우선.
⚠️ {지역} 접수 중 공고 0건입니다.
💡 인접 지역({인접}) 확장하시겠어요? "{인접} 포함해서 다시"
인접 매핑: 서울↔경기↔인천 / 부산↔경남↔울산 / 광주↔전남↔전북 / 대전↔세종↔충남 / 세종↔대전↔충남↔충북 / 강원↔충북 / 대구↔경북 / 경북↔대구↔충북↔강원 / 경남↔부산↔울산↔전남 / 전북↔광주↔전남↔충남 / 충북↔세종↔대전↔충남↔강원 / 충남↔세종↔대전↔충북 / 제주↔(전국 공고만)
📌 참고 일정: 접수 → 발표(7~10일 후) → 계약(1~2주 내)
사용자가 "알림 보내줘", "Slack으로 보내줘", --notify 등을 요청한 경우에만 실행한다.
🚨 기본값 자동 선택 금지 — 주기·필터 둘 다 반드시 사용자에게 물어본다. 어떤 알림 요청이든(필터 지정 여부 무관) 아래 STEP 1·2를 순서대로 강제 진행한다. 묻지 않고 바로 발송하는 경로는 존재하지 않는다.
STEP 1. 발송 주기 선택 (필수)
알림 요청을 받자마자 다른 어떤 동작보다 먼저 아래 표를 출력하고 주기를 묻는다. 기술 용어가 아닌 결과 중심으로 설명할 것.
📢 알림 발송 — 어떻게 받으시겠어요?
| # | 선택 | 결과 | 추천 대상 |
|---|------|------|----------|
| 1 | 지금 한 번만 | 즉시 1회 발송 후 종료 | 오늘만 확인 |
| 2 | 매일 자동 (GitHub) ⭐ | 매일 오전 7시 (KST) 자동 발송, PC 꺼도 OK | 꾸준히 받기 (권장) |
| 3 | 매일 자동 (내 PC) | 매일 오전 7시 (KST) PC가 직접 발송 | 데스크톱 상시 가동 |
| 4 | 창 열린 동안 반복 | Claude 창 열어둔 동안 N시간마다 | 테스트용 |
1~4 중 선택해주세요. (2번 추천)
🕗 2·3번 기본 시간은 오전 7시(KST)입니다. 다른 시각 원하시면 말씀해주세요.
예: "저녁 7시", "오전·오후 2회", "주말만" 등
ℹ️ 내부 구현 참고
1=즉시 API · 2=GitHub Actions · 3=cron/Task Scheduler · 4=/loop
시간 커스터마이징 규칙 (Claude가 변환):
사용자가 한국어로 "저녁 7시", "오전 10시" 등 말하면 Claude가 KST → UTC 변환 후 cron 형식으로 자동 변환한다. GitHub Actions는 UTC 기준이므로 KST 시각에서 -9시간 하면 UTC.
| 사용자 입력 | KST | UTC | cron |
|---|---|---|---|
| 오전 7시 (기본) | 07:00 | 22:00 전날 | 0 22 * * * |
| 오전 8시 | 08:00 | 23:00 전날 | 0 23 * * * |
| 오전 9시 | 09:00 | 00:00 | 0 0 * * * |
| 정오 12시 | 12:00 | 03:00 | 0 3 * * * |
| 오후 6시 | 18:00 | 09:00 | 0 9 * * * |
| 오후 7시 | 19:00 | 10:00 | 0 10 * * * |
| 오후 8시 | 20:00 | 11:00 | 0 11 * * * |
| 오전·오후 7시 2회 | 07·19시 | 22·10시 | 0 22,10 * * * |
| 주말만 오전 9시 | 토·일 09시 | 00시 토·일 | 0 0 * * 0,6 |
3번(로컬)은 cron/Task Scheduler도 로컬 OS 시각 그대로 KST 사용하므로 변환 불필요. 예: crontab에 0 7 * * *로 바로 설정.
사용자가 숫자나 키워드("1번", "매일", "지금만" 등)로 명확히 답할 때까지 대기한다. 애매하거나 답이 없으면 이 표를 다시 출력한다. 절대 "기본 1회성"으로 임의 판단해서 넘어가지 않는다.
사용자가 2번(GitHub 자동) 선택 시 추가 안내:
"GitHub 계정만 있으면 5분 안에 설정 가능합니다. 다음 3가지만 진행하면 됩니다:
① 이 레포를 본인 계정으로 fork (GitHub 홈페이지 Fork 버튼)
② Settings → Secrets → New secret 으로 SLACK_WEBHOOK 등록
③ .github/workflows/apt-notify.yml 커밋
제가 ③번 파일 내용 생성해드리겠습니다."
사용자가 3번(로컬 스케줄러) 선택 시 추가 안내:
OS 확인 후 macOS/Linux는 crontab 한 줄, Windows는 PowerShell Register-ScheduledTask 명령 제공.
STEP 2. 필터 확인 (필수)
주기가 결정되면 8개 필터 표를 반드시 보여주고 사용자가 원하는 조건을 선택하게 한다:
📢 알림 조건 — 아래 필터 중 원하는 것만 조정하세요:
| # | 파라미터 | 현재값 / 기본 | 설명 |
|---|---------|------------|------|
| 1 | category | {초기값} | apt / officetell / lh / remndr / pbl_pvt_rent / opt / all |
| 2 | region | {프로필.regions or all} | 서울·경기·인천 등 17개 광역 (쉼표 복수) |
| 3 | district | (전체) | 강남구·서초구 등 세부 구/군 |
| 4 | min_units | 0 | 최소 세대수 (대단지만, 예: 500) |
| 5 | constructor_contains | (전체) | 시공사 키워드 (삼성·현대·GS 등) |
| 6 | active_only | true | 접수 중인 공고만 |
| 7 | months_back | 2 | 조회 기간 (개월, 최대 12) |
| 8 | reminder | (없음) | d3·d1·winners·contract |
| 9 | exclude_ids | (없음) | 중복 방지용 제외 공고 ID |
원하는 조건을 말씀해주세요.
• 예: "서울·경기 500세대 이상 D-3"
• 또는 "프로필대로" / "기본값" 이라고 하면 현재값 그대로 사용
사용자 메시지에 이미 필터가 포함된 경우("서울 대단지만 알림")에도 위 표는 반드시 출력하되, 해당 필터는 "현재값"에 반영해서 보여준다. 사용자가 더 조정하거나 "이대로"/"확정" 하면 STEP 3로.
STEP 3. 실행 (주기별 분기)
| STEP 1 선택 | STEP 3 실행 내용 |
|---|---|
| 1. 🔂 1회성 | POST /v1/apt/notify?<filters> 즉시 호출 → 결과 보고 |
| 2. 🔁 /loop | /loop 24h /korea-apt-alert <조건> 알림 한 줄 안내만, 사용자가 복붙 실행 |
| 3. 🗓️ GitHub Actions | .github/workflows/apt-notify.yml 예시 yaml 출력 + 필요 Secrets(SLACK_WEBHOOK, PROXY_URL) 등록 안내 |
| 4. 💻 로컬 스케줄러 | macOS/Linux crontab -e 라인 OR Windows PowerShell Task Scheduler 등록 명령 출력 |
2~4번은 Claude가 직접 발송하지 않고 스크립트/설정만 제공한다. 사용자가 등록 후 "완료" 응답하면 마무리.
Slack 발송:
curl -X POST "$KSKILL_APT_SLACK_WEBHOOK" \
-H "Content-Type: application/json" \
-d '{
"blocks": [
{"type": "header", "text": {"type": "plain_text", "text": "🏠 래미안 원펜타스 — 서울 서초구"}},
{"type": "divider"},
{"type": "section", "text": {"type": "mrkdwn", "text": "*📅 접수기간:* 20260415 ~ 20260420\n*🏢 타입:* 민영 / 중형/대형\n*🔴 우선순위:* HIGH\n*⭐ 특별공급:* 신혼부부 자격 해당 (추정)\n*📊 추정 가점:* 32점\n*💬 분석:* _1군 건설사 + 서초구 입지 + 641세대_"}},
{"type": "divider"},
{"type": "actions", "elements": [{"type": "button", "text": {"type": "plain_text", "text": "청약홈 바로가기 →"}, "url": "https://www.applyhome.co.kr", "style": "primary"}]}
]
}'
Telegram 발송:
curl -X POST "https://api.telegram.org/bot${KSKILL_APT_TELEGRAM_TOKEN}/sendMessage" \
-H "Content-Type: application/json" \
-d '{
"chat_id": "'"$KSKILL_APT_TELEGRAM_CHAT_ID"'",
"text": "🏠 <b>래미안 원펜타스</b> — 서울 서초구\n\n📅 <b>접수기간:</b> 20260415 ~ 20260420\n🏢 <b>타입:</b> 민영 / 중형/대형\n🔴 <b>우선순위:</b> HIGH\n⭐ <b>특별공급:</b> 신혼부부 자격 해당\n📊 <b>추정 가점:</b> 32점\n💬 <i>1군 건설사 + 서초구 입지</i>\n\n<a href=\"https://www.applyhome.co.kr\">청약홈 바로가기 →</a>",
"parse_mode": "HTML",
"disable_web_page_preview": true
}'
HIGH 우선순위는 알림음 ON, 나머지는 무음 발송.
| 상황 | 대응 |
|---|---|
| 프록시 응답 없음 | "프록시 서버가 응답하지 않습니다. 잠시 후 다시 시도해주세요." (Render free tier는 15분 비활성 시 슬립) |
| 공고 0건 | "현재 접수 중인 청약 공고가 없습니다." |
| 프로필 없음 | 전체 조회 후 "프로필을 설정하면 맞춤 추천이 가능합니다" 안내 |
| 프로필 매칭 0건 | "현재 조건에 맞는 공고가 없습니다. 지역이나 평형 조건을 넓혀보세요." |
| Slack/Telegram 미설정 | 해당 환경변수 설정 방법 안내 |
https://k-apt-alert-proxy.onrender.com (Render free tier — 15분 비활성 시 슬립)~/.config/k-skill/apt-alert-profile.json (로컬 저장, 서버 전송 없음)