IaC/CI CD Tool

Jenkins CI/CD와 Slack을 연동한 APK QR 코드 자동 생성 봇 구축기

Somaz 2026. 6. 25. 00:01
728x90
반응형

Overview

모바일 앱 개발 환경에서 APK 빌드 후 테스터들에게 다운로드 링크를 전달하는 과정은 생각보다 번거롭다.

링크를 복사해서 Slack에 붙여넣고, 테스터들은 모바일에서 해당 링크를 직접 입력하거나 복사해야 하죠. 특히 긴 URL의 경우 실수로 잘못 입력할 가능성도 있다.

 

이러한 불편함을 해결하기 위해 APK 다운로드 링크를 QR 코드로 자동 변환하여 Slack 채널에 전송하는 봇을 개발했다. Jenkins 빌드가 완료되면 자동으로 QR 코드가 생성되어 Slack에 전송되고, 테스터들은 모바일로 QR 코드를 스캔하기만 하면 바로 APK를 다운로드할 수 있다.

 

 

이번 글에서는 Python Flask 기반의 Slack Bot을 구축하고 Kubernetes에 배포하는 전 과정을 공유하겠다.

 

 

 

 

slack 화면 예시

 

 

 

 

 

 


 

 

 

주요 기능

이 봇은 단순히 QR 코드를 생성하는 것을 넘어 실무에서 필요한 여러 기능을 포함하고 있다.

 

 

핵심 기능

  • APK 링크 → QR 코드 자동 변환: URL을 QR 코드 이미지로 변환
  • 다중 채널 동시 전송: 여러 Slack 채널에 동시에 QR 코드 전송
  • QR 코드 커스터마이징: 색상, 크기 조절 가능
  • 빌드 정보 표시: 빌드 번호, 다운로드 URL 포함

 

 

보안 및 안정성

  • API 키 인증: CI/CD 파이프라인만 호출 가능하도록 인증 제공
  • Rate Limiting: DoS 공격 방어 (분당 요청 제한)
  • 자동 재시도: Slack API 일시적 장애 시 최대 3회 자동 재시도
  • 구조화된 JSON 로깅: ELK Stack, Loki 연동 용이

 

 

개발자 친화적

  • Swagger UI: 인터랙티브 API 문서 제공
  • 상세한 Health Check: Slack 연결 상태 실시간 확인
  • 다양한 엔드포인트: 단일/다중/전체 채널 전송 지원

 

 

 

시스템 아키텍처

Jenkins/GitLab CI/GitHub Actions
    ↓ (HTTP POST with X-API-Key)
Ingress (slack-qr-bot.concrit.us)
    ↓
Kubernetes Service
    ↓
Flask Application Pod
    ├─ API Key Authentication
    ├─ Rate Limiter
    ├─ JSON Logger
    └─ Retry Logic (Tenacity)
        ↓
Slack API (files.upload_v2)

 

 

 

기술 스택

  • 언어: Python 3.14
  • 프레임워크: Flask 3.0 + Gunicorn
  • 주요 라이브러리:
    • slack-sdk - Slack API 통신
    • qrcode[pil] - QR 코드 생성
    • flasgger - Swagger API 문서
    • flask-limiter - Rate Limiting
    • tenacity - 재시도 로직
    • python-json-logger - JSON 로깅
  • 인프라: Docker, Kubernetes, GitLab CI, Harbor Registry

 

 

 

 


 

 

 

구현 과정

 

1. Slack App 설정

먼저 Slack API에서 새로운 앱을 생성하고 필요한 권한을 설정해야 한다.

 

 

필요한 Bot Token Scopes

  • `chat:write` - 메시지 전송
  • `files:write` - 파일 업로드
  • `channels:read` - Public 채널 정보 조회
  • `groups:read` - Private 채널 정보 조회
  • `groups:write` - Private 채널 접근

 

앱을 워크스페이스에 설치한 후 Bot User OAuth Token을 복사해둔다. 형식은 `xoxb-` 로 시작한다.

 

 

 

만약 앱 추가 에러 가 발생 시 채널에 가서 아래의 명령어를 수행한다.

/invite @your-bot-name
  • Scopes를 수정하게 되면 App을 Reinstall 해줘야 한다.

 

 

 

 

2. 프로젝트 구조

