Пример #1
0
    def test_basic_json(self):
        self.assertDictEqual(
            {"text": "some text", "type": "mrkdwn"},
            MarkdownTextObject(text="some text").to_dict(),
        )

        self.assertDictEqual(
            {"text": "some text", "verbatim": True, "type": "mrkdwn"},
            MarkdownTextObject(text="some text", verbatim=True).to_dict(),
        )
Пример #2
0
 def build_slack_block_native(cls, msg1, msg2, data):
     blocks: List[SectionBlock] = [
         SectionBlock(text=MarkdownTextObject.parse(f"*{msg1}*:\n{msg2}")),
         SectionBlock(fields=[]),
     ]
     names: List[str] = list(set(data.keys()) - set("user_comments"))
     fields = [
         MarkdownTextObject.parse(f"*{name}*:\n{data[name]}") for name in names
     ]
     blocks[1].fields = fields
     return list(b.to_dict() for b in blocks)
 def test_basic_json(self):
     expected = {
         "confirm": {
             "emoji": True,
             "text": "Yes",
             "type": "plain_text"
         },
         "deny": {
             "emoji": True,
             "text": "No",
             "type": "plain_text"
         },
         "text": {
             "text": "are you sure?",
             "type": "mrkdwn",
             "verbatim": False
         },
         "title": {
             "emoji": True,
             "text": "some title",
             "type": "plain_text"
         },
     }
     simple_object = ConfirmObject(
         title=PlainTextObject(text="some title"),
         text=MarkdownTextObject(text="are you sure?")).to_dict()
     self.assertDictEqual(simple_object, expected)
 def test_confirm_overrides(self):
     confirm = ConfirmObject(
         title=PlainTextObject(text="some title"),
         text=MarkdownTextObject(text="are you sure?"),
         confirm=PlainTextObject(text="I'm really sure"),
         deny=PlainTextObject(text="Nevermind"),
     )
     expected = {
         "confirm": {
             "emoji": True,
             "text": "I'm really sure",
             "type": "plain_text"
         },
         "deny": {
             "emoji": True,
             "text": "Nevermind",
             "type": "plain_text"
         },
         "text": {
             "text": "are you sure?",
             "type": "mrkdwn",
             "verbatim": False
         },
         "title": {
             "emoji": True,
             "text": "some title",
             "type": "plain_text"
         },
     }
     self.assertDictEqual(confirm.to_dict(), expected)
Пример #5
0
def on_401_unauthorized(exc):

    try:
        msg = exc.args[0]
        code = exc.args[1]
        rqst: AnyRequest = exc.args[2]

    except Exception as exc:
        errmsg = "App error called with exception: {}".format(str(exc))
        slackapp.log.error(errmsg)
        err = dict(blocks=[SectionBlock(text=MarkdownTextObject(text=f"```{errmsg}```")).to_dict()])
        return jsonify(err)

    errmsg = f"I'm sorry <@{rqst.user_id}>, I'm not authorized do to that."
    msg = dict(blocks=[SectionBlock(text=MarkdownTextObject(text=f"```{errmsg}```")).to_dict()])
    return jsonify(msg)
Пример #6
0
def on_main_modal_submit(rqst: ViewRequest, input_values: Dict):
    params = session[SESSION_KEY]['params']

    # The input_values is a dictionary of key=action_id and value=user-input
    # since all action_id are formulated with dots (.), just use the
    # last token as the variable name when form

    results = {k.rpartition('.')[-1]: v for k, v in input_values.items()}

    results.update(dict(clicks=params['clicks']))

    modal = Modal(
        rqst,
        view=View(type="modal",
                  title=PlainTextObject(text='Modal Results'),
                  close=PlainTextObject(text='Done'),
                  clear_on_close=True,
                  blocks=[
                      SectionBlock(text=PlainTextObject(
                          text="Input results in raw JSON")),
                      SectionBlock(text=MarkdownTextObject(
                          text="```" + json.dumps(results, indent=3) + "```"))
                  ]))

    return modal.push()
Пример #7
0
 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()
Пример #8
0
    def test_text_length_with_object(self):
        with self.assertRaises(SlackObjectFormationError):
            plaintext = PlainTextObject(text=STRING_301_CHARS)
            ConfirmObject(title="title", text=plaintext).to_dict()

        with self.assertRaises(SlackObjectFormationError):
            markdown = MarkdownTextObject(text=STRING_301_CHARS)
            ConfirmObject(title="title", text=markdown).to_dict()
Пример #9
0
 def update_message(self, request: GladosRequest, **kwargs):
     message = Message(
         text=request.json.message,
         blocks=[
             ContextBlock(elements=[
                 MarkdownTextObject(
                     text=
                     f"Message Updated: {datetime.now().isoformat(sep=' ', timespec='minutes')}"
                 )
             ]),
             SectionBlock(text=MarkdownTextObject(
                 text=request.json.message)),
         ],
     )
     return self.bot.update_message(channel=request.json.channel,
                                    ts=request.json.ts,
                                    message=message)
