|
55 | 55 | SlackThreadId, |
56 | 56 | SlackWebhookVerifier, |
57 | 57 | ) |
58 | | -from chat_sdk.emoji import convert_emoji_placeholders, emoji_to_slack, resolve_emoji_from_slack |
| 58 | +from chat_sdk.emoji import emoji_to_slack, resolve_emoji_from_slack |
59 | 59 | from chat_sdk.logger import ConsoleLogger, Logger |
60 | 60 | from chat_sdk.modals import ModalElement, OptionsLoadGroup, SelectOptionElement |
61 | 61 | from chat_sdk.shared.adapter_utils import extract_card, extract_files |
@@ -3354,35 +3354,6 @@ def _is_message_from_self(self, event: dict[str, Any]) -> bool: |
3354 | 3354 | return True |
3355 | 3355 | return bool(self._bot_id and event.get("bot_id") == self._bot_id) |
3356 | 3356 |
|
3357 | | - # ================================================================== |
3358 | | - # Table block rendering |
3359 | | - # ================================================================== |
3360 | | - |
3361 | | - def _render_with_table_blocks(self, message: AdapterPostableMessage) -> dict[str, Any] | None: |
3362 | | - """Try to render a message with native Slack table blocks. |
3363 | | -
|
3364 | | - Returns ``{"text": ..., "blocks": ...}`` if the message contains tables, |
3365 | | - ``None`` otherwise. |
3366 | | - """ |
3367 | | - ast: dict[str, Any] | None = None |
3368 | | - if isinstance(message, dict): |
3369 | | - ast = message.get("ast") # type: ignore[union-attr] |
3370 | | - elif hasattr(message, "ast"): |
3371 | | - ast = getattr(message, "ast", None) |
3372 | | - elif hasattr(message, "markdown"): |
3373 | | - # We don't have a full markdown->AST parser in Python; skip table blocks |
3374 | | - return None |
3375 | | - |
3376 | | - if not ast: |
3377 | | - return None |
3378 | | - |
3379 | | - blocks = self._format_converter.to_blocks_with_table(ast) |
3380 | | - if not blocks: |
3381 | | - return None |
3382 | | - |
3383 | | - fallback_text = convert_emoji_placeholders(self._format_converter.render_postable(message), "slack") |
3384 | | - return {"text": fallback_text, "blocks": blocks} |
3385 | | - |
3386 | 3357 | # ================================================================== |
3387 | 3358 | # Post / Edit / Delete messages |
3388 | 3359 | # ================================================================== |
@@ -3446,38 +3417,21 @@ async def post_message(self, thread_id: str, message: AdapterPostableMessage) -> |
3446 | 3417 | ), |
3447 | 3418 | ) |
3448 | 3419 |
|
3449 | | - # Table blocks |
3450 | | - table_result = self._render_with_table_blocks(message) |
3451 | | - if table_result: |
3452 | | - result = await client.chat_postMessage( |
3453 | | - channel=channel, |
3454 | | - thread_ts=thread_ts or None, |
3455 | | - text=table_result["text"], |
3456 | | - blocks=table_result["blocks"], |
3457 | | - unfurl_links=False, |
3458 | | - unfurl_media=False, |
3459 | | - ) |
3460 | | - return RawMessage( |
3461 | | - id=result.get("ts", ""), |
3462 | | - thread_id=thread_id, |
3463 | | - raw=self._augment_raw_with_uploads( |
3464 | | - result.data if hasattr(result, "data") else result, |
3465 | | - uploaded_file_ids, |
3466 | | - ), |
3467 | | - ) |
3468 | | - |
3469 | | - # Regular text |
3470 | | - text = convert_emoji_placeholders(self._format_converter.render_postable(message), "slack") |
| 3420 | + payload = self._format_converter.to_slack_payload(message) |
3471 | 3421 | self._logger.debug( |
3472 | 3422 | "Slack API: chat.postMessage", |
3473 | | - {"channel": channel, "threadTs": thread_ts, "textLength": len(text)}, |
| 3423 | + { |
| 3424 | + "channel": channel, |
| 3425 | + "threadTs": thread_ts, |
| 3426 | + "payloadKey": "markdown_text" if "markdown_text" in payload else "text", |
| 3427 | + }, |
3474 | 3428 | ) |
3475 | 3429 | result = await client.chat_postMessage( |
3476 | 3430 | channel=channel, |
3477 | 3431 | thread_ts=thread_ts or None, |
3478 | | - text=text, |
3479 | 3432 | unfurl_links=False, |
3480 | 3433 | unfurl_media=False, |
| 3434 | + **payload, |
3481 | 3435 | ) |
3482 | 3436 | return RawMessage( |
3483 | 3437 | id=result.get("ts", ""), |
@@ -3547,22 +3501,16 @@ async def edit_message( |
3547 | 3501 | raw=result.data if hasattr(result, "data") else result, |
3548 | 3502 | ) |
3549 | 3503 |
|
3550 | | - table_result = self._render_with_table_blocks(message) |
3551 | | - if table_result: |
3552 | | - result = await client.chat_update( |
3553 | | - channel=channel, |
3554 | | - ts=message_id, |
3555 | | - text=table_result["text"], |
3556 | | - blocks=table_result["blocks"], |
3557 | | - ) |
3558 | | - return RawMessage( |
3559 | | - id=result.get("ts", ""), |
3560 | | - thread_id=thread_id, |
3561 | | - raw=result.data if hasattr(result, "data") else result, |
3562 | | - ) |
3563 | | - |
3564 | | - text = convert_emoji_placeholders(self._format_converter.render_postable(message), "slack") |
3565 | | - result = await client.chat_update(channel=channel, ts=message_id, text=text) |
| 3504 | + payload = self._format_converter.to_slack_payload(message) |
| 3505 | + self._logger.debug( |
| 3506 | + "Slack API: chat.update", |
| 3507 | + { |
| 3508 | + "channel": channel, |
| 3509 | + "messageId": message_id, |
| 3510 | + "payloadKey": "markdown_text" if "markdown_text" in payload else "text", |
| 3511 | + }, |
| 3512 | + ) |
| 3513 | + result = await client.chat_update(channel=channel, ts=message_id, **payload) |
3566 | 3514 | return RawMessage( |
3567 | 3515 | id=result.get("ts", ""), |
3568 | 3516 | thread_id=thread_id, |
@@ -3864,28 +3812,21 @@ async def post_ephemeral( |
3864 | 3812 | raw=result.data if hasattr(result, "data") else result, |
3865 | 3813 | ) |
3866 | 3814 |
|
3867 | | - table_result = self._render_with_table_blocks(message) |
3868 | | - if table_result: |
3869 | | - result = await client.chat_postEphemeral( |
3870 | | - channel=channel, |
3871 | | - thread_ts=thread_ts or None, |
3872 | | - user=user_id, |
3873 | | - text=table_result["text"], |
3874 | | - blocks=table_result["blocks"], |
3875 | | - ) |
3876 | | - return EphemeralMessage( |
3877 | | - id=result.get("message_ts", ""), |
3878 | | - thread_id=thread_id, |
3879 | | - used_fallback=False, |
3880 | | - raw=result.data if hasattr(result, "data") else result, |
3881 | | - ) |
3882 | | - |
3883 | | - text = convert_emoji_placeholders(self._format_converter.render_postable(message), "slack") |
| 3815 | + payload = self._format_converter.to_slack_payload(message) |
| 3816 | + self._logger.debug( |
| 3817 | + "Slack API: chat.postEphemeral", |
| 3818 | + { |
| 3819 | + "channel": channel, |
| 3820 | + "threadTs": thread_ts, |
| 3821 | + "userId": user_id, |
| 3822 | + "payloadKey": "markdown_text" if "markdown_text" in payload else "text", |
| 3823 | + }, |
| 3824 | + ) |
3884 | 3825 | result = await client.chat_postEphemeral( |
3885 | 3826 | channel=channel, |
3886 | 3827 | thread_ts=thread_ts or None, |
3887 | 3828 | user=user_id, |
3888 | | - text=text, |
| 3829 | + **payload, |
3889 | 3830 | ) |
3890 | 3831 | return EphemeralMessage( |
3891 | 3832 | id=result.get("message_ts", ""), |
@@ -3948,14 +3889,23 @@ async def schedule_message( |
3948 | 3889 | unfurl_media=False, |
3949 | 3890 | ) |
3950 | 3891 | else: |
3951 | | - text = convert_emoji_placeholders(self._format_converter.render_postable(message), "slack") |
| 3892 | + payload = self._format_converter.to_slack_payload(message) |
| 3893 | + self._logger.debug( |
| 3894 | + "Slack API: chat.scheduleMessage", |
| 3895 | + { |
| 3896 | + "channel": channel, |
| 3897 | + "threadTs": thread_ts, |
| 3898 | + "postAt": post_at_unix, |
| 3899 | + "payloadKey": "markdown_text" if "markdown_text" in payload else "text", |
| 3900 | + }, |
| 3901 | + ) |
3952 | 3902 | result = await client.chat_scheduleMessage( |
3953 | 3903 | channel=channel, |
3954 | 3904 | thread_ts=thread_ts or None, |
3955 | 3905 | post_at=post_at_unix, |
3956 | | - text=text, |
3957 | 3906 | unfurl_links=False, |
3958 | 3907 | unfurl_media=False, |
| 3908 | + **payload, |
3959 | 3909 | ) |
3960 | 3910 |
|
3961 | 3911 | scheduled_message_id = result.get("scheduled_message_id", "") |
@@ -4425,7 +4375,10 @@ def parse_message(self, raw: dict[str, Any]) -> Message: |
4425 | 4375 | return self._parse_slack_message_sync(event, thread_id) |
4426 | 4376 |
|
4427 | 4377 | def render_formatted(self, content: FormattedContent) -> str: |
4428 | | - """Render formatted content (AST) to Slack mrkdwn.""" |
| 4378 | + """Render formatted content (AST) to standard markdown. |
| 4379 | +
|
| 4380 | + Slack now accepts markdown natively via ``markdown_text``. |
| 4381 | + """ |
4429 | 4382 | return self._format_converter.from_ast(content) |
4430 | 4383 |
|
4431 | 4384 | # ================================================================== |
@@ -4547,18 +4500,13 @@ async def _send_to_response_url( |
4547 | 4500 | "blocks": card_to_block_kit(card), |
4548 | 4501 | } |
4549 | 4502 | else: |
4550 | | - table_result = self._render_with_table_blocks(message) |
4551 | | - if table_result: |
4552 | | - payload = { |
4553 | | - "replace_original": True, |
4554 | | - "text": table_result["text"], |
4555 | | - "blocks": table_result["blocks"], |
4556 | | - } |
4557 | | - else: |
4558 | | - payload = { |
4559 | | - "replace_original": True, |
4560 | | - "text": convert_emoji_placeholders(self._format_converter.render_postable(message), "slack"), |
4561 | | - } |
| 4503 | + # Slack rejects `markdown_text` on response_url payloads |
| 4504 | + # (`no_text`), so markdown/AST messages are rendered to |
| 4505 | + # Slack's legacy mrkdwn format for this surface. |
| 4506 | + payload = { |
| 4507 | + "replace_original": True, |
| 4508 | + "text": self._format_converter.to_response_url_text(message), |
| 4509 | + } |
4562 | 4510 |
|
4563 | 4511 | if thread_ts: |
4564 | 4512 | payload["thread_ts"] = thread_ts |
|
0 commit comments