들어가며
슬랙에서 GitHub봇을 구독했더니 위와 같이 알림이 온다. 하지만 UI가 상당히 좋지 않고, 내가 확인해야할 PR이 아니라 백엔드 등 다른 파트의 PR도 함께 올라온다는 단점이 있다. GitHub봇을 사용하기에는 너무 불편해서 직접 만들어보기로 결심했다.
본격적으로 시작하기
1) 슬랙 봇 만들기
- 슬랙 홈페이지에서 내 앱에 들어간다.
- From scratch로 앱을 만든다.
- 앱 이름과 슬랙 봇을 설치할 워크스페이스를 선택한다.

- OAuth & Permissions 탭으로 이동해서 OAuth Tokens를 발급받는다.
이 토큰은 추후 GitHub의 Secret key에 설정해두어야하니 안전한 곳에 복사해두자. 토큰이 노출되면 누구나 내 슬랙 봇을 사용할 수 있게 되니 절대 커밋에 포함시키거나 공개적인 곳에 올리면 안 된다.
- 같은 탭에서 조금 아래로 내려가면 Scopes 섹션이 있다. 여기서 봇이 슬랙에서 어떤 작업을 할 수 있는지 권한을 설정해야 한다.
chat:write권한은 필수로 추가해야 하는데, 이게 있어야 봇이 메시지를 보낼 수 있다. 만약 특정 채널에만 메시지를 보내고 싶다면chat:write.public도 추가하면 좋다.
2) 사전 세팅
본격적으로 코드를 작성하기 전에 몇 가지 정보들을 수집해야 한다.
- 먼저 슬랙 채널 ID를 추출해보자.
메시지를 보낼 채널에서 우클릭한 다음, 복사 > 링크 복사를 선택한다.
복사한 링크를 보면 https://thebombom.slack.com/archives/C097LA5K6CA 이런 형식인데, 가장 뒤에 있는 C097LA5K6CA가 바로 채널 ID다. 이 ID를 어딘가에 메모해두자.
- 다음으로 팀원들의 슬랙 ID도 필요하다.
리뷰어로 할당될 팀원의 프로필을 클릭하고, … 메뉴에서 멤버 ID 복사를 선택하면 된다.
- 이 정보들을 GitHub에 등록할 차례다. GitHub 레포지토리의 Settings > Secrets and variables > Actions로 들어가서 다음 두 가지를 등록한다.
SLACK_BOT_TOKEN: 아까 복사해둔 OAuth TokenSLACK_CHANNEL_ID: 슬랙 채널 ID
Secret을 등록할 때 이름을 정확하게 입력해야 한다. 나중에 워크플로우 파일에서 이 이름 그대로 사용하기 때문이다.
- 마지막으로 프로젝트 루트에
.github폴더를 만들고, 그 안에reviewers.json파일을 생성한다.
// .github/reviewers.json
{
"guesung": "U097FK06C3U",
"jinwoo": "U098GH07D4V",
"soyeon": "U099IJ08E5W"
}
여기서 key는 GitHub 닉네임, value는 슬랙 내 팀원 ID로 등록하면 된다. 이렇게 매핑 파일을 만들어두면 나중에 PR 리뷰어로 할당된 GitHub 유저를 슬랙에서 멘션할 수 있다.
3) GitHub Actions 워크플로우 작성
이제 본격적으로 자동화 스크립트를 작성해보자. .github/workflows 폴더를 만들고 그 안에 pr-notification.yml 파일을 생성한다.
name: Pull Request
on:
pull_request:
types: [review_requested]
send_slack_message:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Get Reviewers List
id: reviewers
uses: actions/github-script@v6
with:
script: |
const fs = require('fs');
const workers = JSON.parse(fs.readFileSync('.github/reviewers.json'));
const mention = context.payload.pull_request.requested_reviewers.map((user) => {
const login = user.login;
const mappedValue = workers[login];
return mappedValue ? `<@${mappedValue}>` : `No mapping found for ${login}`;
})
return mention.join(', ');
result-encoding: string
- name: pr reviewer 되면 slack 알림 보냄
uses: slackapi/slack-github-action@v1.24.0
with:
channel-id: ${{ secrets.SLACK_CHANNEL_ID }}
payload: |
{
"text": "pr review request",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "리뷰어로 할당되었습니다.\n • 제목: ${{ github.event.pull_request.title }}\n • 리뷰어: ${{ steps.reviewers.outputs.result }}\n • 링크: <${{ github.event.pull_request.html_url }}|리뷰하러 가기>\n💪 코드 리뷰는 코드 품질을 향상시키고, 버그를 줄이며, 팀원 간의 지식 공유와 협업을 촉진하는 핵심 프로세스입니다.\n🙏 적극적인 참여와 의견을 부탁드립니다."
}
}
]
}
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
코드를 하나씩 뜯어보면서 어떻게 동작하는지 살펴보자.
on: pull_request: types: [review_requested]는 누군가를 PR 리뷰어로 할당했을 때만 이 워크플로우가 실행되도록 트리거를 설정한 것이다. PR이 열리거나 머지될 때는 실행되지 않는다.
uses: actions/github-script@v6는 워크플로우 안에서 JavaScript로 GitHub API를 사용할 수 있게 해주는 액션이다. 덕분에 복잡한 API 호출 없이도 간단하게 PR 정보를 가져올 수 있다.
script 부분을 보면 먼저 reviewers.json 파일을 읽어온다. 그리고 PR에 할당된 리뷰어 목록(context.payload.pull_request.requested_reviewers)을 순회하면서 각 리뷰어의 GitHub 닉네임을 슬랙 ID로 매핑한다. 만약 reviewers.json에 등록되지 않은 사람이라면 GitHub 닉네임 그대로 보여준다. 최종적으로는 <@슬랙ID1>, <@슬랙ID2> 형식의 문자열을 반환하는데, 슬랙에서는 이 형식을 멘션으로 인식한다.
여기서 주의할 점이 하나 있다. fs.readFileSync의 두 번째 인자로 'utf8'을 명시적으로 넣어주는 게 좋다. 그렇지 않으면 가끔 인코딩 문제가 발생할 수 있다.
uses: slackapi/slack-github-action@v1.24.0는 슬랙으로 메시지를 전송하는 공식 액션이다. channel-id에 아까 설정한 시크릿을 넣고, payload에 보낼 메시지의 내용을 정의한다.
슬랙 메시지는 Block Kit이라는 형식을 사용하는데, 단순 텍스트보다 훨씬 보기 좋고 구조화된 메시지를 만들 수 있다. 여기서는 mrkdwn 타입을 사용해서 마크다운처럼 텍스트를 꾸몄다. PR 제목, 리뷰어, 링크 같은 정보를 ${{ }} 문법으로 동적으로 넣을 수 있다.
결과
워크플로우를 푸시하고 실제로 PR을 만들어서 리뷰어를 할당해보니, 위처럼 깔끔한 알림이 슬랙으로 날아왔다. 기본 GitHub 봇보다 훨씬 보기 좋고, 무엇보다 내가 리뷰어로 할당된 PR만 알림이 오니까 정말 편하다.
메시지 내용도 얼마든지 커스터마이징할 수 있다. 예를 들어 좀 더 재밌는 문구로 바꿔보면 어떨까?
text만 고치면 되니 분위기 맞춰 자유롭게 바꾸면 된다.
팁
혹시 메시지가 안 날아온다면 다음 사항들을 체크해보자.
- 먼저 슬랙 봇이 해당 채널에 초대되어 있는지 확인한다. 채널에 들어가서
/초대 @봇이름을 입력하면 봇을 초대할 수 있다. 봇이 채널에 없으면 당연히 메시지를 보낼 수 없다. - 그리고 GitHub Actions 탭에서 워크플로우 실행 로그를 확인해보자. 에러가 발생했다면 어느 단계에서 실패했는지 자세히 나온다. 보통은 권한 문제거나 시크릿 값이 잘못 입력된 경우가 많다.
reviewers.json파일 경로도 다시 한 번 확인해보자. 반드시.github/reviewers.json에 위치해야 한다. 그리고 JSON 형식이 올바른지도 체크해보자. 쉼표나 중괄호가 빠지면 파싱 에러가 발생한다.
맺으며
처음엔 단순히 불편한 GitHub 봇을 대체하려는 마음으로 시작했는데, 겁먹었던 것보다 연동은 간단했다..
무엇보다 팀원들이 "훨씬 깔끔하고 보기 좋다", "필요한 알림만 와서 편하다"는 피드백을 해줄 때가 가장 뿌듯했다. 사소한 불편도 직접 고쳐보니 결국 팀 전체가 편해졌다.
더 나아가서 생각해보면, 슬랙봇은 팀 프로젝트일 때 효과를 누리는 사람들이 많으니 더 큰 시너지를 발휘하지만, 연습용으로 개인 프로젝트에서도 혼자서 만들어볼 수 있을 거라 생각한다. 다양한 실험들을 해볼 수 있을 것이다. 예를들어 예전에 배포가 되었는지 안되었는지 GitHub Actions에 들어가 일일이 확인해야했다면, 이를 슬랙을 통해 알림을 주도로 자동화할 수 있지 않을까?
앞으로도 이런 작은 자동화들을 더 만들어보고 싶다는 생각이 든다. 이번에 재미를 붙였으니 다음엔 또 뭘 만들지 생각 중이다.