async def __call__( self, text: Union[str, dict] = "", blocks: Optional[Sequence[Union[dict, Block]]] = None, attachments: Optional[Sequence[Union[dict, Attachment]]] = None, response_type: Optional[str] = None, replace_original: Optional[bool] = None, delete_original: Optional[bool] = None, ) -> WebhookResponse: if self.response_url is not None: client = AsyncWebhookClient(self.response_url) text_or_whole_response: Union[str, dict] = text if isinstance(text_or_whole_response, str): message = _build_message( text=text, blocks=blocks, attachments=attachments, response_type=response_type, replace_original=replace_original, delete_original=delete_original, ) return await client.send_dict(message) elif isinstance(text_or_whole_response, dict): whole_response: dict = text_or_whole_response message = _build_message(**whole_response) return await client.send_dict(message) else: raise ValueError(f"The arg is unexpected type ({type(text)})") else: raise ValueError( "respond is unsupported here as there is no response_url")
async def test_with_attachments(self): url = os.environ[SLACK_SDK_TEST_INCOMING_WEBHOOK_URL] webhook = AsyncWebhookClient(url) response = await webhook.send( text="fallback", attachments=[ Attachment( text="attachment text", title="Attachment", fallback="fallback_text", pretext="some_pretext", title_link="link in title", fields=[ AttachmentField(title=f"field_{i}_title", value=f"field_{i}_value") for i in range(5) ], color="#FFFF00", author_name="John Doe", author_link="http://johndoeisthebest.com", author_icon="http://johndoeisthebest.com/avatar.jpg", thumb_url="thumbnail URL", footer="and a footer", footer_icon="link to footer icon", ts=123456789, markdown_in=["fields"], ) ], ) self.assertEqual(200, response.status_code) self.assertEqual("ok", response.body)
async def test_webhook(self): url = os.environ[SLACK_SDK_TEST_INCOMING_WEBHOOK_URL] webhook = AsyncWebhookClient(url) response = await webhook.send(text="Hello!") self.assertEqual(200, response.status_code) self.assertEqual("ok", response.body) token = os.environ[SLACK_SDK_TEST_BOT_TOKEN] channel_name = os.environ[ SLACK_SDK_TEST_INCOMING_WEBHOOK_CHANNEL_NAME].replace("#", "") client = AsyncWebClient(token=token) channel_id = None async for resp in await client.conversations_list(limit=10): for c in resp["channels"]: if c["name"] == channel_name: channel_id = c["id"] break if channel_id is not None: break history = await client.conversations_history(channel=channel_id, limit=1) self.assertIsNotNone(history) actual_text = history["messages"][0]["text"] self.assertEqual("Hello!", actual_text)
async def test_ratelimited(self): client = AsyncWebhookClient( "http://localhost:8888/ratelimited", retry_handlers=[AsyncRateLimitErrorRetryHandler()], ) response = await client.send(text="hello!") # Just running retries; no assertions for call count so far self.assertEqual(429, response.status_code)
async def test_user_agent_customization_issue_769(self): client = AsyncWebhookClient( url="http://localhost:8888/user-agent-this_is-test", user_agent_prefix="this_is", user_agent_suffix="test", ) resp = await client.send_dict({"text": "hi!"}) self.assertEqual(resp.body, "ok")
async def test_send(self): client = AsyncWebhookClient("http://localhost:8888") resp: WebhookResponse = await client.send(text="hello!") self.assertEqual(200, resp.status_code) self.assertEqual("ok", resp.body) resp = await client.send(text="hello!", response_type="in_channel") self.assertEqual("ok", resp.body)
async def test_send_blocks(self): client = AsyncWebhookClient("http://localhost:8888") resp = await client.send( text="hello!", response_type="ephemeral", blocks=[ SectionBlock(text="Some text"), ImageBlock(image_url="image.jpg", alt_text="an image"), ], ) self.assertEqual("ok", resp.body) resp = await client.send( text="hello!", response_type="ephemeral", blocks=[ { "type": "section", "text": { "type": "mrkdwn", "text": "This is a mrkdwn section block :ghost: *this is bold*, and ~this is crossed out~, and <https://google.com|this is a link>", }, }, { "type": "divider" }, { "type": "section", "text": { "type": "mrkdwn", "text": "Pick a date for the deadline." }, "accessory": { "type": "datepicker", "initial_date": "1990-04-28", "placeholder": { "type": "plain_text", "text": "Select a date", }, }, }, ], ) self.assertEqual("ok", resp.body) resp = await client.send( text="hello!", response_type="ephemeral", blocks=[ SectionBlock(text="Some text"), ImageBlock(image_url="image.jpg", alt_text="an image"), ], ) self.assertEqual("ok", resp.body)
async def test_send(self): retry_handler = MyRetryHandler(max_retry_count=2) client = AsyncWebhookClient( "http://localhost:8888/remote_disconnected", retry_handlers=[retry_handler], ) try: await client.send(text="hello!") self.fail("An exception is expected") except Exception as _: pass self.assertEqual(2, retry_handler.call_count)
async def test_with_attachments_dict(self): url = os.environ[SLACK_SDK_TEST_INCOMING_WEBHOOK_URL] webhook = AsyncWebhookClient(url) response = await webhook.send( text="fallback", attachments=[{ "author_name": "John Doe", "fallback": "fallback_text", "text": "attachment text", "pretext": "some_pretext", "title": "Attachment", "footer": "and a footer", "id": 1, "author_link": "http://johndoeisthebest.com", "color": "FFFF00", "fields": [ { "title": "field_0_title", "value": "field_0_value", }, { "title": "field_1_title", "value": "field_1_value", }, { "title": "field_2_title", "value": "field_2_value", }, { "title": "field_3_title", "value": "field_3_value", }, { "title": "field_4_title", "value": "field_4_value", }, ], "mrkdwn_in": ["fields"], }], ) self.assertEqual(200, response.status_code) self.assertEqual("ok", response.body)
async def test_webhook(self): url = os.environ[SLACK_SDK_TEST_INCOMING_WEBHOOK_URL] webhook = AsyncWebhookClient(url) response = await webhook.send(text="Hello!") self.assertEqual(200, response.status_code) self.assertEqual("ok", response.body) token = os.environ[SLACK_SDK_TEST_BOT_TOKEN] client = AsyncWebClient(token=token) history = await client.conversations_history(channel=self.channel_id, limit=1) self.assertIsNotNone(history) actual_text = history["messages"][0]["text"] self.assertEqual("Hello!", actual_text)
async def test_with_unfurls_off(self): url = os.environ[SLACK_SDK_TEST_INCOMING_WEBHOOK_URL] token = os.environ[SLACK_SDK_TEST_BOT_TOKEN] webhook = AsyncWebhookClient(url) client = AsyncWebClient(token=token) # send message that does not unfurl response = await webhook.send( text= "<https://imgs.xkcd.com/comics/desert_golfing_2x.png|Desert Golfing>", unfurl_links=False, unfurl_media=False, ) self.assertEqual(200, response.status_code) self.assertEqual("ok", response.body) # wait to allow Slack API to edit message with attachments time.sleep(2) history = await client.conversations_history(channel=self.channel_id, limit=1) self.assertIsNotNone(history) self.assertTrue("attachments" not in history["messages"][0])
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)
async def test_with_unfurls_on(self): # Slack API rate limits unfurls of unique links so test will # fail when repeated. For testing, either use a different URL # for text option or delete existing attachments in webhook channel. url = os.environ[SLACK_SDK_TEST_INCOMING_WEBHOOK_URL] token = os.environ[SLACK_SDK_TEST_BOT_TOKEN] webhook = AsyncWebhookClient(url) client = AsyncWebClient(token=token) # send message that does unfurl response = await webhook.send( text="<https://imgs.xkcd.com/comics/red_spiders_small.jpg|Spiders>", unfurl_links=True, unfurl_media=True, ) self.assertEqual(200, response.status_code) self.assertEqual("ok", response.body) # wait to allow Slack API to edit message with attachments time.sleep(2) history = await client.conversations_history(channel=self.channel_id, limit=1) self.assertIsNotNone(history) # FIXME: when repeatedly running this test, the following assertion can fail self.assertTrue("attachments" in history["messages"][0])
async def test_issue_919_response_url_flag_options(self): client = AsyncWebhookClient("http://localhost:8888") resp = await client.send( text="hello!", response_type="ephemeral", replace_original=True, blocks=[ SectionBlock(text="Some text"), ImageBlock(image_url="image.jpg", alt_text="an image"), ], ) self.assertEqual("ok", resp.body) resp = await client.send( text="hello!", response_type="ephemeral", delete_original=True, blocks=[ SectionBlock(text="Some text"), ImageBlock(image_url="image.jpg", alt_text="an image"), ], ) self.assertEqual("ok", resp.body)
async def test_timeout_issue_712(self): client = AsyncWebhookClient(url="http://localhost:8888/timeout", timeout=1) with self.assertRaises(Exception): await client.send_dict({"text": "hello!"})
async def test_send_attachments(self): client = AsyncWebhookClient("http://localhost:8888") resp = await client.send( text="hello!", response_type="ephemeral", attachments=[ { "color": "#f2c744", "blocks": [ { "type": "section", "text": { "type": "mrkdwn", "text": "This is a mrkdwn section block :ghost: *this is bold*, and ~this is crossed out~, and <https://google.com|this is a link>", }, }, {"type": "divider"}, { "type": "section", "text": { "type": "mrkdwn", "text": "Pick a date for the deadline.", }, "accessory": { "type": "datepicker", "initial_date": "1990-04-28", "placeholder": { "type": "plain_text", "text": "Select a date", }, }, }, ], } ], ) self.assertEqual("ok", resp.body) resp = await client.send( text="hello!", response_type="ephemeral", attachments=[ Attachment( text="attachment text", title="Attachment", fallback="fallback_text", pretext="some_pretext", title_link="link in title", fields=[ AttachmentField( title=f"field_{i}_title", value=f"field_{i}_value" ) for i in range(5) ], color="#FFFF00", author_name="John Doe", author_link="http://johndoeisthebest.com", author_icon="http://johndoeisthebest.com/avatar.jpg", thumb_url="thumbnail URL", footer="and a footer", footer_icon="link to footer icon", ts=123456789, markdown_in=["fields"], ) ], ) self.assertEqual("ok", resp.body)
async def test_if_it_uses_custom_logger_issue_921(self): logger = CustomLogger("test-logger") client = AsyncWebhookClient(url="http://localhost:8888", logger=logger) await client.send_dict({"text": "hi!"}) self.assertTrue(logger.called)
async def test_send_dict(self): client = AsyncWebhookClient("http://localhost:8888") resp: WebhookResponse = await client.send_dict({"text": "hello!"}) self.assertEqual(200, resp.status_code) self.assertEqual("ok", resp.body)
async def test_with_blocks_dict(self): url = os.environ[SLACK_SDK_TEST_INCOMING_WEBHOOK_URL] webhook = AsyncWebhookClient(url) response = await webhook.send( text="fallback", blocks=[ { "type": "section", "block_id": "sb-id", "text": { "type": "mrkdwn", "text": "This is a mrkdwn text section block.", }, "fields": [ { "type": "plain_text", "text": "*this is plain_text text*", }, { "type": "mrkdwn", "text": "*this is mrkdwn text*", }, { "type": "plain_text", "text": "*this is plain_text text*", }, ], }, { "type": "divider", "block_id": "9SxG" }, { "type": "actions", "block_id": "avJ", "elements": [ { "type": "button", "action_id": "yXqIx", "text": { "type": "plain_text", "text": "Create New Task", }, "style": "primary", "value": "create_task", }, { "type": "button", "action_id": "KCdDw", "text": { "type": "plain_text", "text": "Create New Project", }, "value": "create_project", }, { "type": "button", "action_id": "MXjB", "text": { "type": "plain_text", "text": "Help", }, "value": "help", }, ], }, ], ) self.assertEqual(200, response.status_code) self.assertEqual("ok", response.body)
async def test_proxy_issue_714(self): client = AsyncWebhookClient( url="http://localhost:8888", proxy="http://invalid-host:9999" ) with self.assertRaises(Exception): await client.send_dict({"text": "hello!"})