agentleFS
isac7722isac7722/skills/tickets-notion/SKILL.md

tickets-notion

Skill1 starsChanged 5 months agoMITView on GitHub

사용자가 첨부한 야구 티켓 예매 이미지를 파싱하여 Notion tickets DB에 페이지를 생성합니다. Use this skill when the user says "/tickets-notion", "티켓 이미지 저장", "예매 내역 노션에 넣어줘", "야구 티켓 저장", "예매 스크린샷 정리", "예매 이미지 파싱", "tickets DB에 넣어", or attaches a ticket purchase screenshot and asks to save it to Notion. 이미지를 분석해서 홈팀/상대팀/경기일시/좌석/매입가 등 구조화 데이터로 변환하고, 사용자 확인을 거쳐 notion-update로 저장합니다.

  • Reads credentials

The file

Files
SKILL.md

Tickets-Notion Skill

야구 티켓 예매 이미지를 한 번에 Notion tickets DB에 저장하는 스킬. 이미지 파싱 → 필드 매핑 → 사용자 확인 → 저장까지를 책임집니다.

사전 조건

  • 필수 의존성:
    • notion-shared 스킬 (sibling으로 설치)
    • notion-update 스킬 (저장 실행용)
    • notion-config 스킬 (field_map 조회용)
  • ~/.notion-skills/config.yaml 에 tickets data_type이 등록되어 있어야 합니다.
  • ~/.notion-skills/.env 에 TICKETS_NOTION_TOKEN(또는 tickets가 NOTION_TOKEN을 쓰도록 등록된 경우 그쪽)이 있어야 합니다.

설치 여부와 등록 상태가 의심되면 먼저 다음으로 확인:

PYTHONDONTWRITEBYTECODE=1 uv run --with notion-client --with pyyaml --with python-dotenv \
  python ~/.claude/skills/notion-config/scripts/config.py show tickets

success: false 또는 누락이면 사용자에게 /notion-config add tickets ... 를 먼저 실행하라고 안내.

Workflow

Step 1: 이미지 확보

사용자가 직접 첨부한 이미지를 분석합니다. 첨부가 없는 상태로 이 스킬이 트리거됐다면 먼저 이미지 첨부를 요청하세요. 이미지가 야구 티켓이 아니거나 핵심 필드(경기명/일시/좌석)가 식별 불가하면 그 사실을 사용자에게 알리고 중단합니다 — 억지로 추론하지 마세요.

Step 2: 현재 field_map 조회

DB 스키마는 시간에 따라 바뀔 수 있으므로 매번 최신 field_map을 조회합니다:

PYTHONDONTWRITEBYTECODE=1 uv run --with notion-client --with pyyaml --with python-dotenv \
  python ~/.claude/skills/notion-config/scripts/config.py show tickets

응답의 field_map에서 각 필드의 type과 options(select 필드)를 파악합니다.

Step 3: 이미지 → 필드 매핑

이미지에서 다음 항목을 추출합니다 (없으면 None):

이미지 항목 (한국어)추출 예시
예매일시2026.05.22 14:23:29
취소 가능 시간2026.06.06 13:00:00
예매번호6142262144
예매자유*중
경기명롯데 VS 한화이글스
매수5매
관람장소 및 일시사직야구장 2026.06.06 17:00
권종명일반 5매
총 결제내역신용카드 67,500원
수령방법무인발권기/모바일
좌석1루 외야석 925블럭 7열 28~32번

추출 결과를 다음 규칙으로 DB 필드에 매핑:

