如何基于SocketModeClient创建仅响应@提及消息的Slack机器人?
解决Slack SocketMode机器人仅响应@提及消息的问题
核心优化思路
Slack的app_mention事件本身就是专门为机器人被@提及的场景设计的,触发该事件时就意味着机器人已被明确@,无需额外检查消息文本——不过如果需要严谨验证,得先获取机器人的User ID(格式为UXXXXXXX)。
步骤1:获取机器人的User ID
用auth.test API可以直接拿到当前token对应的机器人User ID,比users_profile_get更精准:
from slack_sdk.web import WebClient import os web_client = WebClient(token=os.environ['TOKEN']) auth_response = web_client.auth_test() BOT_USER_ID = auth_response['user_id'] # 得到类似U12345678的ID
步骤2:修改消息处理逻辑
利用app_mention事件的特性,简化判断逻辑;如果需要额外验证,可检查消息文本中是否包含<@{BOT_USER_ID}>:
from slack_sdk.socket_mode import SocketModeClient from slack_sdk.socket_mode.request import SocketModeRequest from slack_sdk.socket_mode.response import SocketModeResponse import os # 初始化WebClient并获取Bot User ID web_client = WebClient(token=os.environ['TOKEN']) auth_response = web_client.auth_test() BOT_USER_ID = auth_response['user_id'] # 初始化SocketModeClient socket_mode_client = SocketModeClient( app_token=os.environ['APP_TOKEN'], web_client=web_client ) def _process_websocket_message(client: SocketModeClient, request: SocketModeRequest): # 先确认请求,避免Slack重复发送 client.send_socket_mode_response(SocketModeResponse(envelope_id=request.envelope_id)) if request.type != 'events_api': return # 忽略重试请求 if request.retry_attempt and request.retry_attempt > 0: return payload_event = request.payload['event'] # 仅处理app_mention事件(已确保机器人被@) if payload_event['type'] == 'app_mention': # 可选:额外验证消息中确实包含机器人的@标识 mention_tag = f"<@{BOT_USER_ID}>" if mention_tag in payload_event['text']: # 执行你的响应操作,比如回复消息 web_client.chat_postMessage( channel=payload_event['channel'], text=f"收到你的@提及啦!消息内容:{payload_event['text'].replace(mention_tag, '').strip()}" ) # 注册消息处理器 socket_mode_client.socket_mode_request_listeners.append(_process_websocket_message) # 启动客户端 socket_mode_client.start()
关键说明
app_mention事件是Slack官方提供的精准触发机制,只要机器人被@就会触发,无需自己遍历消息文本判断提及。- 用
auth.test获取的user_id是机器人的用户ID,对应@提及在消息文本中的格式<@UXXXXXXX>,和bot_id(格式B开头)不是同一个,这就是你之前找不到对应ID的原因。
内容的提问来源于stack exchange,提问作者Minura Punchihewa
相关产品推荐
相关产品推荐

