1- """Slack message event template ."""
1+ """Slack message event handler for OWASP NestBot ."""
22
33import logging
44from datetime import timedelta
55
66import django_rq
77
88from apps .ai .common .constants import QUEUE_RESPONSE_TIME_MINUTES
9+ from apps .slack .common .handlers .ai import get_dm_blocks
910from apps .slack .common .question_detector import QuestionDetector
1011from apps .slack .events .event import EventBase
11- from apps .slack .models import Conversation , Member , Message
12+ from apps .slack .models import Conversation , Member , Message , Workspace
1213from apps .slack .services .message_auto_reply import generate_ai_reply_if_unanswered
1314
1415logger = logging .getLogger (__name__ )
1516
1617
1718class MessagePosted (EventBase ):
18- """Handles new messages posted in channels."""
19+ """Handles new messages posted in channels or direct messages ."""
1920
2021 event_type = "message"
2122
@@ -24,25 +25,30 @@ def __init__(self):
2425 self .question_detector = QuestionDetector ()
2526
2627 def handle_event (self , event , client ):
27- """Handle an incoming message event ."""
28+ """Handle incoming Slack message events ."""
2829 if event .get ("subtype" ) or event .get ("bot_id" ):
29- logger .info ("Ignored message due to subtype, bot_id, or thread_ts." )
30+ logger .info ("Ignored message due to subtype or bot_id." )
31+ return
32+
33+ channel_id = event .get ("channel" )
34+ user_id = event .get ("user" )
35+ text = event .get ("text" , "" )
36+ channel_type = event .get ("channel_type" )
37+
38+ if channel_type == "im" :
39+ self .handle_dm (event , client , channel_id , user_id , text )
3040 return
3141
3242 if event .get ("thread_ts" ):
3343 try :
3444 Message .objects .filter (
3545 slack_message_id = event .get ("thread_ts" ),
36- conversation__slack_channel_id = event . get ( "channel" ) ,
46+ conversation__slack_channel_id = channel_id ,
3747 ).update (has_replies = True )
3848 except Message .DoesNotExist :
3949 logger .warning ("Thread message not found." )
4050 return
4151
42- channel_id = event .get ("channel" )
43- user_id = event .get ("user" )
44- text = event .get ("text" , "" )
45-
4652 try :
4753 conversation = Conversation .objects .get (
4854 slack_channel_id = channel_id ,
@@ -71,3 +77,50 @@ def handle_event(self, event, client):
7177 generate_ai_reply_if_unanswered ,
7278 message .id ,
7379 )
80+
81+ def handle_dm (self , event , client , channel_id , user_id , text ):
82+ """Handle direct messages with NestBot (DMs)."""
83+ workspace_id = event .get ("team" )
84+
85+ if not workspace_id :
86+ try :
87+ channel_info = client .conversations_info (channel = channel_id )
88+ workspace_id = channel_info ["channel" ]["team" ]
89+ except Exception :
90+ logger .exception ("Failed to fetch workspace ID for DM." )
91+ return
92+
93+ try :
94+ Member .objects .get (slack_user_id = user_id , workspace__slack_workspace_id = workspace_id )
95+ except Member .DoesNotExist :
96+ try :
97+ user_info = client .users_info (user = user_id )
98+ workspace = Workspace .objects .get (slack_workspace_id = workspace_id )
99+ Member .update_data (user_info ["user" ], workspace , save = True )
100+ logger .info ("Created new member for DM" )
101+ except Exception :
102+ logger .exception ("Failed to create member for DM." )
103+ return
104+
105+ thread_ts = event .get ("thread_ts" )
106+
107+ try :
108+ response_blocks = get_dm_blocks (text , user_id , workspace_id )
109+ if response_blocks :
110+ client .chat_postMessage (
111+ channel = channel_id ,
112+ blocks = response_blocks ,
113+ text = text ,
114+ thread_ts = thread_ts ,
115+ )
116+
117+ except Exception :
118+ logger .exception ("Error processing DM" )
119+ client .chat_postMessage (
120+ channel = channel_id ,
121+ text = (
122+ "I'm sorry, I'm having trouble processing your message right now. "
123+ "Please try again later."
124+ ),
125+ thread_ts = thread_ts ,
126+ )
0 commit comments