Skip to content

DaleStudy/coffee

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Coffee Chat ☕

디스코드 서버에서 커피챗 참여자를 자동으로 매칭해주는 봇입니다.

기능

  • Discord Role 기반 참여자 자동 조회
  • 중복 방지 알고리즘으로 매칭 생성 (최근 4회 이력 확인)
  • Discord Webhook으로 매칭 결과 발표
  • GitHub Actions를 통한 격주 자동 실행
  • 매칭 이력 자동 PR 생성

설치 방법

1. Bun 설치

curl -fsSL https://bun.sh/install | bash

2. 의존성 설치

bun install

환경변수 설정

환경변수 설명 타입
DISCORD_BOT_TOKEN Discord Bot 토큰 Secret
DISCORD_WEBHOOK_URL Discord Webhook URL Secret
DISCORD_SERVER_ID Discord 서버(Guild) ID Variable
DISCORD_ROLE_ID 커피챗 참여자 Role ID Variable

GitHub Actions 설정

  1. Repository Settings > Secrets and variables > Actions
  2. Secrets 탭에서 추가:
    • DISCORD_BOT_TOKEN
    • DISCORD_WEBHOOK_URL
  3. Variables 탭에서 추가:
    • DISCORD_SERVER_ID
    • DISCORD_ROLE_ID

Discord 봇 & Webhook 설정

Bot 생성

  1. Discord Developer Portal 접속
  2. "New Application" 클릭하여 앱 생성
  3. Bot 메뉴에서 "Add Bot" 클릭
  4. "Reset Token"으로 토큰 발급 → DISCORD_BOT_TOKEN으로 사용

Bot 권한 설정

  1. Bot 메뉴 > Privileged Gateway Intents
  2. SERVER MEMBERS INTENT 활성화 (필수)
  3. OAuth2 > URL Generator에서 권한 설정:
    • Scopes: bot
    • Bot Permissions: Read Messages/View Channels
  4. 생성된 URL로 서버에 봇 초대

Webhook 생성

  1. Discord 서버 > 채널 설정 > 연동
  2. "웹후크 만들기" 클릭
  3. Webhook URL 복사 → DISCORD_WEBHOOK_URL로 사용

ID 확인 방법

  1. Discord 설정 > 고급 > 개발자 모드 활성화
  2. 서버 이름 우클릭 > "서버 ID 복사" → DISCORD_SERVER_ID
  3. 서버 설정 > 역할 > 역할 우클릭 > "역할 ID 복사" → DISCORD_ROLE_ID

사용 방법

로컬 실행

# 환경변수 설정 후
export DISCORD_BOT_TOKEN="your-token"
export DISCORD_WEBHOOK_URL="your-webhook-url"
export DISCORD_SERVER_ID="your-server-id"
export DISCORD_ROLE_ID="your-role-id"

# 매칭 실행
bun run match

GitHub Actions 자동 실행

  • 스케줄: 매주 월요일 UTC 00:00 (KST 09:00)
  • 격주 실행: 짝수 주차에만 실행
  • 수동 실행 시에는 주차 상관없이 실행

수동 실행

# GitHub CLI 사용
gh workflow run match.yml

# 또는 GitHub 웹에서
# Actions > Coffee Chat Matching > Run workflow

실행 흐름

  1. Discord API로 Role 기반 참여자 조회
  2. 매칭 이력 로드 (data/history.json)
  3. 중복 방지 알고리즘으로 매칭 생성
  4. history.json에 새 매칭 저장
  5. Discord Webhook으로 결과 발표
  6. 자동 PR 생성 (chore/update-match-history-YYYY-MM-DD)

매칭 알고리즘

핵심 원칙

원칙 설명
2인 1조 기본적으로 2명씩 매칭
중복 방지 최근 4회 이력 내 같은 조합 불가
적게 만난 사람 우선 과거에 적게 만난 사람일수록 매칭 확률 증가
경험 믹싱 신규 멤버와 경험 많은 멤버가 섞이도록 유도

점수 기반 매칭