slack-qr-bot
├── Dockerfile
├── README.md
├── backup
│   └── app.py.bak
├── img
│   └── slack-qr-bot-example.png
├── k8s
│   ├── api-key-secret.yaml
│   ├── deployment.yaml
│   ├── harbor-robot-secret.yaml
│   └── slack-token-secret.yaml
├── requirements.txt
└── src
    ├── __init__.py
    ├── __pycache__
    │   ├── __init__.cpython-313.pyc
    │   ├── app.cpython-313.pyc
    │   ├── config.cpython-313.pyc
    │   ├── decorators.cpython-313.pyc
    │   ├── services.cpython-313.pyc
    │   └── utils.cpython-313.pyc
    ├── app.py
    ├── config.py
    ├── decorators.py
    ├── routes
    │   ├── __init__.py
    │   ├── __pycache__
    │   │   ├── __init__.cpython-313.pyc
    │   │   ├── channels.cpython-313.pyc
    │   │   ├── health.cpython-313.pyc
    │   │   ├── qr.cpython-313.pyc
    │   │   └── slack_events.cpython-313.pyc
    │   ├── channels.py
    │   ├── health.py
    │   ├── qr.py
    │   └── slack_events.py
    ├── services.py
    └── utils.py

 

 

 

 

3. Python 코드 구현

 

 

4. Kubernetes 배포

 

 

5. GitLab CI/CD 파이프라인

 

자동화된 빌드 및 배포

  • `src/` 폴더 내 파일 변경 시 자동 빌드
  • Harbor Registry에 이미지 푸시
  • 수동 또는 자동 배포 트리거

 

 

 

 

 


 

 

 

 

 

사용 방법

 

 

1. Jenkins에서 호출

Jenkins 파이프라인에서 APK 빌드 후 QR 코드를 자동으로 전송할 수 있다.

// Jenkinsfile
stage('Send QR to Slack') {
    steps {
        script {
            sh '''
            curl -X POST http://slack-qr-bot.somaz.link/generate-qr \
              -H "Content-Type: application/json" \
              -H "X-API-Key: ${SLACK_QR_BOT_API_KEY}" \
              -d '{
                "channel": "apk-qr-generator",
                "apk_url": "https://example.com/app.apk",
                "build_number": "1.0.0"
              }'
            '''
        }
    }
}
  • apk_url은 apk 파일을 올릴 경로로 변경해주면 된다.
  • 나머지 channel, build_number, post 주소 등은 전부 예시이다.

 

 

 

2. curl로 호출

curl -X POST http://slack-qr-bot.somaz.link/generate-qr \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-api-key-here" \
  -d '{
    "channel": "apk-qr-generator",
    "apk_url": "https://example.com/app.apk",
    "build_number": "1.0.0"
  }'
  • channel name과 channel id 둘다 가능하다.

 

 

 

3. Swagger UI로 테스트

브라우저에서 `http://<slack bot url>/api-docs` 에 접속하면 모든 API를 인터랙티브하게 테스트할 수 있습니다.

  1. 우측 상단 "Authorize" 버튼 클릭
  2. API Key 입력
  3. 원하는 API 선택 후 "Try it out"
  4. 파라미터 입력 후 "Execute"

 

 

 

 

 

실행 결과

QR 코드가 Slack 채널에 다음과 같이 전송된다.

 

 

 

 

 

 


 

 

로컬 테스트 방법

 

 

Docker Build

docker build -f Dockerfile -t slack-bot:test .

 

 

 

Docker Run

# Slack Bot Token을 환경 변수로 설정하고 실행
docker run -d \
  --name slack-qr-bot \
  -p 8080:8080 \
  -e API_KEY="api-key" \
  -e SLACK_BOT_TOKEN="xoxb-your-token-here" \
  slack-bot:test

# 로그 확인
docker logs -f slack-qr-bot

 

 

 

 

 

로컬 기능 테스트

 

 

헬스체크

curl http://localhost:8080/health | jq

 

 

채널 목록 조회

curl http://localhost:8080/channels | jq

 

 

채널 이름으로 조회

curl -X POST http://localhost:8080/generate-qr \
  -H 'Content-Type: application/json' \
  -H 'X-API-Key: api-key' \
  -d '{
    "apk_url": "https://example.com/test-app.apk",
    "channel": "#apk-qr-generator",
    "build_number": "1"
  }'

 

 

채널 ID로 조회

# 채널 ID 사용 (C로 시작)
curl -X POST http://localhost:8080/generate-qr \
  -H 'Content-Type: application/json' \
  -H 'X-API-Key: api-key' \
  -d '{
    "apk_url": "https://example.com/test-app.apk",
    "channel": "Cxxxxxxxxxx",
    "build_number": "1"
  }'

 

 

 

 

