지난 포스트에서 Slack bot을 classic 앱설정하는 방법과 post 하는 방법에 대해서 알아 보았습니다.
아래 예제가 동작이 안되면 bot 설정을 꼭 확인하시기 바랍니다.
이전 예제는 특정 채널에 메세지를 보내는 동작이었습니다. 이번에는 내용을 모니터링 하고 있다가 들어오는 내용에 답변을 하는 동작입니다. 이것을 구현하기 위해서는 모니터링을 계속 해야만 합니다. 이때 사용하는 기능이 RTM(Real time messaging)기능 입니다.
이전 예제에서는 봇이 어떤방에 속해있지 않더라도 채널명만 알면 보낼 수 있었습니다. 그러나 내용을 읽는것은 workspace내에 bot을 add 해주어야 합니다.
봇 만들기
첫번째로 봇 부터 만들어 보겠습니다.
아래 예제를 따라하면 되는데 주의할점 있습니다.
https://www.fullstackpython.com/blog/build-first-slack-bot-python.html
Slack client 버전이 변경되어서 꼭 해당 버전을 설치해야 합니다.
pip install slackclient==1.3.2
전체 소스
import os import time import re from slackclient import SlackClient # instantiate Slack client slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN')) # starterbot's user ID in Slack: value is assigned after the bot starts up starterbot_id = None # constants RTM_READ_DELAY = 1 # 1 second delay between reading from RTM EXAMPLE_COMMAND = "do" MENTION_REGEX = "^<@(|[WU].+?)>(.*)" def parse_bot_commands(slack_events): """ Parses a list of events coming from the Slack RTM API to find bot commands. If a bot command is found, this function returns a tuple of command and channel. If its not found, then this function returns None, None. """ for event in slack_events: print("event['type'],event['text']:",event.get("type"),event.get("text")) if event["type"] == "message" and not "subtype" in event: user_id, message = parse_direct_mention(event["text"]) if user_id == starterbot_id: return message, event["channel"] return None, None def parse_direct_mention(message_text): """ Finds a direct mention (a mention that is at the beginning) in message text and returns the user ID which was mentioned. If there is no direct mention, returns None """ matches = re.search(MENTION_REGEX, message_text) # the first group contains the username, the second group contains the remaining message return (matches.group(1), matches.group(2).strip()) if matches else (None, None) def handle_command(command, channel): """ Executes bot command if the command is known """ # Default response is help text for the user default_response = "Not sure what you mean. Try *{}*.".format(EXAMPLE_COMMAND) # Finds and executes the given command, filling in response response = None # This is where you start to implement more commands! if command.startswith(EXAMPLE_COMMAND): response = "Sure...write some more code then I can do that!" # Sends the response back to the channel slack_client.api_call( "chat.postMessage", channel=channel, text=response or default_response ) if __name__ == "__main__": if slack_client.rtm_connect(with_team_state=False): print("Starter Bot connected and running!") # Read bot's user ID by calling Web API method `auth.test` starterbot_id = slack_client.api_call("auth.test")["user_id"] print("starterbot_id:",starterbot_id) while True: command, channel = parse_bot_commands(slack_client.rtm_read()) if command: handle_command(command, channel) time.sleep(RTM_READ_DELAY) else: print("Connection failed. Exception traceback printed above.")
공유 소스 대비 로그를 추가하였습니다.
자세히 보시면 속해있는 방의 모든 내용을 받을 수 있습니다.
실행시 token을 아래와 같이 bat 파일에 설정합니다.
run.bat 파일 내용
set SLACK_BOT_TOKEN=xoxb-xxxxx python slack_client.py
동작 화면
C:\Users\USER\Documents\slack>python slack_client.py Starter Bot connected and running! starterbot_id: U013R483Q1F event['type'],event['text']: hello None event['type'],event['text']: user_typing None event['type'],event['text']: message do event['type'],event['text']: desktop_notification None event['type'],event['text']: user_typing None event['type'],event['text']: message do try event['type'],event['text']: desktop_notification None event['type'],event['text']: user_typing None event['type'],event['text']: message ddd event['type'],event['text']: user_typing None event['type'],event['text']: message d event['type'],event['text']: desktop_notification None event['type'],event['text']: user_typing None event['type'],event['text']: message a event['type'],event['text']: desktop_notification None event['type'],event['text']: desktop_notification None event['type'],event['text']: user_typing None event['type'],event['text']: user_typing None event['type'],event['text']: message <@U013R483Q1F> do it event['type'],event['text']: message Sure...write some more code then I can do that! event['type'],event['text']: desktop_notification None event['type'],event['text']: user_typing None event['type'],event['text']: message <@U013R483Q1F> hello event['type'],event['text']: desktop_notification None event['type'],event['text']: message Not sure what you mean. Try *do*
사용하기전에 채널에 bot을 Add해줍니다.
테스트 하기 위해서는 @봇이름 do 내용 이렇게 보내야 봇이 동작합니다.