모든 가능한 페어에 대해 점수를 계산하고, 점수가 높을수록 매칭 확률이 높아집니다.

종합 점수 = 만남 횟수 점수 (60%) + 경험 믹싱 점수 (40%)

만남 횟수 점수

점수 = 1 / (1 + 만남 횟수)
만남 횟수 점수
0회 1.0
1회 0.5
2회 0.33
3회 0.25

경험 믹싱 점수

참여자의 경험 수준을 3단계로 분류합니다:

  • Newcomer: 하위 25% (참여 횟수 적음)
  • Regular: 중간 50%
  • Veteran: 상위 25% (참여 횟수 많음)
A \ B Newcomer Regular Veteran
Newcomer 0.3 0.8 1.0
Regular 0.8 0.6 0.8
Veteran 1.0 0.8 0.5

→ 신규+신규 = 낮은 점수 (0.3), 신규+베테랑 = 높은 점수 (1.0)

매칭 과정

flowchart TD
    A[참여자 목록] --> B[경험 통계 계산]
    B --> C{홀수 인원?}
    C -->|Yes| D[1명 랜덤 선택 후 별도 보관]
    C -->|No| E[점수 매트릭스 생성]
    D --> E

    E --> F[최근 4회 중복 조합 필터링]
    F --> G[소프트맥스 확률 변환]
    G --> H[가중 무작위 선택]
    H --> I[선택된 페어 확정]
    I --> J{남은 인원 있음?}
    J -->|Yes| E
    J -->|No| K{홀수였음?}

    K -->|Yes| L[보관된 1명을<br/>최적 점수 조에 추가]
    K -->|No| M[매칭 완료]
    L --> M
Loading

예시

점수 계산 예시

참여자: A(베테랑), B(신규), C(레귤러), D(신규)

A-B 점수: 만남0회(1.0×0.6) + 베테랑-신규(1.0×0.4) = 1.0
A-C 점수: 만남1회(0.5×0.6) + 베테랑-레귤러(0.8×0.4) = 0.62
B-D 점수: 만남0회(1.0×0.6) + 신규-신규(0.3×0.4) = 0.72

→ A-B 매칭 확률이 가장 높음

홀수 인원 (5명)

참여자: A, B, C, D, E
         ↓ E를 랜덤 선택 후 보관
         ↓ 나머지 4명 점수 기반 매칭
  중간: [A-B] [C-D]
         ↓ E를 점수가 가장 높은 조에 추가
결과: [A-B-E] [C-D]
      (3인조 × 1, 2인조 × 1)

중복 방지

최근 4회 매칭 이력을 확인하여 같은 조합이 반복되지 않도록 합니다.

// history.json 예시
{
  "matches": [
    { "date": "2024-01-01", "pairs": [["A","B"], ["C","D"]] },
    { "date": "2024-01-15", "pairs": [["A","C"], ["B","D"]] },
    { "date": "2024-01-29", "pairs": [["A","D"], ["B","C"]] },
    { "date": "2024-02-12", "pairs": [["A","B"], ["C","D"]] }
  ]
}

위 이력 기준:

  • 불가능한 조합: A-B, C-D, A-C, B-D, A-D, B-C
  • 4회 이전 이력은 다시 매칭 가능
  • 불가능한 조합이 모두 최근 4회에 포함된 경우, fallback으로 가능한 조합 선택

제약사항 및 향후 계획

현재 제약사항 개선 방향
JSON 파일 기반 저장 (동시성 제어 없음, 스케일링 한계) PostgreSQL/MongoDB로 마이그레이션
GitHub Actions 실행 (실시간 명령어 처리 불가, 주기 변경 시 코드 수정 필요) 상시 실행 봇 + 설정 관리 시스템
Role 수동 관리 (사용자가 직접 참여/탈퇴 불가) 슬래시 명령어로 자동화

개발

# 테스트 실행
bun test

# 린트 검사
bun run lint

# 포맷팅
bun run format

# 타입 체크
bun run typecheck

라이선스

MIT

About

☕ 커피챗

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •