변명은 만개 결과는 한개

[Discord bot] 메세지에 이모지 받아 처리하기 본문

공부/Discord

[Discord bot] 메세지에 이모지 받아 처리하기

노마십가 2021. 1. 10. 06:08
728x90
반응형

메시지에 이모지 받아 처리하기

디스코드 봇 (discord.py) 을 통해 특정 메시지에 부여되는 이모지에 따라 원하는 동작을 실행하는 메시지 이모지 처리방법 두 가지에 대해 예제와 함께 다룹니다

  1. wait_for 를 이용하여 특정 이모지 부여 1회 대기 및 액션 취하기

  2. bot event on_raw_reaction_add 를 이용하여 이모지 부여에 따른 액션 취하기


1️⃣ wait_for 를 이용하여 특정 이모지(🙌) 부여 1회 대기 및 액션 취하기

1. 메시지 생성 및 가이드 이모지 부여

msg = await.channel.send("Sample message")
await msg.add_reaction('🙌')

메시지를 생성하는 동시에 msg.add_reaction() 으로 유저가 손쉽게 이모지를 부여할 수 있도록 메시지에 가이드 이모지(🙌) 를 줍니다

2. 이모지를 체크하는 (predicate)함수 정의

def check_emoji(reaction, user):
    return reaction.emoji == '🙌' and reaction.message.id == msg.id and user.bot == False

3번에서 사용 할, 특정 이벤트를 받아들인 뒤 expect event 인지 확인 후 '모두' 맞는 경우 wait_for 을 탈출하도록 하는 함수를 정의해놓습니다. 이때 확인하는 항목은 세 가지입니다

  1. 기대한 이모지가 맞는지 확인
    방금 해당 이벤트에서 받은 이모지가 우리가 찾는 '🙌' 이모지가 맞는지 확인
  2. 부여된 메시지 아이디가 맞는지 확인
    모든 메시지에 대한 특정 이벤트를 받아들이기에, 우리가 원하는 그 메시지(msg)에 이모지가 부여되어있는지
    리액션된 메시지의 아이디와 msg 메세지의 id 확인
  3. 리액션을 부여한 유저가 bot 이 아닌 것을 확인

3. wait_for 사용하여 특정 이벤트를 구독하며 대기

try:
    reaction, user = await bot.wait_for(event='reaction_add', timeout=60.0, check=check_emoji)
    # some action code when get emoji successfully
    pass
except asyncio.TimeoutError:
    # some action code when get emoji timeout
    return

wait_for() 함수를 사용하여 제한시간인 timeout 초만큼 특정 이벤트 reaction_add 를 받아 확인 함수 check_emoji 에 넣어 True 값이 반환될 때까지 대기합니다.
제한시간 이내에 predicate 함수가 True가 반환하면 대기 상태를 해제하고 다음 코드를 실행합니다.
제한시간을 넘겼을 경우 대기 상태를 해제하고 asyncio.TimeoutError 에러가 발생됩니다

  1. wait_for() 참고 링크

  2. event
     기다릴 특정 이벤트 명을 기입하면 됩니다. 단, on_ 접두사(prefix)는 제외하셔야 합니다
    코드에 사용된 on_reaction_add 이벤트모든 Event reference

  3. timeout
     asyncio.TimeoutError 를 발생시키는 제한시간(초)을 설정합니다. None 으로 입력 시 무한정 기다립니다

  4. check
     무엇을 기다릴지 확인하여 True 혹은 False 를 반환하는 predicate 함수입니다.

* 실제 구현 케이스 : 익명 의뢰 기능

커맨드로 의뢰를 신청하면 특정 채널로 안내 메시지가 가며,

해당 안내 메시지의 이모지를 눌러 의뢰를 수락하도록 구현

 


2️⃣ bot event on_raw_reaction_add 를 이용하여 이모지 부여에 따른 액션 취하기

대부분이 wait_for 을 이용한 이모지 처리와 비슷합니다

1. 메시지 생성 및 가이드 이모지 부여

conference_msg = await.channel.send("Sample message")
await conference_msg.add_reaction("⭕")
await conference_msg.add_reaction("❌")

메시지를 생성하는 동시에 msg.add_reaction() 으로 유저가 손쉽게 이모지를 부여할 수 있도록 메시지에 가이드 이모지를 줍니다

2. on_raw_reaction_add(payload) 이벤트 처리 함수 작성

@bot.event
async def on_raw_reaction_add(payload):
    global conference_msg

    if payload.message_id != conference_msg.id and user.bot == True:
        return

    if str(payload.emoji) == '⭕':
        # some action code when get ⭕ emoji
    elif str(payload.emoji) == '❌':
        # some action code when get ❌ emoji

on_raw_reaction_add event를 이모지가 추가된 메시지 아이디가 conference_msg 의 메세지 아이디와 동일한지, 그리고 부여한 주체가 봇이 아님을 확인한 뒤
이모지를 체크하여 해당하는 액션을 취하도록 합니다

 

* 실제 구현 케이스 : 회의 개설 알림 및 취합 봇

커맨드로 회의를 생성하며 유저 혹은 Role을 태그 하면

해당 인원들 대상으로 이모지를 통해 회의 참석 여부를 취합할 수 있습니다


참고

 on_reaction_addon_raw_reaction_add

on_reaction_add 의 경우 internal messager cache 에 메시지가 존재하지 않을 경우 호출되지 않을 수 있습니다.
그에 반하여 on_raw_reaction_addinternal message cache 의 상태와 상관없이 불리기에 충분히 고려하여 사용해야 합니다

728x90
반응형