def test_json(self): self.assertDictEqual( ButtonElement( text="button text", action_id="some_button", value="button_123" ).to_dict(), { "text": {"emoji": True, "text": "button text", "type": "plain_text"}, "action_id": "some_button", "value": "button_123", "type": "button", }, ) confirm = ConfirmObject(title="really?", text="are you sure?") self.assertDictEqual( ButtonElement( text="button text", action_id="some_button", value="button_123", style="primary", confirm=confirm, ).to_dict(), { "text": {"emoji": True, "text": "button text", "type": "plain_text"}, "action_id": "some_button", "value": "button_123", "type": "button", "style": "primary", "confirm": confirm.to_dict(), }, )
def main(rqst: Union[InteractiveMessageRequest, CommandRequest]) -> None: block_id = cmd.prog + '.main.button' # create a Slack message that will be used to respond to the User's # interaction which was the invocation of the /demo command. resp = Response(rqst) # ------------------------------------------------------------------------- # define the button callback handler to send a response back to the # User telling the time when they pressed the button # ------------------------------------------------------------------------- @rqst.app.ic.block_action.on(block_id) def on_button(btn_rqst: BlockActionRequest, btn_action: ActionEvent): btn_resp = Response(btn_rqst) btn_resp.send_response(text=( f"At timestamp `{btn_action.data['action_ts']}`, " f"you pressed: *{btn_action.value.title()}*") ) # ------------------------------------------------------------------------- # create a message to send to the User that has two buttons; and when # they click either one, the above callback will be executed. # ------------------------------------------------------------------------- user_id = rqst.user_id resp['blocks'] = extract_json([ SectionBlock(text=MarkdownTextObject(text=f'Hi there <@{user_id}>!')), DividerBlock(), ActionsBlock( block_id=block_id, elements=[ ButtonElement( text='Press for Bad', style='danger', action_id=f'{block_id}.bad', value='bad'), ButtonElement( text='Press for Good', style="primary", action_id=f'{block_id}.good', value='good') ] ), DividerBlock() ]) resp.send()
def delayed_update_view(rqst: ViewRequest, view: View, delay: int): sleep(delay) modal = Modal(rqst=rqst, view=view, detached=True) # If the User clicks on Done, then the `done_booping` handler will be # invoked as a result of the view close. modal.notify_on_close = done_booping view = modal.view view.title = PlainTextObject(text='Booped!') view.close = PlainTextObject(text='Done') view.blocks[0] = SectionBlock(text=PlainTextObject( text=f'First boop after {delay} seconds')) button = view.add_block( SectionBlock(text=PlainTextObject(text='Click button to boop again.'), block_id=cmd.prog + ".boop")) button.accessory = ButtonElement(text='Boop', action_id=button.block_id, value='boop') rqst.app.ic.block_action.on(button.block_id, on_boop_button) res = modal.update() if not res.get('ok'): rqst.app.log.error(f'failed to boop: {res}')
def setUp(self) -> None: self.elements = [ ButtonElement(text=PlainTextObject(text="Click me"), action_id="reg_button", value="1"), LinkButtonElement(text=PlainTextObject(text="URL Button"), url="http://google.com"), ]
def test_home_tab_construction(self): home_tab_view = View( type="home", blocks=[ SectionBlock(text=MarkdownTextObject( text="*Here's what you can do with Project Tracker:*"), ), ActionsBlock(elements=[ ButtonElement( text=PlainTextObject(text="Create New Task", emoji=True), style="primary", value="create_task", ), ButtonElement( text=PlainTextObject(text="Create New Project", emoji=True), value="create_project", ), ButtonElement( text=PlainTextObject(text="Help", emoji=True), value="help", ), ], ), ContextBlock(elements=[ ImageElement( image_url= "https://api.slack.com/img/blocks/bkb_template_images/placeholder.png", alt_text="placeholder", ), ], ), SectionBlock( text=MarkdownTextObject(text="*Your Configurations*"), ), DividerBlock(), SectionBlock( text=MarkdownTextObject( text= "*#public-relations*\n<fakelink.toUrl.com|PR Strategy 2019> posts new tasks, comments, and project updates to <fakelink.toChannel.com|#public-relations>" ), accessory=ButtonElement( text=PlainTextObject(text="Edit", emoji=True), value="public-relations", ), ), ], ) home_tab_view.validate_json()
def test_json_simple(self): button = ButtonElement(text=PlainTextObject(text="button text"), action_id="some_button", value="button_123").to_dict() coded = { "text": {"emoji": True, "text": "button text", "type": "plain_text"}, "action_id": "some_button", "value": "button_123", "type": "button", } self.assertDictEqual(button, coded)
def test_document_1(self): input = { "type": "button", "text": { "type": "plain_text", "text": "Click Me" }, "value": "click_me_123", "action_id": "button", } self.assertDictEqual(input, ButtonElement(**input).to_dict())
def test_document_3(self): input = { "type": "button", "text": { "type": "plain_text", "text": "Link Button" }, "url": "https://api.slack.com/block-kit", } self.assertDictEqual(input, ButtonElement(**input).to_dict()) self.assertDictEqual(input, LinkButtonElement(**input).to_dict())
async def test_with_blocks(self): url = os.environ[SLACK_SDK_TEST_INCOMING_WEBHOOK_URL] webhook = AsyncWebhookClient(url) response = await webhook.send( text="fallback", blocks=[ SectionBlock( block_id="sb-id", text=MarkdownTextObject( text="This is a mrkdwn text section block."), fields=[ PlainTextObject(text="*this is plain_text text*", emoji=True), MarkdownTextObject(text="*this is mrkdwn text*"), PlainTextObject(text="*this is plain_text text*", emoji=True), ]), DividerBlock(), ActionsBlock(elements=[ ButtonElement( text=PlainTextObject(text="Create New Task", emoji=True), style="primary", value="create_task", ), ButtonElement( text=PlainTextObject(text="Create New Project", emoji=True), value="create_project", ), ButtonElement( text=PlainTextObject(text="Help", emoji=True), value="help", ), ], ), ]) self.assertEqual(200, response.status_code) self.assertEqual("ok", response.body)
def test_json(self): self.elements = [ ButtonElement(text="Click me", action_id="reg_button", value="1"), LinkButtonElement(text="URL Button", url="http://google.com"), ] self.dict_elements = [] for e in self.elements: self.dict_elements.append(e.to_dict()) self.assertDictEqual( {"elements": self.dict_elements, "type": "actions"}, ActionsBlock(elements=self.elements).to_dict(), ) with self.assertRaises(SlackObjectFormationError): ActionsBlock(elements=self.elements * 3).to_dict()
def action_go_to_alerts(self, request: GladosRequest, **kwargs): # self.bot.validate_slack_signature(request) self.bot.send_message( message=Message( text="Going to alerts", blocks=[ SectionBlock( text="Confirm Action", accessory=ButtonElement( text="Acknowledge", action_id="ack", value="ack" ), ) ], ), channel=request.json.user.id, )
def test_json_with_confirm(self): confirm = ConfirmObject(title=PlainTextObject(text="really?"), text=PlainTextObject(text="are you sure?")) button = ButtonElement( text=PlainTextObject(text="button text"), action_id="some_button", value="button_123", style="primary", confirm=confirm, ).to_dict() coded = { "text": {"emoji": True, "text": "button text", "type": "plain_text"}, "action_id": "some_button", "value": "button_123", "type": "button", "style": "primary", "confirm": confirm.to_dict(), } self.assertDictEqual(button, coded)
def main(rqst): app: SlackApp = rqst.app params = session[SESSION_KEY]['params'] # define the event ID for when the User clicks the Submit button on the # Modal. bind that event to the code handler that will process the data. event_id = cmd.prog + ".view1" app.ic.view.on(event_id, on_main_modal_submit) priv_data = { 'name': 'Jeremy', 'state': "NC" } # create a Modal instace, which will also defined a View when one is not # provided. Tie the submit callback ID to the envent_id value modal = Modal(rqst) view = modal.view = View( type="modal", title=PlainTextObject(text="Awesome Modal"), callback_id=event_id, close=PlainTextObject(text="Cancel"), submit=PlainTextObject(text="Next"), private_metadata=str(priv_data)) # ------------------------------------------------------------------------- # Create a button block: # Each time the User clicks it a counter will be incremented by 1. # The button click count is stored in the session params. # ------------------------------------------------------------------------- button1 = view.add_block(SectionBlock( text=PlainTextObject(text="It's Block Kit...but _in a modal_"), block_id=event_id + ".button1")) button1.accessory = ButtonElement( text='Click me', value='0', action_id=button1.block_id, style='danger' ) params['clicks'] = 0 # noinspection PyUnusedLocal @app.ic.block_action.on(button1.block_id) def remember_button(btn_rqst: BlockActionRequest): session[SESSION_KEY]['params']['clicks'] += 1 # ------------------------------------------------------------------------- # Create a Checkboxes block: # When the User checks/unchecks the items, they are stored to the session. # ------------------------------------------------------------------------- checkbox_options = [ Option(label='Box 1', value='A1'), Option(label='Box 2', value='B2') ] params['checkboxes'] = checkbox_options[0].value checkbox = view.add_block(SectionBlock( text=PlainTextObject(text='Nifty checkboxes'), block_id=event_id + ".checkbox")) checkbox.accessory = CheckboxesElement( action_id=checkbox.block_id, options=checkbox_options, initial_options=[checkbox_options[0]] ) @app.ic.block_action.on(checkbox.block_id) def remember_check(cb_rqst: BlockActionRequest, action: ActionEvent): session[SESSION_KEY]['params']['checkboxes'] = action.value # ------------------------------------------------------------------------- # Create an Input block: # Required single line of text. # ------------------------------------------------------------------------- view.add_block(InputBlock( label=PlainTextObject(text='First input'), element=PlainTextInputElement( action_id=event_id + ".text1", placeholder='Type in here' ) )) # ------------------------------------------------------------------------- # Create an Input block: # Optional multi-line text area, maximum 500 characters. # ------------------------------------------------------------------------- host_selector = view.add_block(InputBlock( label=PlainTextObject(text='Next input selector ... start typing'), optional=True, block_id=event_id + ".ext1", element=ExternalDataSelectElement( placeholder='hosts ..', action_id=event_id + ".ext1",) )) @app.ic.select.on(host_selector.element.action_id) def select_host_from_dynamic_list(_rqst): return { 'options': extract_json([ Option(label=val, value=val) for val in ('lx5e1234', 'lx5w1234', 'lx5e4552') ]) } # ------------------------------------------------------------------------- # Create an Input Datepicker block # ------------------------------------------------------------------------- view.add_block(InputBlock( label=PlainTextObject(text="Pick a date"), element=DatePickerElement( action_id=event_id + ".datepicker", placeholder='A date' ) )) # ------------------------------------------------------------------------- # Create an Input to select from static list, optional. # ------------------------------------------------------------------------- view.add_block(InputBlock( label=PlainTextObject(text="Select one option"), optional=True, element=SelectElement( placeholder='Select one of ...', action_id=event_id + ".select_1", options=[ Option(label='this', value='this'), Option(label='that', value='that') ] ) )) # ------------------------------------------------------------------------- # Create an Input to allow the User to select multiple items # from a static list. # ------------------------------------------------------------------------- view.add_block(InputBlock( label=PlainTextObject(text="Select many option"), element=StaticMultiSelectElement( placeholder=PlainTextObject(text='Select any of ...'), action_id=event_id + ".select_N", options=[ Option(label='cat', value='cat'), Option(label='dog', value='dog'), Option(label='monkey', value='monkey') ] ) )) res = modal.open(callback=on_main_modal_submit) if not res.get('ok'): app.log.error(json.dumps(res, indent=3))
def test_action_id(self): with self.assertRaises(SlackObjectFormationError): ButtonElement(text="click me!", action_id=STRING_301_CHARS, value="clickable button").to_dict()
def test_invalid_style(self): with self.assertRaises(SlackObjectFormationError): ButtonElement(text="Button", action_id="button", value="button", style="invalid").to_dict()
def test_value_length(self): with self.assertRaises(SlackObjectFormationError): ButtonElement(text="Button", action_id="button", value=STRING_3001_CHARS).to_dict()
def test_text_length(self): with self.assertRaises(SlackObjectFormationError): ButtonElement(text=STRING_301_CHARS, action_id="button", value="click_me").to_dict()
from slack.web.classes.elements import ButtonElement, ExternalDataSelectElement from slack.web.classes.messages import Message from slack.web.classes.objects import MarkdownTextObject from glados import EventRoutes, GladosBot, GladosPlugin, GladosRequest, RouteType from glados.slack_classes.views import Home HOME_VIEW = Home(blocks=[ SectionBlock(text=MarkdownTextObject( text="*Welcome to GLaDOS From Lambda!*")), DividerBlock(), SectionBlock( text="*Security Events*", fields=["*New Alerts*\n20", "*Open Cases*\n5"], accessory=ButtonElement(text="Go To Security Alerts", action_id="gotoSecurityAlerts", value="go"), ), DividerBlock(), SectionBlock( text="*Service Tickets*", fields=["*Total Tickets*\n23"], accessory=ButtonElement(text="Go To Service Desk", action_id="gotoServiceDesk", value="go"), ), DividerBlock(), SectionBlock( text="Test External Menu", accessory=ExternalDataSelectElement(placeholder="Loading", action_id="testMenu"),
OptionGroup, Option, ) from slack.web.classes.elements import ButtonElement, ExternalDataSelectElement from slack.web.classes.actions import ActionButton from glados.slack_classes.views import Home HOME_VIEW = Home(blocks=[ SectionBlock(text=MarkdownTextObject(text="*Welcome to GLaDOS!*")), DividerBlock(), SectionBlock( text="*Security Events*", fields=["*New Alerts*\n20", "*Open Cases*\n5"], accessory=ButtonElement(text="Go To Security Alerts", action_id="gotoSecurityAlerts", value="go"), ), DividerBlock(), SectionBlock( text="*Service Tickets*", fields=["*Total Tickets*\n23"], accessory=ButtonElement(text="Go To Service Desk", action_id="gotoServiceDesk", value="go"), ), DividerBlock(), SectionBlock( text="Test External Menu", accessory=ExternalDataSelectElement(placeholder="Loading", action_id="testMenu"),