【Python3+Lambda】Slack에서 2020년 인사말

이번 배경



업무나 커뮤니티 등에서 slack을 사용하고 있어, 일상적인 교환을 포함해 slack상에서 행해지는 경우가 많습니다. 그런 가운데, 2019년 새해 전날 slack에서 새해 인사를 하자! 라고 생각한 것이 본 기사의 시작입니다.

슬랙에서 새해 인사를 하기 위해



개요



slack의 Incoming Webhook에 메시지를 POST하는 Lambda Function을 작성해, 일본 ​​시간의 2020/1/1 00:00:00에 기동시킵니다.

처리 흐름



꽤 간단한 흐름이지만 아래 그림과 같습니다.

1.2020/1/1 0:00에 CloudWatch Event에서 Lambda를 킥.
2.1에서 킥된 람다가 인코밍 웹훅에게 메시지를 POST한다.

그럼 구현에 들어갑니다!

Incoming Webhook 준비



slack의 App 추가 페이지에서 Incoming Webhook을 검색하고 메시지를 보낼 채널을 선택하고 "Slack에 추가"를 누릅니다. 버튼을 누르면 Webhook 엔드포인트가 생성됩니다. ※이 URL은 누구나 메시지를 POST 할 수 버리므로 제 3 자에게 누설하지 않도록주의하시기 바랍니다. 이 기사에서도 URL은 마스크 위에 게시합니다.
상기의 자세한 것은 이쪽의 기사( Slack의 Incoming Webhooks를 쓰러뜨리다 )가 참고가 되었으므로, 기재하겠습니다.

Incoming Webhook에 POST하는 메시지와 그 설명도 함께 기재합니다.
우선, 메시지의 전용은 아래와 같다.
    message = "<!channel> *Happy new year 2020!*"

    send_data = {
        "username": "〇〇_BOT",
        "icon_emoji": ":laughing:",
        "text": message
    }

개별 설명을 하면
  • 메시지에 "@channel"을 추가합니다.
  • *XXX* *로 둘러싼 문자를 slack상에서 굵게 표시합니다.
  • username slack로 표시할 이름.
  • icon_emoji icon로 표시하는 이모티콘.
  • text 메시지 메시지 본문.

  • 이모티콘의 종류는 이쪽의 기사( Qiita/Github/Slack/Discord 이모티콘 목록 )를 참고로 했습니다.

    Lambda 구현



    이번에는 Python3.8에서 구현했습니다. 구현 코드는 다음과 같다.
    import json
    import urllib.request
    import os
    
    def lambda_handler(event, context):
        result = post_slack()
        #determine the existence of OK
        if 'ok' in json.dumps(result):
            body = json.dumps(result)
        else:
            body = 'NG!Watch logs of execution!'
    
        return {
            'statusCode': 200,
            'body': "slack result is " + body
        }
    
    #method posting messages to slack    
    def post_slack():
        message = "<!channel> *Happy new year 2020!*"
    
        send_data = {
            "username": "〇〇_BOT",
            "icon_emoji": ":laughing:",
            "text": message
        }
    
        send_text = "payload=" + json.dumps(send_data) #make a request data
        headers = {"Content-Type" : "application/json"}
        request = urllib.request.Request(
            os.environ["slack_url"], #url is configured as an OS environmental variable 
            data=send_text.encode('utf-8'),
            method="POST"
        )
        try:
            with urllib.request.urlopen(request) as response:
                response_body = response.read().decode('utf-8')
        except urllib.error.HTTPError as error:
            print(str(error.code) + error.reason)
        else:
            return response_body
    

    대체로 포인트로서,
  • payload 매개 변수로 JSON 문자열을 생성하고 POST합니다
  • lambda의 환경 변수에 slack endpoint를 설정하고 처리가 실행될 때 가져옵니다.
  • slack response에 「OK」가 포함되어 있는지를 판정해, 메세지 송신의 성공을 판정한다
    ※에러 핸들링의 제작은 본 실장에서는 생략하고 있습니다.

  • 2020년을 맞이한 순간 처리를 실행



    CloudWatch 이벤트를 Lambda 시작 트리거로 설정합니다. CloudWatch측에서는 cron식으로 일시 지정을 실시해, 2020/1/1 00:00에 Lambda를 킥하도록(듯이) 합니다. 이때 CloudWatch는 UTC에서 작동하므로 JST → UTC 변환을 위해 9시간 거슬러 올라갑니다.
    따라서 cron 식은 다음과 같습니다.
    cron(0 15 31 12 ? 2019)
    

    cron은 (min hour day month sun-sat※ year)로 지정합니다.
    ※요일은 이번 불필요하므로, 와일드 카드를 넣습니다.
    Lambda의 시작 트리거로 설정하면 아래 그림과 같습니다.

    이것으로 나머지는 연월을 맞이할 뿐입니다! !

    새해를 맞이했습니다!




    무사히 만든 BOT에서 새해 인사가 왔습니다! 새해에 딱 맞는 기사를 썼습니다.
    서버리스 아키텍처와 SaaS 통합의 편의성을 다시 한 번 느낀 것입니다. 새해 전날 밤에 새해 인사 BOT을 만들 수 있으니까.

    좋은 웹페이지 즐겨찾기