slack-machine
slack-machine copied to clipboard
Add support for interactive buttons [block_actions]
Hey! I badly needed support for interactive buttons. So I implemented an early but working version.
What's new:
- update existing message
- delete existing message
- handle
block_actions
payloads
Example usage:
from machine.plugins.base import MachineBasePlugin
from machine.plugins.decorators import listen_to, process
from slack_sdk.models.blocks.blocks import SectionBlock, ActionsBlock
from slack_sdk.models.blocks.block_elements import ButtonElement
class PasswordReset(MachineBasePlugin):
"""Detects Password reset requests"""
@listen_to(regex=r"(Password.*reset)|(reset.*Password)")
async def question(self, msg):
fields = SectionBlock(
text=f"Hey <@{msg.sender.id}>, it looks like you might want to reset your password. Do you want me to do it?"
)
approve_button = ButtonElement(
text="Yes, please.",
action_id="password_reset_yes_for_user",
value=f"{msg.sender.id}",
style="primary",
)
deny_button = ButtonElement(
text="No, thank you.",
action_id="password_reset_no_for_user",
value=f"{msg.sender.id}",
style="danger",
)
buttons = [approve_button, deny_button]
actions = ActionsBlock(
block_id="password_reset_user_confirmation_block", elements=buttons
)
await msg.reply(
# providing text is strongly advised for i.e. mobile notifications
text=f"Hey <@{msg.sender.id}>, it looks like you might want to reset your password. Do you want me to do it?",
in_thread=True,
blocks=[fields, actions],
)
@process("block_actions")
async def update_block(self, event):
if (
event.get("actions")
and event["actions"][0]["block_id"]
== "password_reset_user_confirmation_block"
):
channel = event["channel"]
# do more validation, i.e. if the person who clicked the button is allowed to execute the action
await self.update(
blocks=[], # reset all blocks to display text
channel=channel["id"],
ts=event["message"]["ts"],
text='Got it',
)
# or delete initial message and i.e. post a new one
# await self.delete(channel=channel["id"], ts=event["message"]["ts"])
PS. I really tried to delete or update initial message according to https://api.slack.com/interactivity/handling#payloads but I did not manage to do it with socket mode. I am not sure if it is even possible, so I decided to introduce update and delete methods.
Cheers!