Slack Message에 button 추가하기 (Legacy)
Slack은 bot을 이용하여 workspace에 메시지를 보내고, 버튼 등을 통해 interaction을 할 수 있도록 지원한다. 이러한 기능은 매우 많이 쓰이고, ChatOps라고 부르는 방법도 이러한 기능을 이용하여 구현할 수 있다. 협업, 소통, CI/CD 등 편의성을 높이기 위해 많이 쓰인다.
이 문서에서는 아래 2가지를 다룰 것이다.
- bot에서 보내는 메시지에 button을 붙이는 방법
- button에서 발생한 message action에 API 서버가 응답하는 방법 (API spec, 3초 타임아웃 등)
Slack app을 준비하는 방법
- refer: https://api.slack.com/legacy/interactive-messages
- 적절한 OAuth scope 등을 설정해야 함
Attaching interactive message buttons
refer: https://api.slack.com/legacy/message-buttons
메시지에 상호작용 버튼을 붙이는 방법을 설명한다.
위와 같은 슬랙 메시지를 JSON으로 표현하면 아래와 같다
{
"text": "Would you like to play a game?",
"attachments": [
{
"text": "Choose a game to play",
"fallback": "You are unable to choose a game",
"callback_id": "wopr_game",
"color": "#3AA3E3",
"attachment_type": "default",
"actions": [
{
"name": "game",
"text": "Chess",
"type": "button",
"value": "chess"
},
{
"name": "game",
"text": "Falken's Maze",
"type": "button",
"value": "maze"
},
{
"name": "game",
"text": "Thermonuclear War",
"style": "danger",
"type": "button",
"value": "war",
"confirm": {
"title": "Are you sure?",
"text": "Wouldn't you prefer a good game of chess?",
"ok_text": "Yes",
"dismiss_text": "No"
}
}
]
}
]
}
- attachment.callback_id: 필수값. 이름 그대로 식별 용도.
- refer: https://api.slack.com/legacy/interactive-message-field-guide#field-guide__top-level-message-fields__attachment-fields
- action.name: action의 이름. 여러 action이 같은 name을 가지면 오직 하나만 trigger 상태가 될 수 있음.
- refer: https://api.slack.com/legacy/interactive-message-field-guide#field-guide__top-level-message-fields__message-action-fields
- action의 이름은 다를 수 있음. 또다른 예제는 위 링크 참고.
- action.value: 이름이 같은 action들 사이에서 의도를 구별하기 위한 용도
Responding to message actions
메시지의 버튼을 누르면 POST
요청을 받게 됨. 요청은 slack app의 action URL로 보내짐.
Slack app(bot)은 하나의 action URL을 가짐
refer: https://api.slack.com/legacy/interactive-messages#making-messages-interactive__readying-your-application-for-interactive-messages__preparing-your-request-url
request body에 JSON string의 payload가 온다.
Content type: application/x-www-form-urlencoded
API 요청을 받으면 원하는대로 요청을 핸들링하면 된다.
slack 메시지를 업데이트하기 위해 응답하는 방법은 여러 가지가 있는데, 다음 내용에서 다룬다.
Responding to message actions
보안을 위해, Slack 요청을 받으면 X-Slack-Signature 헤더를 validate해야한다
refer: https://api.slack.com/legacy/interactive-messages#making-messages-interactive__building-workflows__receiving-action-invocations__validating-slack-requests
refer: https://api.slack.com/legacy/interactive-messages#responding
응답 방법에는 여러 가지가 있으며, 함께 사용할 수도 있다.
즉시 응답
- API에 JSON message body로 즉시 응답할 수 있음
- 3초 내에 응답해야 함. 3초 이상 걸릴 경우 200 OK로 즉시 응답하고
response_url
을 대신 사용해야 함.
response_url로 응답 (incrementally)
이 방법의 용도는:
- 현재 메시지를 대체하거나
- public message로 응답하거나
- action을 누른 유저만 볼 수 있는 ephemeral message로 응답하거나
단, 30분 내에 5번만 사용할 수 있음
chat.update로 응답
기존 메시지가 chat.postMessage
로 생성된 것이라면 message_ts
와 함께 chat.update
를 사용해 수정할 수 있음
에러 응답
에러가 발생하면 ephemeral
응답을 보내자. 요청에 즉시 응답하거나 response_url
을 사용할 수 있다.
예시 응답은 아래와 같다.
{
"response_type": "ephemeral",
"replace_original": false,
"text": "Sorry, that didn't work. Please try again."
}
슬랙에서 “이 메시지는 오직 당신에게만 보입니다”와 같은 문구와 함께 메시지를 본 적이 있을 것이다.
그러한 메시지가 바로 ephemeral message이다.