[Slack API] Interactivity Request URL with AWS API Gateway, Lambda - Reply in thread

이아영·2021년 3월 24일
0

Slack-API

목록 보기
2/2

이 글은 Slack API 두번째 글이다. 첫 번째 글과 이어지는 내용이니 첫 번째 글을 먼저 보고 오는 것을 추천한다.

Slack이 Request URL로 보낸 요청을 처리하기 위한 Lambda를 먼저 만들어주자.
일단 Slack에서 어떤식으로 요청을 보내는지 알아보기 위해서 다음과 같이 event를 출력해주는 코드만 작성했다. (Lambda 함수 이름은 response-from-slack으로 했다)

import json

def lambda_handler(event, context):
    print(json.dumps(event))

Slack의 요청을 Lambda에게 전해줄 API Gateway를 구축해보자.
AWS API Gateway 콘솔에 접속해서 API 생성버튼 클릭 후 API 유형에서 REST API 구축 선택


작업 버튼에서 리소스 생성을 선택하면

새로운 하위 리소스를 만들 수 있다.

우리가 만든 리소스에 POST 메소드를 만들어 준다.
작업 버튼에서 메소드 생성을 클릭. 앞에서 만든 Lambda 함수를 고르고 저장해준다.


통합 요청으로 들어가서 아래쪽을 보면 매핑 템플릿 탭이 있다. 다음과 같이 설정해준다.

#set($payload = $input.body.split("="))
$util.urlDecode($payload[1])

매핑 템플릿은 API Gateway가 Lambda에게 값을 어떻게 전해줄 것인지 형식을 정의하는 부분이다.

Handling interaction payloads(Slack API)에 있는 내용을 보면 Slack이 보내는 요청의 본문에는 payload라는 매개 변수가 포함되고 payload를 JSON으로 파싱해야 한다고 나온다. 따라서 데이터는 payload=<JSON으로 파싱해야하는 값> 이렇게 들어온다.

매핑 템플릿의 코드에서 $payload값은 ['payload', 'JSON으로 파싱해야하는 값']이 되고 $util.urlDecode()를 이용하여 $payload[1]을 디코딩한 값을 Lambda로 넘겨준다.
(API Gateway 매핑 템플릿)

매핑템플릿 설정이 완료되었으면 저장하고 API배포를 진행해준다.

배포를 누르면 다음과 같이 호출할 수 있는 URL이 나온다. 이 URL을 복사해서 다시 Slack API 사이트로 이동한다.

이전 글에서 비워두었던 Request URL에 복사한 URL + /<리소스 이름>을 다음과 같이 넣어준다. 그리고 아래에 Save Changes 버튼으로 저장

이제 이전 글에서 Slack으로 보냈던 메시지에서 버튼을 눌러보자.
이번에는 경고 표시가 나오지 않고 실행이 잘 된다.

Lambda가 실제로 잘 실행되었는지 보기 위해 AWS CloudWatch 콘솔에서 response-from-slack의 로그를 보면 Json 형태로 데이터가 잘 들어온 것을 볼 수 있다.

이제 메시지의 버튼을 클릭했을 때 어떤 버튼을 클릭했는지 reply를 달아보자.
response-from-slack 함수를 아래처럼 수정한 후 Deploy

import json
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError
import logging
import os

# logger setting
logger = logging.getLogger()
logger.setLevel(logging.INFO)

OAUTH_TOKEN = os.environ['SLACK_OAUTH_TOKEN']

def lambda_handler(event, context):
    logger.info(json.dumps(event))
    try:
        client = WebClient(token=OAUTH_TOKEN)
        client.chat_postMessage(
            channel=event['channel']['name'], 
            thread_ts=event['container']['message_ts'],
            text=event['actions'][0]['text']['text']+" button clicked"
        )
        return {
            "result": event['actions'][0]['text']['text']+" button clicked"
        }
    except Exception as e:
        logger.error(e)
        return {
            "result": "Slack reply failed"
        }

Lambda 함수 수정 배포 후 Slack 메시지의 버튼을 눌러보면 다음과 같이 reply가 달리는 것을 볼 수 있다.
참고로 reply 함수가 따로 있지는 않고 thread_ts에 Slack에서 전달한 message_ts 값을 넣어주면 새로운 message가 아니라 해당 message의 reply로 달리게 된다.

1개의 댓글

comment-user-thumbnail
2023년 7월 25일

잘봤습니다!

답글 달기