Пример #10
0
def on_slack_apierror(exc):
    errmsg = f"Error with call to api.slack.com: {str(exc)}"
    slackapp.log.error(errmsg)
    msg = dict(blocks=[
        SectionBlock(text=MarkdownTextObject(
            text=f"```{errmsg}```")).to_dict()
    ])
    return jsonify(msg)
Пример #11
0
 def test_json_with_fields(self):
     self.assertDictEqual(
         SectionBlock(text=MarkdownTextObject(text="some text"),
                      fields=[
                          MarkdownTextObject(text=f"field{i}")
                          for i in range(5)
                      ]).to_dict(),
         {
             "text": {
                 "text": "some text",
                 "type": "mrkdwn",
                 "verbatim": False
             },
             "fields": [
                 {
                     "text": "field0",
                     "type": "mrkdwn",
                     "verbatim": False
                 },
                 {
                     "text": "field1",
                     "type": "mrkdwn",
                     "verbatim": False
                 },
                 {
                     "text": "field2",
                     "type": "mrkdwn",
                     "verbatim": False
                 },
                 {
                     "text": "field3",
                     "type": "mrkdwn",
                     "verbatim": False
                 },
                 {
                     "text": "field4",
                     "type": "mrkdwn",
                     "verbatim": False
                 },
             ],
             "type":
             "section",
         },
     )
Пример #12
0
def on_general_exception(exc):
    exc_info = sys.exc_info()
    tb_content = json.dumps(traceback.format_tb(exc_info[2]), indent=3)
    errmsg = f"Unexpected error: {str(exc)}:\n{tb_content}"
    slackapp.log.critical(errmsg)
    msg = dict(blocks=[
        SectionBlock(text=MarkdownTextObject(
            text=f"```{errmsg}```")).to_dict()
    ])
    return jsonify(msg)
Пример #13
0
    def test_passing_text_objects(self):
        direct_construction = ConfirmObject(
            title=PlainTextObject(text="title"),
            text=MarkdownTextObject(text="Are you sure?"))

        mrkdwn = MarkdownTextObject(text="Are you sure?")

        preconstructed = ConfirmObject(title=PlainTextObject(text="title"),
                                       text=mrkdwn)

        self.assertDictEqual(direct_construction.to_dict(),
                             preconstructed.to_dict())

        plaintext = PlainTextObject(text="Are you sure?", emoji=False)

        passed_plaintext = ConfirmObject(title=PlainTextObject(text="title"),
                                         text=plaintext)

        self.assertDictEqual(
            passed_plaintext.to_dict(),
            {
                "confirm": {
                    "emoji": True,
                    "text": "Yes",
                    "type": "plain_text"
                },
                "deny": {
                    "emoji": True,
                    "text": "No",
                    "type": "plain_text"
                },
                "text": {
                    "emoji": False,
                    "text": "Are you sure?",
                    "type": "plain_text"
                },
                "title": {
                    "emoji": True,
                    "text": "title",
                    "type": "plain_text"
                },
            },
        )
Пример #14
0
 def send_message(self, request: GladosRequest, **kwargs):
     message = Message(
         text=request.json.message,
         blocks=[
             SectionBlock(text=MarkdownTextObject(
                 text=request.json.message))
         ],
     )
     return self.bot.send_message(channel=request.json.channel,
                                  message=message)
Пример #15
0
 def test_from_list_of_json_objects(self):
     json_objects = [
         PlainTextObject(text="foo"),
         MarkdownTextObject(text="bar"),
     ]
     output = extract_json(json_objects)
     expected = {"result": [
         {"type": "plain_text", "text": "foo", "emoji": True},
         {"type": "mrkdwn", "text": "bar", "verbatim": False},
     ]}
     self.assertDictEqual(expected, {"result": output})
Пример #16
0
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()
Пример #17
0
 def test_json_simple(self):
     section = SectionBlock(text=MarkdownTextObject(text="some text"),
                            block_id="a_block").to_dict()
     json = {
         "text": {
             "text": "some text",
             "type": "mrkdwn",
             "verbatim": False
         },
         "block_id": "a_block",
         "type": "section",
     }
     self.assertDictEqual(section, json)
 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)
Пример #19
0
def on_view2_submit(rqst: ViewRequest):

    # same technique as on_main_modal_submit; in this case disable the submit
    # button only allow the User to click the "Done" (close) button.

    modal = Modal(rqst)

    view = modal.view
    view.title = PlainTextObject(text='Final Modal View')
    view.close = PlainTextObject(text='Done')
    view.submit = None

    view.add_block(SectionBlock(text=MarkdownTextObject(text='Final bit.')))

    return modal.update()
Пример #20
0
 def test_json_with_accessory(self):
     button = LinkButtonElement(text=PlainTextObject(text="Click me!"),
                                url="http://google.com")
     section = SectionBlock(text=MarkdownTextObject(text="some text"),
                            accessory=button).to_dict()
     coded = {
         "text": {
             "text": "some text",
             "type": "mrkdwn",
             "verbatim": False
         },
         "accessory": button.to_dict(),
         "type": "section",
     }
     self.assertDictEqual(section, coded)
