# 🎯 G2B Bid Scout

**나라장터 입찰공고를 자동 수집·큐레이션해 매주 메일로 받아보는 봇**

기업교육 강사를 위해 만들었습니다. 매주 월요일 오후 5시, 본인 전문 분야에 맞는 입찰공고만 골라서 적합도 + 한 줄 이유와 함께 Gmail로 받아볼 수 있습니다.

---

## 누가 쓰면 좋은가

- 매주 나라장터에서 본인 분야 공고를 수동으로 검색하는 게 번거로운 강사
- 마감일 임박 공고를 놓쳐서 제안 기회를 놓친 적이 있는 강사
- 특정 키워드(예: 디자인씽킹, AI교육, 리빙랩) 중심으로 입찰을 살피는 강사
- 무료 + 자동화 + 본인 메일로 받는 솔루션을 원하는 강사

---

## 한눈에 보는 구조

```
매주 월요일 17시 (KST)
   ↓
GitHub Actions 자동 실행
   ↓
조달청 API → 키워드별 용역 공고 검색 (PPSSrch, 병렬)
   ↓
코드 필터 (마감 D-14 → 예산·대상 태깅)
   ↓
Claude AI 적합도 평가 (1회 호출)
   ↓
HTML 메일 빌드 → Gmail SMTP 발송
   ↓
📬 본인 메일함에 도착
```

---

## 시작하기 (30분 가이드)

### 사전 준비물

다음 4가지가 필요합니다. 각각 발급/생성에 5~10분 정도 걸립니다.

