본문 바로가기
프로젝트/GCP+Python | 성결대학교 공지사항 알리미 앱

[성결대학교 공지사항 알리미 디스코드 채널 만들기] #3. 디스코드 크롤링 봇 제작하기 (학교 공지 크롤링)

by 카랑현석 2024. 3. 29.

혹시 성결대학교 공지사항 알림을 받고 싶다면 https://discord.gg/CgRbux9V 에 들어오면 된다.

 

왜 디스코드로 하게 되었는가?

새롭게 학교 공지 게시글이 올라오면 그 공지사항을 알려주는 매체로는 카카오톡, Discord, Telegram, 자신이 만든 앱 등이 있는데 먼저 대형 플랫폼이 제공하는 서비스에서 간단하게 서비스를 만들어 학생(사용자)의 반응을 보는 것이 우선이라고 생각했다.

 

그래서 카카오톡, Discord, Telegram 중에 하나를 골라 진행하기로 했다.

- 먼저, Telegram은 당시 마약, 성착취 등 인식이 좋지 않아 가장 후순위로 두었다.

- 카카오톡의 경우 플러스 친구를 통해 다른 사용자에게 서비스를 제공하기 위해서 문자 한 건당 15~30원의 비용이 든다고 한다. 사용자가 새롭게 올라온 공지가 10개이고 사용자가 50명이라면 10*50*30 = 150000원의 비용이 든다.

사용자의 반응을 보기 위해서 사용하는 것이고 대학생은 지갑 사정이 궁핍하기 때문에 이 방법을 사용하기에는 어려웠다.

- Discord는 무료였다. 그리고 카카오톡보다 접근성은 떨어지지만 인식은 나쁘지 않았기 때문에 Discord로 학교 공지사항 알리미 봇을 만들기로 결심했다.

Discord 봇 개발

1. 디스코드 Application 생성

1. 구글에 '디스코드 개발자 포털'을 검색해서 들어갑니다.

https://discord.com/developers/applications

 

2. 왼쪽 바의 'Applications' 을 클릭합니다.

3. 오른쪽 상단에서 'New Application' 버튼을 클릭합니다.

4. 원하는 application의 이름을 적어줍니다.

 

2. 봇(Bot) 만들기

1. 왼쪽 바에서 'Bot' 창을 클릭합니다.

2. 'Add Bot' 버튼을 클릭 > 'Yes, do it!' 버튼 클릭 (이미 만들어진 경우 Add Bot 버튼이 없고 아래 이미지와 같음)

 

3. 'Reset Token' 버튼을 눌러 토큰을 발급해줍니다. (반드시 기억해야 합니다.)

 

3. 봇(Bot)을 자신의 서버로 초대하기

1. 왼쪽 창에서 'OAuth2' 을 선택합니다.

2. SCOPES 에서 'bot'을 선택합니다.

 

3. 스크롤을 내리면 GENERATED URL에 자신의 bot URL이 나온다. 이를 Copy 버튼을 눌러 복사하고 새로운 인터넷 주소창에 붙여넣기 한다.

4. 위와 같은 화면에서 봇을 추가할 서버를 선택하고 '승인' 버튼을 클릭한다.

 

정상적으로 잘 만들어졌다면 discord 채널에 봇이 하나 추가되어 있을 것이다.

4. python을 이용해서 discord 봇 활성화하기

이제 본격적으로 잠자고 있는 discord 봇을 활성화하는 작업을 진행합니다.

잠자고 있는 discord 봇

 

1. 개발 환경에서 터미널(콘솔창)을 키고 discord.py 라이브러리를 설치합니다.

pip install discord.py

 

2. 아래 코드를 작성해봅니다.

- 참고 : bot.run('your_token_number') 에는 '2. 봇(Bot) 만들기 단계'의 3번째에서 발급 받았던 token을 복사해서 넣어줍니다.

import discord
from discord.ext import commands
 
bot = commands.Bot(command_prefix='!') # 명령을 할 때 '#'을 넣어서 명령어를 실행
 
@bot.event # 봇이 실행되는 동안 발생하는 이벤트
async def on_ready(): # 봇이 시작될 때 실행되는 이벤트 함수
    print(f'Login bot: {bot.user}')
 
@bot.command()
async def hello(message): # "!hello"를 대화창에 입력한 경우 실행되는 함수
    await message.channel.send('Hi!') # 봇이 메세지가 온 채널에 "Hi!" 라는 메시지를 보내준다.
 
bot.run('your_token_number')

 

 

해당 코드를 실행했을 때 발생할 수 있는 오류

        1) TypeError: BotBase.__init__() missing 1 required keyword-only argument: 'intents' 오류

더보기

4번째줄 코드를 아래와 같이 수정

import discord # 추가
 
bot = commands.Bot(command_prefix='!',intents=discord.Intents.all())

         2) discord.errors.PrivilegedIntentsRequired: Shard ID None is requesting privileged intents that have not been explicitly enabled in the developer portal. It is recommended to go to https://discord.com/developers/applications/ and explicitly enable the privileged intents within your application's page. If this is not possible, then consider disabling the privileged intents instead. 오류

더보기

디스코드 개발자 포털에서 Privileged Gateway Intents 에 관한 권한을 모두 허용해준다.

3. 파이썬 파일을 실행하고, 봇이 정상적으로 켜졌는지 확인 및 !hello 채팅을 쳐봅니다.

봇 활성화
봇 응답

 

5. python을 이용해서 discord 봇 활성화하기

이제 해당 코드를 적절히 조합해서 기존에 만들었던 크롤링 코드에 끼워넣으면 된다.

await message.channel.send('보낼 메시지') 구문이 디스코드 채널에 메시지를 출력하는 것이므로 이를 적절히 코드에 넣어 활용하면 된다.

 

필자의 경우 @bot.command()의 async 함수에다가 크롤링하는 기능부터 디스코드 출력하는 부분까지 while True을 통해 무한루프를 돌려 한 번 명령어를 내리면 계속 공지사항을 모니터링 하도록 구현했다.

 

그리고 나서 실행을 했는데, WARNING discord.gateway Shard ID None heartbeat blocked for more than 20 seconds. 오류 문구가 뜨면서 디스코드 봇이 꺼졌었다.

알고보니 디스코드 봇 기반 코드 자체가 비동기 처리(async) 방식이라 time.sleep() 을 사용하는 것보다 await asyncio.sleep() 구문을 사용하는 것이 더 안정적이라고 한다. 이렇게 바꾸니 해결되었다.

 

이와 관련해서 도움이 되었던 문서이다.

https://discordpy.readthedocs.io/en/stable/faq.html?highlight=heartbeat#what-does-blocking-mean

 

결과물 

새로 올라온 공지사항을 제대로 감지하는지 확인을 하기 위해 비교과 선생님께 부탁을 드렸다.

어떻게 이게 가능했냐면.. 평소 비교과를 열심히 참여해서 비교과 선생님들이 나를 알고 있었고 연락도 계속 하고 있었기 때문에 공지를 올려주시면 잘 작동 되는지 테스트도 원활하게 할 수 있었다.

 

비교과 선생님들.. 감사합니다.. :)

 

잘 작동한다 :)


혹시 성결대학교 공지사항 알림을 받고 싶다면 https://discord.gg/CgRbux9V 에 들어오면 된다.

 

향후 계획

지금은 내 컴퓨터에서 실행을 계속 24시간 돌려야한다. 

하지만 컴퓨터를 24시간 켜 놓을 수는 없는 노릇이므로 이제 이를 서버에 올려야겠다.