Пример #21
0
def on_dialog_submit(rqst: DialogRequest, submit):
    # when the User clicks submit from the dialog, this function is called and
    # a response message is send to the User showing their inputs; as well as a
    # state variable that was hardcoded.

    resp = Response(rqst)

    resp['blocks'] = [
        blocks.SectionBlock(text=MarkdownTextObject(text=f"""
Your selections:\n
*message*: {submit['message']}
*signature*: {submit['signature']}\n
*state* `value`: {rqst.state['value']} (hardcoded in demo)
""")).to_dict()
    ]

    res = resp.send_response()
Пример #22
0
def main(rqst: AnyRequest):

    # create a Modal and view, setting the callback so that when the User
    # clicks the "Next" button the code in on_main_modal_submit will be used as
    # the handler.

    Modal(rqst,
          callback=on_main_modal_submit,
          view=View(type="modal",
                    title='First Modal View',
                    callback_id=cmd.prog + ".view1",
                    close='Cancel',
                    submit='Next',
                    blocks=[
                        SectionBlock(text=MarkdownTextObject(
                            text="This is the *first* modal view."))
                    ])).open()
Пример #23
0
def on_main_modal_submit(rqst: ViewRequest):

    # define the modal and view based on the received view request from
    # api.slack.com as a result of this instance, the code can then "update"
    # the view by returning the update payload as a resposse message.

    modal = Modal(rqst)

    view = modal.view
    view.title = PlainTextObject(text=('Second Modal View'))

    view.callback_id = cmd.prog + ".view2"
    modal.callback = on_view2_submit

    view.add_block(
        SectionBlock(text=MarkdownTextObject(
            text="This is the *second* modal view.")))

    return modal.update()
Пример #24
0
    def test_json_with_confirm(self):
        confirm = ConfirmObject(title=PlainTextObject(text="confirm_title"),
                                text=MarkdownTextObject(text="confirm_text"))
        button = ActionButton(
            name="button_1",
            text="Click me!",
            value="btn_1",
            confirm=confirm,
            style="danger",
        ).to_dict()

        coded = {
            "name": "button_1",
            "text": "Click me!",
            "value": "btn_1",
            "type": "button",
            "confirm": confirm.to_dict("action"),
            "style": "danger",
        }
        self.assertDictEqual(button, coded)
Пример #25
0
from slack.web.classes.blocks import ContextBlock, SectionBlock, DividerBlock
from slack.web.classes.messages import Message
from slack.web.classes.objects import (
    MarkdownTextObject,
    PlainTextObject,
    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"),
    ),
Пример #26
0
 def test_valid_construction(self):
     modal_view = View(
         type="modal",
         callback_id="modal-id",
         title=PlainTextObject(text="Awesome Modal"),
         submit=PlainTextObject(text="Submit"),
         close=PlainTextObject(text="Cancel"),
         blocks=[
             InputBlock(
                 block_id="b-id",
                 label=PlainTextObject(text="Input label"),
                 element=PlainTextInputElement(action_id="a-id"),
             ),
             InputBlock(
                 block_id="cb-id",
                 label=PlainTextObject(text="Label"),
                 element=CheckboxesElement(
                     action_id="a-cb-id",
                     options=[
                         Option(
                             text=PlainTextObject(
                                 text="*this is plain_text text*"),
                             value="v1",
                         ),
                         Option(
                             text=MarkdownTextObject(
                                 text="*this is mrkdwn text*"),
                             value="v2",
                         ),
                     ],
                 ),
             ),
             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(),
             SectionBlock(
                 block_id="rb-id",
                 text=MarkdownTextObject(
                     text=
                     "This is a section block with radio button accessory"),
                 accessory=RadioButtonsElement(
                     initial_option=Option(
                         text=PlainTextObject(text="Option 1"),
                         value="option 1",
                         description=PlainTextObject(
                             text="Description for option 1"),
                     ),
                     options=[
                         Option(
                             text=PlainTextObject(text="Option 1"),
                             value="option 1",
                             description=PlainTextObject(
                                 text="Description for option 1"),
                         ),
                         Option(
                             text=PlainTextObject(text="Option 2"),
                             value="option 2",
                             description=PlainTextObject(
                                 text="Description for option 2"),
                         ),
                     ],
                 ),
             ),
         ],
     )
     modal_view.validate_json()
Пример #27
0
 def test_deny_length(self):
     with self.assertRaises(SlackObjectFormationError):
         ConfirmObject(
             title=PlainTextObject(text="title"),
             text=MarkdownTextObject(text="Are you sure?"),
             deny=PlainTextObject(text=STRING_51_CHARS)).to_dict()
Пример #28
0
 def test_fields_length(self):
     with self.assertRaises(SlackObjectFormationError):
         SectionBlock(fields=[
             MarkdownTextObject(text=f"field{i}") for i in range(11)
         ]).to_dict()
Пример #29
0
 def test_from_string(self):
     markdown = MarkdownTextObject(text="some text")
     self.assertDictEqual(
         markdown.to_dict(),
         MarkdownTextObject.direct_from_string("some text"))
Пример #30
0
from slack.web.classes.blocks import DividerBlock, SectionBlock
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",