feat(02-05): Slack file_share extraction and channel-aware outbound routing
- Add gateway/channels/slack_media.py with is_file_share_event, media_type_from_mime, build_slack_storage_key, build_attachment_from_slack_file, download_and_store_slack_file - Add _send_response() helper to orchestrator/tasks.py for channel-aware dispatch (Slack -> chat.update, WhatsApp -> send_whatsapp_message) - Add send_whatsapp_message import to orchestrator/tasks.py for WhatsApp outbound - Add boto3>=1.35.0 to gateway dependencies for MinIO S3 client - Add 23 unit tests in test_slack_media.py (TDD)
This commit is contained in:
@@ -44,6 +44,7 @@ import json
|
||||
import logging
|
||||
import uuid
|
||||
|
||||
from gateway.channels.whatsapp import send_whatsapp_message
|
||||
from orchestrator.main import app
|
||||
from shared.models.message import KonstructMessage
|
||||
|
||||
@@ -524,6 +525,68 @@ def _extract_tool_name_from_confirmation(confirmation_message: str) -> str:
|
||||
return "unknown_tool"
|
||||
|
||||
|
||||
async def _send_response(
|
||||
channel: str,
|
||||
text: str,
|
||||
extras: dict,
|
||||
) -> None:
|
||||
"""
|
||||
Channel-aware outbound routing — dispatch a response to the correct channel.
|
||||
|
||||
Checks ``channel`` and routes to:
|
||||
- ``slack``: calls ``_update_slack_placeholder`` to replace the "Thinking..." message
|
||||
- ``whatsapp``: calls ``send_whatsapp_message`` via Meta Cloud API
|
||||
- other channels: logs a warning and returns (no-op for unsupported channels)
|
||||
|
||||
Args:
|
||||
channel: Channel name from KonstructMessage.channel (e.g. "slack", "whatsapp").
|
||||
text: Response text to send.
|
||||
extras: Channel-specific metadata dict.
|
||||
For Slack: ``bot_token``, ``channel_id``, ``placeholder_ts``
|
||||
For WhatsApp: ``phone_number_id``, ``bot_token`` (access_token), ``wa_id``
|
||||
"""
|
||||
if channel == "slack":
|
||||
bot_token: str = extras.get("bot_token", "") or ""
|
||||
channel_id: str = extras.get("channel_id", "") or ""
|
||||
placeholder_ts: str = extras.get("placeholder_ts", "") or ""
|
||||
|
||||
if not channel_id or not placeholder_ts:
|
||||
logger.warning(
|
||||
"_send_response: Slack channel missing channel_id or placeholder_ts in extras"
|
||||
)
|
||||
return
|
||||
|
||||
await _update_slack_placeholder(
|
||||
bot_token=bot_token,
|
||||
channel_id=channel_id,
|
||||
placeholder_ts=placeholder_ts,
|
||||
text=text,
|
||||
)
|
||||
|
||||
elif channel == "whatsapp":
|
||||
phone_number_id: str = extras.get("phone_number_id", "") or ""
|
||||
access_token: str = extras.get("bot_token", "") or ""
|
||||
wa_id: str = extras.get("wa_id", "") or ""
|
||||
|
||||
if not phone_number_id or not wa_id:
|
||||
logger.warning(
|
||||
"_send_response: WhatsApp channel missing phone_number_id or wa_id in extras"
|
||||
)
|
||||
return
|
||||
|
||||
await send_whatsapp_message(
|
||||
phone_number_id=phone_number_id,
|
||||
access_token=access_token,
|
||||
recipient_wa_id=wa_id,
|
||||
text=text,
|
||||
)
|
||||
|
||||
else:
|
||||
logger.warning(
|
||||
"_send_response: unsupported channel=%r — response not delivered", channel
|
||||
)
|
||||
|
||||
|
||||
async def _update_slack_placeholder(
|
||||
bot_token: str,
|
||||
channel_id: str,
|
||||
|
||||
Reference in New Issue
Block a user