Exemple #1
0
 def test_close_in_home_tab(self):
     modal_view = View(
         type="home",
         callback_id="home-tab-id",
         close=PlainTextObject(text="Cancel"),
         blocks=[DividerBlock()],
     )
     with self.assertRaises(SlackObjectFormationError):
         modal_view.validate_json()
 def test_eq(self):
     input = {
         "type": "modal",
         "blocks": [DividerBlock()],
     }
     another_input = {
         "type": "modal",
         "blocks": [DividerBlock(), DividerBlock()],
     }
     self.assertEqual(View(**input), View(**input))
     self.assertNotEqual(View(**input), View(**another_input))
 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 open_modal(trigger_id: str):
    try:
        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-1",
                    label=PlainTextObject(text="Input label"),
                    element=ConversationSelectElement(
                        action_id="a",
                        default_to_current_conversation=True,
                    ),
                ),
                InputBlock(
                    block_id="b-id-2",
                    label=PlainTextObject(text="Input label"),
                    element=ConversationMultiSelectElement(
                        action_id="a",
                        max_selected_items=2,
                        default_to_current_conversation=True,
                    ),
                ),
            ],
        )
        api_response = client.views_open(trigger_id=trigger_id, view=view)
        return make_response("", 200)
    except SlackApiError as e:
        code = e.response["error"]
        return make_response(f"Failed to open a modal due to {code}", 200)
Exemple #5
0
 async def test_view_update_2(self):
     ack = AsyncAck()
     response: BoltResponse = await ack(
         response_action="update",
         view=View(
             type="modal",
             callback_id="view-id",
             title=PlainTextObject(text="My App"),
             close=PlainTextObject(text="Cancel"),
             blocks=[DividerBlock(block_id="b")],
         ),
     )
     assert (response.status, response.body) == (
         200,
         ""
         '{"response_action": "update", '
         '"view": {'
         '"blocks": [{"block_id": "b", "type": "divider"}], '
         '"callback_id": "view-id", '
         '"close": {"text": "Cancel", "type": "plain_text"}, '
         '"title": {"text": "My App", "type": "plain_text"}, '
         '"type": "modal"'
         "}"
         "}",
     )
Exemple #6
0
 def test_invalid_type_value(self):
     modal_view = View(
         type="modallll",
         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"),
             ),
         ],
     )
     with self.assertRaises(SlackObjectFormationError):
         modal_view.validate_json()
Exemple #7
0
def slack_app():
    if not signature_verifier.is_valid_request(request.get_data(),
                                               request.headers):
        return make_response("invalid request", 403)

    if "payload" in request.form:
        payload = json.loads(request.form["payload"])
        if (payload["type"] == "shortcut"
                and payload["callback_id"] == "open-modal-shortcut"):
            # Open a new modal by a global shortcut
            try:
                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"),
                        )
                    ],
                )
                api_response = client.views_open(
                    trigger_id=payload["trigger_id"],
                    view=view,
                )
                return make_response("", 200)
            except SlackApiError as e:
                code = e.response["error"]
                return make_response(f"Failed to open a modal due to {code}",
                                     200)

        if (payload["type"] == "view_submission"
                and payload["view"]["callback_id"] == "modal-id"):
            # Handle a data submission request from the modal
            submitted_data = payload["view"]["state"]["values"]
            print(
                submitted_data
            )  # {'b-id': {'a-id': {'type': 'plain_text_input', 'value': 'your input'}}}
            return make_response("", 200)

    return make_response("", 404)
Exemple #8
0
async def shortcuts(request: Request):
    form = await request.form()
    payload = Payload.parse_raw(form['payload'])
    try:
        team_conf = TeamConf.get(payload.team.id)
    except TeamConf.DoesNotExist:
        return Response(status_code=HTTPStatus.BAD_REQUEST)
    client = WebClient(team_conf.access_token)
    if payload.callback_id == 'edit_emoji_set':
        emoji_set = team_conf.emoji_set
        # 登録できるemojiは3つまで
        if emoji_set is None:
            emoji_count = 0
            external_input = 3
            blocks = []
        else:
            emoji_count = len(emoji_set)
            external_input = 3 - emoji_count
            blocks = [
                InputBlock(
                    block_id=f'emoji_{index}',
                    label=f':{item}:',
                    element=PlainTextInputElement(
                        action_id=f'emoji_{index}',
                        initial_value=item,
                        placeholder=':atodeyomu:',
                    ),
                    optional=True,
                ) for index, item in enumerate(emoji_set)
            ]
        blocks += [
            InputBlock(
                block_id=f'emoji_{emoji_count + i}',
                label=f'追加するemoji({emoji_count + i}つ目)',
                element=PlainTextInputElement(action_id=f'emoji_{emoji_count + i}', placeholder=':atodeyomu:'),
                optional=True,
            ) for i in range(external_input)
        ]
        view = View(title='emojiを追加する', type='modal', callback_id='edit_emoji_set', blocks=blocks, submit='送信')
        if payload.trigger_id:
            client.views_open(trigger_id=payload.trigger_id, view=view)
    return Response()
