[FastAPI] 슬랙 봇이 알려주는 심심풀이 불용한자 2

hukim·2022년 6월 19일
0

Open API

목록 보기
7/11
post-thumbnail

지난 포스팅에 이어 슬랙 봇을 이용한 불용한자 알아보기를 이어서 진행한다.

Interactivity & Shortcuts

슬랙의 커스텀 슬래시 커맨드를 이용하여 유저에게 슬랙 봇이 DM을 보내는 기능까지 작성했었다.

이 후에 최초로 구상한 것은 슬래시 커맨드가 발생하였을 때
위 이미지와 같은 plain text를 보내서 메시지를 유저에게 전달하고,
유저가 답변을 작성한 것을 바탕으로 다음 로직을 실행하도록 작성하는 방향으로 생각하였다.

Block Kit Builder 슬랙에서 제공하는 킷 빌더를 통해서 여러가지 Block 메시지를 구성할 수 있다.

유저와 상호작용을 하기 위해서 plain_text_input에서 유저가 입력한 메시지를 얻어내려면
앱 페이지에서 Interactivity & Shortcuts 메뉴로 들어간 후 이미지처럼
트리거가 발생했을 때 작동하는 엔드포인트를 설정해주어야 한다.

적용화면 및 코드

@app.post("/myname")
async def input_myname():
    channel_id = "U023VKA2PUJ"
    blocks = [
        {
            "dispatch_action": True,
            "type": "input",
            "element": {
                "type": "plain_text_input",
                "action_id": "plain_text_input-action",
                "placeholder": {
                    "type": "plain_text",
                    "text": "ex) 金炯旭"
                },
            },
            "label": {
                "type": "plain_text",
                "text": "당신의 이름을 '한자'로 입력해 주세요.",
                "emoji": True
            }
        }
    ]

    slack_client = SlackAPI(config.slack_bot_token)
    result = slack_client.post_message(
        channel_id=channel_id,
        text="나의이름은",
        blocks=blocks
    )
    return

슬래시 커맨드가 발생했을 때 유저가 입력할 수 있는 텍스트 폼을 보내준다.

@app.post("/interactive")
async def post_message(request: Request):
    form_data = await request.form()
    payload = json.loads(form_data.get("payload"))
    
    print(payload.get("actions"))

    return

유저가 입력했을 때 위에서 설정한 것 처럼 이 엔드포인트로 정보가 들어오게 된다.
form_data 형식으로 받고 payload라는 키에 정보들이 들어있으며 텍스트에 입력한 값은 actionsvalue에서 찾을 수 있다.

DB

이제 유저가 입력한 값을 바탕으로 DB에서 찾아서 메시지를 다시 유저에게 알려주도록 한다.

from pydantic import BaseModel, Field


class ChinaCharacterInfo(BaseModel):
    chn_character_no: int = Field(...)
    cha_name: str = Field(...)
    kor_name: str = Field(...)
    description: str = Field(...)
    call_name: str = Field(...)

pydantic 모델을 사용하여 DB에서 얻은 값들을 담아주고,

from sqlalchemy.orm import Session

from db.models.china_character import ChinaCharacterInfo
from db.schema.china_character import ChinaCharacter


async def get_china_character_name(
    name: list[str],
    db: Session
):
    query = db.query(ChinaCharacter).filter(ChinaCharacter.CHA_NAME.in_(name)).all()

    result = [
        ChinaCharacterInfo(
            chn_character_no=row.CHN_CHARACTER_NO,
            cha_name=row.CHA_NAME,
            kor_name=row.KOR_NAME,
            description=row.DESCRIPTION,
            call_name=row.CALL_NAME,
        ) for row in query
    ]
    return result

사용자가 입력한 이름을 1글자 단위로 쪼개서 디비에서 검색한다.

@app.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"))

    myname = payload["actions"][0]["value"]
    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부모님이 주신 소중한 이름, 재미로만 봐주세요 🥹"

    channel_id = "U023VKA2PUJ"
    slack_client = SlackAPI(config.slack_bot_token)
    slack_client.post_message(
        channel_id=channel_id,
        text=message,
    )

    return

이제 슬랙에서 실제로 사용해본다.

테스트로 디비에 있는 값들 아무거나 넣어봤는데 무시무시한 뜻 풀이다.
역시, 이런 거는 재미로만 보는것이 정신건강에 이롭다.

디비에 없는 경우도 잘 나온다.

기능을 우선 만들어보고자 코드가 많이 더러워졌기 때문에 다음번엔 기능을 추가하면서 코드를 정리해보려고 한다.

0개의 댓글