커스텀 qr 코드 생성

curl -X POST http://localhost:8080/generate-qr/custom \
  -H 'Content-Type: application/json' \
  -H 'X-API-Key: api-key' \
  -d '{
    "apk_url": "https://example.com/test-app.apk",
    "channel": "#apk-qr-generator",
    "build_number": "124",
    "qr_options": {
      "box_size": 15,
      "border": 4,
      "fill_color": "#FF0000",
      "back_color": "#FFFFFF"
    }
  }' | jq

 

 

 

 

 

 

다중 채널 전송

curl -X POST http://localhost:8080/generate-qr/broadcast \
  -H 'Content-Type: application/json' \
  -H 'X-API-Key: api-key' \
  -d '{
    "apk_url": "https://example.com/test-app.apk",
    "channels": ["#apk-qr-generator", "#test-channel"],
    "build_number": "125"
  }' | jq

 

 

 

 

모든 채널 전송

curl -X POST http://localhost:8080/generate-qr/broadcast-all \
  -H 'Content-Type: application/json' \
  -H 'X-API-Key: api-key' \
  -d '{
    "apk_url": "https://example.com/test-app.apk",
    "build_number": "126"
  }'

 

 

 

 

 

 


 

 

 

 

 

 

트러블슈팅

 

1. `channel_not_found` 에러

 

원인: Bot이 채널에 추가되지 않음

 

 

해결:

# Slack 채널에서 실행
/invite @APK QR Generator
  • Private 채널의 경우 `groups:read`, `groups:write` 권한이 필요

 

 

 

2. 429 Too Many Requests 에러

 

원인: Rate Limit 초과

 

 

해결:

  • 1분 대기 후 재시도
  • 개발 환경: RATE_LIMIT_ENABLED=false로 비활성화

 

 

 

3. Slack API 일시적 장애

자동 재시도 로직이 최대 3회까지 시도한다 (2초 → 4초 → 8초 대기).

 

재시도 후에도 실패하면 로그를 확인하면 된다.

kubectl logs -f -n slack-bots deployment/slack-qr-bot

 

 

 

 

 

 

성능 및 모니터링

 

Rate Limiting 정책

엔드포인트 제한 용도
전역 기본값 10 req/min 일반 호출
`/generate-qr` 20 req/min 단일 채널 QR 생성
`/generate-qr/broadcast` 10 req/min 다중 채널 전송
`/generate-qr/broadcast-all` 5 req/min 전체 채널 전송
`/health` 제한 없음 Health check

 

 

 

 

구조화된 로깅

JSON 포맷으로 로그가 기록되어 ELK Stack이나 Loki에서 쉽게 분석할 수 있다.

{
  "asctime": "2025-12-23 10:30:45",
  "name": "src.app",
  "levelname": "INFO",
  "message": "QR code sent successfully",
  "channel": "apk-qr-generator",
  "file_id": "F07KP4R8E9S"
}

 

 

 

 

 


 

 

 

 

마무리

이번 프로젝트를 통해 모바일 앱 배포 과정을 크게 개선할 수 있었다.

 

Jenkins에서 APK를 빌드하면 자동으로 QR 코드가 Slack 채널에 전송되고, 테스터들은 모바일로 QR 코드만 스캔하면 바로 앱을 다운로드할 수 있게 되었다.

 

 

특히 다음과 같은 장점이 있었다.

  1. 편의성 향상: URL 복사/붙여넣기 없이 QR 스캔만으로 다운로드
  2. 실수 방지: 긴 URL 입력 시 발생할 수 있는 오타 제거
  3. 자동화: CI/CD 파이프라인에 완전히 통합
  4. 확장성: 다중 채널, 커스텀 QR 코드 등 다양한 기능 지원
  5. 안정성: API 인증, Rate Limiting, 자동 재시도 등 운영 환경 고려

 

 

앞으로는 다음과 같은 기능을 추가할 계획이다.

  • APK 메타데이터 자동 추출 (버전, 빌드 날짜 등)
  • QR 코드에 로고 삽입
  • 다운로드 통계 추적
  • 여러 플랫폼 지원 (iOS IPA, Web 배포 등)

 

 

이 봇이 비슷한 환경에서 작업하시는 분들에게 도움이 되었으면 좋겠다.

 

 

 

 

 

 

 

 

 

 

 

 

 


Reference

 

 

 

Somaz | DevOps Engineer | Kubernetes & Cloud Infrastructure Specialist

728x90
반응형