[FastAPI] 슬랙 슬래시커맨드(Slash Command), Block kit Builder

hukim·2022년 7월 17일
0

Open API

목록 보기
9/11
post-thumbnail

슬래시 커맨드를 실행했을 때, 여러가지 버튼 선택지를 주고
이에 따라서 메뉴를 실행할 수 있도록 만들어보려고 한다.

Block Kit Builder

Block kit Builder

빌더 사이트에서 여러가지 block들을 미리 사용해보고 ui가 어떻게 나오는지도 확인할 수 있다.
이중에서 액션 버튼을 이용해서 선택지를 여러가지 선택지를 줄 수 있게하려고 한다.

        def action_buttons(self, elements: list):
        blocks = [{
            "type": "actions",
            "elements": []
        }]

        for row in elements:
            blocks[0]["elements"].append(
                {
                    "type": "button",
                    "text": {
                        "type": "plain_text",
                        "text": row["text"],
                        "emoji": True
                    },
                    "value": row["value"],
                    # "url": row["url"]
                }
            )

        return blocks
@router.post("/")
async def select_menu():
    elements_list = [
        {
            "text": "menu1",
            "value": "menu1",
            "url": "",
        },
        {
            "text": "menu2",
            "value": "menu2",
            "url": "",
        }
    ]
    
    slack_client.post_message(
        channel_id=url.channel_id,
        text="select_menu",
        blocks=slack_client.action_buttons(
            elements=elements_list
        )
    )
    return

Text 부분에는 버튼에 들어가는 문구
url 부분에 클릭 시 이동할 주소를 적어주면 해당 주소로 이동시킬 수도 있다.

이를 활용해서 여러 개 버튼을 내려줄 수 있도록 작성한다.

단, url은 위 처럼 빈 값(빈 문자열 포함)이 들어가면 안되고 반드시 값이 있어야한다.
그렇지 않으면 key값에서 빼야 한다.

작업하면서 알게 된 점은 url을 추가할 때 앞에 http:// 부분을 적지 않으면
invalid url로 에러를 뱉어낸다는 점이다.

menu가 위처럼 버튼 형식으로 출력되고 이제 버튼 눌렀을 때
어떤 액션을 할 것인지 정해주면 된다.

interactivity

그 이전과 마찬가지로 버튼을 눌렀을 때 상호작용을 하려면 interactivity에서 정해놓은
endpoint로 api를 호출하게끔 되어있다.

여러가지 메뉴를 상호작용 하기위해서 actions의 type으로 구분하면 될거같다.
ex) plain_text_input, button

@router.post("/interactive")
async def post_message(request: Request, db: Session = Depends(get_db)):
    form_data = await request.form()
    payload = json.loads(form_data.get("payload"))
    message = "message"
    actions = payload["actions"][0]

    if payload:
        if actions["type"] == "plain_text_input":
            message = await interactive_myname(myname=payload["actions"][0]["value"], db=db)
        if actions["type"] == "button":
            if actions["value"] == "menu1":
                await input_myname()
                return

    slack_client.post_message(
        channel_id=url.channel_id,
        text=message,
    )

    return
async def interactive_myname(myname: str, db: Session) -> str:
    name_list = [myname[i:i + 1] for i in range(len(myname))]

    result = await get_china_character_name(name_list, db)

    if not result:
        message = "멋진 이름입니다. 당신의 이름에는 불용한자가 없습니다!"
    else:
        name_text = ""
        for name in result:
            name_text = f"{name_text}불용한자는 [{name.cha_name},{name.kor_name}]이며, 이 한자는 {name.description}\n"

        message = f"당신의 이름 중 불용한자는 총 {len(result)}개 입니다...\n{name_text}\n\n부모님이 주신 소중한 이름, 재미로만 봐주세요 🥹"

    return message

menu1을 눌렀을 때는 기존에 만들었던 불용한자 슬래시 커맨드를 나오게끔 하고
menu2를 눌렀을 때 새로운 액션을 하게끔 만들었다.

다음에는 menu2를 눌렀을 때 내용을 작성하도록 하려고 한다.

0개의 댓글