직접 매핑 필드

  • 홈팀 (select): 경기 장소로 추론.
    • 사직야구장 → 롯데
    • 잠실 두산전 홈/원정 구분 등은 일시·관중석 정보로 판단
    • 모르면 사용자에게 질문
  • 상대팀 (select): 경기명에서 추출. "롯데 VS 한화이글스" → "한화"
  • 경기_일시 (date): "2026.06.06 17:00" → 2026-06-06T17:00:00+09:00
  • 블럭 (number): 좌석 표기에서 "925블럭" → 925
  • 열 (number): "7열" → 7
  • 구매_수량 (number): "5매" → 5
  • 매입_가격 (number): "67,500원" → 67500
  • 좌석 (select): "1루 외야석" → 옵션과 매칭("1루외야석"). 공백 제거/유사 매칭으로 비교
  • 예매_명의 (select): 예매자 이름. 옵션과 정확히 일치하지 않으면 → Step 4: 모호한 select 처리 참조

자동 계산되는 Formula 필드 (입력 금지)

다음 필드는 Notion의 formula로 자동 계산되므로 JSON 페이로드에 포함하지 마세요:

  • 수익률, 티켓_정보, 요일, 미등록, 예상_순수익, 티켓_단가, 티켓_상태

Title (title): 고정 템플릿

{예매번호} | {홈팀}vs{상대팀} {MM-DD} | {블럭}블럭 {열}열 {좌석시작}~{좌석끝}번

예: 6142262144 | 롯데vs한화 06-06 | 925블럭 7열 28~32번

좌석이 단일 번호면 ~끝번을 생략하고 단일 번호만 표기.

Step 4: 모호한 select 처리

select 필드에서 추출 값이 옵션과 일치하지 않으면, 자의적으로 결정하지 말고 AskUserQuestion으로 사용자에게 선택을 요청합니다. 자주 발생 케이스:

  • 예매_명의: 마스킹된 이름(유*중)이 옵션(김도현/한승화)과 매칭 안 됨

선택지 구성 (한 질문에 모아서):

  1. 기존 옵션 중 가장 가까운 것 선택
  2. 새 옵션으로 추가 (Notion API가 자동 생성)
  3. 비워두기

여러 필드에 동시 모호함이 생기면 한 번의 AskUserQuestion 호출에 묶어서 질문하세요. 사용자 인터럽션 횟수를 최소화하는 게 중요합니다.

Step 5: 부가 정보 body 작성

DB field_map에 없는 이미지 정보는 페이지 본문에 markdown으로 자동 기록합니다. 정보 손실을 막기 위함이며, 이게 이 스킬의 핵심 가치 중 하나입니다.

다음 템플릿을 사용하세요(존재하는 항목만 포함):

## 예매 상세
- **예매일시**: 2026.05.22 14:23:29
- **취소 가능 시간**: 2026.06.06 13:00:00
- **권종명**: 일반 5매
- **결제**: 신용카드 67,500원
- **수령방법**: 무인발권기 발권 또는 경기 당일 모바일티켓 발권

## 좌석 (5장)
- 1루 외야석 925블럭 7열 28번
- 1루 외야석 925블럭 7열 29번
- 1루 외야석 925블럭 7열 30번
- 1루 외야석 925블럭 7열 31번
- 1루 외야석 925블럭 7열 32번

좌석은 매수만큼 풀어서 나열. body 텍스트는 notion-update의 body 필드로 전달하면 markdown_parser가 Notion blocks로 변환합니다.

Step 6: 사용자 확인 (필수)

저장 전 항상 미리보기를 제시하고 사용자 승인을 받습니다. 형식:

📋 tickets DB 저장 미리보기

📌 Title
  6142262144 | 롯데vs한화 06-06 | 925블럭 7열 28~32번

🏟  경기
  - 홈팀: 롯데
  - 상대팀: 한화
  - 경기 일시: 2026-06-06 17:00 (Sat)

🎫 좌석/결제
  - 좌석: 1루외야석
  - 블럭/열: 925블럭 7열
  - 구매 수량: 5매
  - 매입 가격: 67,500원

👤 예매 명의: 유*중 (신규 옵션 추가)

📝 body에 추가 기록될 정보
  - 예매일시, 취소가능시간, 권종명, 결제수단, 수령방법, 좌석 5건

진행할까요? (yes / 수정사항)

