Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion tools/send_message_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
# because the API requires a conversation ID. To DM a user you must first call
# conversations.open to obtain a D... ID. Without this gate, Slack IDs fall
# through to channel-name resolution, which only matches by name and fails.
_SLACK_TARGET_RE = re.compile(r"^\s*([CGD][A-Z0-9]{8,})\s*$")
_SLACK_TARGET_RE = re.compile(r"^\s*([CGDU][A-Z0-9]{8,})\s*$")
# Session-derived Slack thread targets use "<conversation_id>:<thread_ts>".
_SLACK_THREAD_TARGET_RE = re.compile(r"^\s*([CGD][A-Z0-9]{8,}):([^\s:]+)\s*$")
_WEIXIN_TARGET_RE = re.compile(r"^\s*((?:wxid|gh|v\d+|wm|wb)_[A-Za-z0-9_-]+|[A-Za-z0-9._-]+@chatroom|filehelper)\s*$")
Expand Down Expand Up @@ -275,6 +275,28 @@ def _handle_send(args):
if duplicate_skip:
return json.dumps(duplicate_skip)

# Slack: resolve user IDs (U...) to DM channel IDs via conversations.open
if platform_name == "slack" and chat_id and chat_id.startswith("U"):
try:
import aiohttp
async def _open_slack_dm(token, user_id):
url = "https://slack.com/api/conversations.open"
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
async with aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=10)) as session:
async with session.post(url, headers=headers, json={"users": [user_id]}) as resp:
data = await resp.json()
if data.get("ok"):
return data["channel"]["id"]
return None
from model_tools import _run_async
dm_channel = _run_async(_open_slack_dm(pconfig.token, chat_id))
if dm_channel:
chat_id = dm_channel
else:
return json.dumps({"error": f"Could not open DM with Slack user {chat_id}. Check bot permissions (im:write)."})
except Exception as e:
return json.dumps({"error": f"Failed to open Slack DM: {e}"})

try:
from model_tools import _run_async
result = _run_async(
Expand Down