Exemple #9
0
    def __init__(self, ack: Ack, client: WebClient, context: BoltContext,
                 logger: logger, request: BoltRequest, view: View):
        logger.info("Updating Zotero config...")
        super().__init__(context.get('user_id'))
        state: dict = view.get('state')
        form_fields: dict = state['values']
        sql_fields: dict = {'user_id': context.get('user_id')}
        for i in form_fields:
            form_field: dict = form_fields[i]
            for t in form_field:
                field_name: str = t
                field = form_field[t]
                field_type = field.get('type')
                field_value: dict = field.get('value')
                if field_type == 'static_select':
                    field_value = field.get('selected_option').get('value')

                if field_value is None and hasattr(self, field_name):
                    field_value = getattr(self, field_name)

                if field_name == 'zotero_api_key':
                    field_value = self.db.cipher.encrypt(
                        field_value.encode('utf-8'))

                sql_fields[field_name] = field_value

        placeholders: list = []
        for i in range(0, len(sql_fields)):
            placeholders.append("?")

        placeholder: str = ','.join(placeholders)
        field_names: str = ', '.join(sql_fields.keys())
        insert_query = f"INSERT OR REPLACE INTO {self.table_name} ({field_names}) VALUES({placeholder})"
        self.db.cursor.execute(insert_query, list(sql_fields.values()))
        self.db.connection.commit()
        ack()
Exemple #10
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()
Exemple #11
0
 def verify_loaded_view_object(self, file):
     input = json.load(file)
     view = View(**input)
     self.assertDictEqual(input, view.to_dict())
Exemple #12
0
def handle_command(body: dict, ack: Ack, respond: Respond, client: WebClient,
                   logger: Logger) -> None:
    logger.info(body)
    ack(
        text="Accepted!",
        blocks=[
            SectionBlock(
                block_id="b",
                text=MarkdownTextObject(text=":white_check_mark: Accepted!"),
            )
        ],
    )

    respond(blocks=[
        SectionBlock(
            block_id="b",
            text=MarkdownTextObject(
                text="You can add a button alongside text in your message. "),
            accessory=ButtonElement(
                action_id="a",
                text=PlainTextObject(text="Button"),
                value="click_me_123",
            ),
        ),
    ])

    res = client.views_open(
        trigger_id=body["trigger_id"],
        view=View(
            type="modal",
            callback_id="view-id",
            title=PlainTextObject(text="My App"),
            submit=PlainTextObject(text="Submit"),
            close=PlainTextObject(text="Cancel"),
            blocks=[
                InputBlock(
                    element=PlainTextInputElement(action_id="text"),
                    label=PlainTextObject(text="Label"),
                ),
                InputBlock(
                    block_id="es_b",
                    element=ExternalDataSelectElement(
                        action_id="es_a",
                        placeholder=PlainTextObject(text="Select an item"),
                        min_query_length=0,
                    ),
                    label=PlainTextObject(text="Search"),
                ),
                InputBlock(
                    block_id="mes_b",
                    element=ExternalDataMultiSelectElement(
                        action_id="mes_a",
                        placeholder=PlainTextObject(text="Select an item"),
                        min_query_length=0,
                    ),
                    label=PlainTextObject(text="Search (multi)"),
                ),
            ],
        ),
    )
    logger.info(res)
 def verify_loaded_view_object(self, file):
     input = json.load(file)
     view = View(**input)
     self.assertTrue(view.state is None or isinstance(view.state, ViewState))
     self.assertDictEqual(input, view.to_dict())