사용자가 yes / OK / 응 / 진행 등 긍정 응답 시 Step 7. 수정 요청이 오면 해당 부분만 고쳐서 미리보기 재출력.

Step 7: notion-update 호출

stdin JSON으로 호출. formula 필드는 절대 포함하지 마세요.

echo '<JSON_PAYLOAD>' | PYTHONDONTWRITEBYTECODE=1 uv run \
  --with notion-client --with pyyaml --with python-dotenv \
  python ~/.claude/skills/notion-update/scripts/update.py --type tickets

JSON 구조 예:

{
  "title": "6142262144 | 롯데vs한화 06-06 | 925블럭 7열 28~32번",
  "홈팀": "롯데",
  "상대팀": "한화",
  "경기_일시": "2026-06-06T17:00:00+09:00",
  "블럭": 925,
  "열": 7,
  "구매_수량": 5,
  "매입_가격": 67500,
  "좌석": "1루외야석",
  "예매_명의": "유*중",
  "body": "## 예매 상세\n- ..."
}

응답이 success: true 면 page URL을 사용자에게 출력. success: false 면 에러 메시지와 함께 어떻게 복구할지 (예: select 옵션 부재, token 미설정) 안내.

팀명 정규화 사전

티켓 표기는 풀네임("한화이글스", "기아타이거즈" 등)인 경우가 많지만 DB select는 보통 축약("한화", "KIA")입니다. 다음 매핑을 사용:

풀네임 표기DB 옵션
한화이글스한화
두산베어스두산
기아타이거즈 / KIA타이거즈KIA
삼성라이온즈삼성
롯데자이언츠롯데
LG트윈스LG
키움히어로즈키움
KT위즈KT
SSG랜더스SSG
NC다이노스NC

매핑되지 않는 새 팀(예: 미국 MLB)이 등장하면 → Step 4 모호한 select 처리로 사용자에게 질문.

홈/원정 판단

경기 장소로 홈팀 결정:

경기장홈팀
사직야구장롯데
잠실야구장LG 또는 두산 (요일/일정으로 추가 판단 필요)
고척스카이돔키움
광주기아챔피언스필드KIA
대구삼성라이온즈파크삼성
인천SSG랜더스필드SSG
수원KT위즈파크KT
창원NC파크NC
대전한화생명이글스파크 / 대전한밭종합운동장한화

잠실은 두산/LG가 공용하므로 단독 결정 불가 → 사용자 질문.

자주 발생하는 함정

  • 경기 일시 vs 예매 일시 혼동: "예매일시"는 결제 시점, "관람장소 및 일시"가 경기 시작. 경기_일시 필드에는 관람 일시를 넣습니다.
  • 좌석 표기 변형: "1루 외야석", "1루외야석", "외야 1루" 등 다양함. DB 옵션과 공백/순서 차이만 있을 때는 자동 매칭하되, 의미가 다를 수 있는 경우(예: "내야지정석A" vs "B") 사용자 질문.
  • 매수와 좌석 번호 개수 불일치: 예 매수=5인데 좌석 번호가 4개만 명시 → 사용자에게 확인.
  • 취소 가능 시간 0시 케이스: "2026.06.06 0:00:00" 같이 자정 표기. ISO 변환 시 T00:00:00 처리.

출력 컨벤션

  • 미리보기와 최종 메시지는 한국어. 필드명도 가능하면 한국어.
  • 저장 성공 시 한 줄 요약 + page URL 출력. 추가 설명은 생략 (사용자가 페이지를 직접 보면 됨).
  • 저장 실패 시 에러 원문 + 가능한 복구 액션을 명확히 제시.

비범위 (현재 스킬에서 처리 안 함)

  • 콘서트/뮤지컬/영화 등 다른 종류의 티켓 이미지 → 현재는 야구 티켓 전용
  • 여러 장의 이미지 일괄 처리 → 한 번에 하나의 이미지
  • 기존 티켓 페이지 업데이트 → 현재는 생성만. 업데이트는 별도 요청 시 notion-update --page-id를 직접 사용

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.