1. **공공데이터포털 API 키** ([data.go.kr](https://www.data.go.kr/data/15129394/openapi.do))
2. **Claude API 키** ([console.anthropic.com](https://console.anthropic.com))
3. **Gmail 계정 + 앱 비밀번호** ([myaccount.google.com](https://myaccount.google.com/apppasswords))
4. **GitHub 계정**

---

### Step 1. 이 저장소 Fork

1. 이 페이지 우측 상단 **Fork** 클릭
2. 본인 계정으로 복사 완료

---

### Step 2. GitHub Secrets 등록

Fork한 저장소에서 **Settings → Secrets and variables → Actions → New repository secret** 클릭. 아래 항목을 하나씩 등록합니다.

| Secret 이름 | 값 | 설명 |
|-------------|-----|------|
| `G2B_API_KEY` | 공공데이터 디코딩 키 | 인코딩 키 아닌 **디코딩 키** 사용 |
| `ANTHROPIC_API_KEY` | sk-ant-... | Claude API 키 |
| `GMAIL_USER` | your@gmail.com | 발신용 Gmail 주소 |
| `GMAIL_APP_PASSWORD` | xxxx xxxx xxxx xxxx | Gmail 앱 비밀번호 (공백 제거) |
| `MAIL_TO` | your@gmail.com | 받을 메일 주소 (보통 본인) |

> ⚠️ Gmail 일반 비밀번호 아닌 **앱 비밀번호** 필요. 2단계 인증 켜야 발급 가능.

---

### Step 3. 키워드 / 프로필 수정 (본인에게 맞게)

GitHub Secrets에 아래 값들을 환경변수로 추가합니다. (로컬 실행 시에는 `.env.example`을 복사해 `.env`를 만들고 값을 채움)

**필수 환경변수**:

| 이름 | 기본값 | 설명 |
|------|--------|------|
| `KEYWORDS` | `디자인씽킹,AI교육,리빙랩` | 공고명에 매칭할 키워드 (쉼표 구분) |
| `TARGET_SCOPE` | `기업,공공,대학` | 교육 대상 범위 키워드 (쉼표 구분) |
| `MIN_BUDGET` | `20000000` | 메인 후보 진입 예산 (원, 미만은 참고용으로) |
| `DEADLINE_WINDOW_DAYS` | `14` | 마감 D-N 이내만 수집 |
| `INSTRUCTOR_PROFILE` | (예시 문장) | AI가 적합도 평가에 쓸 강사 프로필 |
| `CLAUDE_MODEL` | `claude-haiku-4-5` | 사용할 Claude 모델 |

**예시 — 강사별 커스터마이징**:

| 강사 유형 | KEYWORDS | INSTRUCTOR_PROFILE |
|-----------|----------|---------------------|
| 디자인씽킹 | `디자인씽킹,AI교육,리빙랩` | "17년 이상 디자인씽킹 교육·퍼실리테이션 전문가" |
| 리더십 | `리더십,코칭,조직개발` | "대기업 임원 코칭 12년, MBTI·DISC 자격 보유" |
| 마케팅 | `디지털마케팅,콘텐츠마케팅,퍼포먼스` | "B2B 마케팅 강사, 데이터 분석 기반 캠페인 설계 전문" |

위 값들을 GitHub Secrets에 추가합니다. (또는 `.env` 파일에 직접 입력)

---

### Step 4. 발송 주기 변경 (선택)

기본 설정은 **매주 월요일 KST 17시** 입니다. 다른 주기를 원하면 `.github/workflows/weekly.yml` 파일의 cron 표현식을 수정합니다.

| 발송 주기 | cron 표현식 (UTC) |
|-----------|------------------|
| 매주 월요일 17시 KST (기본) | `'0 8 * * 1'` |
| 매일 17시 KST | `'0 8 * * *'` |
| 월/수/금 17시 KST | `'0 8 * * 1,3,5'` |
| 화/목 17시 KST | `'0 8 * * 2,4'` |
| 매주 금요일 09시 KST | `'0 0 * * 5'` |

> KST = UTC + 9시간. 17시 KST = 08시 UTC.

---

### Step 5. 첫 실행 (수동)

자동 실행을 기다리지 않고 바로 테스트해볼 수 있습니다.

1. 저장소 → **Actions** 탭
2. 좌측 워크플로 목록에서 **Weekly Bid Scout** 클릭
3. 우측 상단 **Run workflow** → **Run workflow** 버튼 클릭
4. 1~3분 후 메일함 확인

---

## 받게 되는 메일 예시

### 적합 공고가 있을 때

- 상단에 **요약 바** — 총 건수, A적합/B검토/C참고/긴급 뱃지
- 각 공고마다 **카드** — 적합도·긴급도 컬러 뱃지, 기관/예산/마감, AI 한 줄 평
- 예산 미달·대상 범위 밖 공고는 탈락이 아닌 `⚠️ 태그`로 표시
- 하단에 CTA 버튼 → 나라장터 원문 바로가기

### 적합 공고가 없을 때

- **필터링 퍼널** — 전체 수집 → 마감 D-14 → 키워드 매칭 단계별 시각화
- **키워드별 히트 바 차트** — 어떤 키워드가 몇 건 걸렸는지
- **아까운 공고 미리보기** — 키워드는 매칭됐지만 기준 미달인 공고 최대 3건

---

## 자주 묻는 질문

### Q. 비용이 얼마나 드나요?
A. 주 1회 발송 기준:
- 공공데이터 API: **무료**
- Claude API (Haiku 4.5): **주당 약 50원 이하** (보통 10건 미만 평가)
- Gmail SMTP: **무료** (일 500통 한도 내)
- GitHub Actions: **무료** (월 2,000분 한도 내, 이 봇은 월 5분 미만 사용)

→ 사실상 **월 200원 이하**.

### Q. 키워드는 몇 개까지 넣을 수 있나요?
A. 키워드 1개당 API 1회 호출이므로 10개 이내 권장. 너무 많으면 호출 횟수가 늘어납니다.

### Q. 키워드 매칭이 누락되는 경우가 있나요?
A. API가 **부분 매칭**을 지원하므로 "디자인씽킹" 키워드로 "2026년 디자인씽킹 기반 혁신교육"이 매칭됩니다. 단, "디자인 씽킹"(띄어쓰기)이나 "Design Thinking"(영문)은 별도 키워드로 추가해야 합니다. v1.1에서 유사어 사전 도입 예정.

### Q. 메일이 안 와요.
A. 순서대로 확인:
1. GitHub Actions 탭에서 실행 성공 여부 확인
2. 실패했다면 로그에서 에러 메시지 확인
3. 성공인데 메일이 없으면 스팸함 확인
4. Gmail 앱 비밀번호 공백이 들어갔는지 확인 (공백 제거 필요)

### Q. AI가 잘못 평가하는 것 같아요.
A. `INSTRUCTOR_PROFILE`을 더 구체적으로 작성해보세요. 경력, 강의 형태, 특화 분야를 한두 문장 더 추가하면 정확도가 올라갑니다.

### Q. 다른 강사와 메일을 공유하고 싶어요.
A. `MAIL_TO`에 여러 주소를 쉼표로 구분해 넣으면 됩니다. 예: `me@a.com,colleague@b.com`

### Q. 정정공고가 별도 메일로 안 오나요?
A. v0.3은 `ntceKindNm`(공고종류: 등록공고/재공고/변경공고)만 표시합니다. 정정공고 자동 매칭은 v1.1에서 검토 예정.

---

## 문제 해결

### "G2B_API_KEY가 설정되지 않았습니다" 에러
→ GitHub Secrets에 `G2B_API_KEY`가 등록됐는지 확인. 이름 오타 주의.

### "Anthropic API authentication failed" 에러
→ Claude API 키가 만료/잘못됨. console.anthropic.com에서 재발급.

### "Invalid login: 535-5.7.8 Username and Password not accepted"
→ Gmail 일반 비밀번호 대신 **앱 비밀번호** 사용. 2단계 인증 활성화 필요.

### 메일은 오는데 적합도 평가가 비어있어요
→ Claude API 응답 파싱 실패. GitHub Actions 로그 확인 후 이슈 등록.

---

## 기여하기

이 프로젝트는 오픈소스입니다. PR / Issue 환영합니다.

특히 다음 기능에 관심 있다면 함께 만들고 싶습니다:
- 키워드 유사어 사전
- 정정공고 자동 매칭
- 강사 피드백 루프 (메일에서 "이 공고 적합했다/아니었다" 클릭 → 학습)
- 영문 공고명 대응

---

## 만든 사람

**Teddy (최송일)** — [WOWD.LAB](https://wowdlab.com) 대표
디자인씽킹 × AI로 일하는 방식을 변화시키는 교육 훈련 전문 기업

> "AI를 제대로 쓰려면 디자인씽킹부터"

문의: support@wowdlab.com

---

## 라이선스

MIT License. 자유롭게 Fork·수정·재배포 가능. 단, 본인 책임 하에 사용.
