@@ -22,24 +22,11 @@ def connect_slack(args, token):
2222 system .print_error (args , f"Failed to connect to Slack with error: { e .response ['error' ]} " )
2323 return None
2424
25-
26- def check_slack_messages (args , client , patterns , profile_name , channel_types , channel_ids = None , limit_mins = 60 , archived_channels = False ):
25+ def check_slack_messages (args , client , patterns , profile_name , channel_types , read_from , channel_ids = None , limit_mins = 60 , archived_channels = False ):
2726 results = []
2827 try :
2928 team_info = client .team_info ()
3029 workspace_url = team_info ["team" ]["url" ].rstrip ('/' )
31-
32- # Get the Unix timestamp for 'limit_mins' minutes ago
33- current_time = time .time ()
34- oldest_time = current_time - (limit_mins * 60 )
35-
36- # Convert to human-readable time for debugging
37- current_time_readable = datetime .fromtimestamp (current_time ).strftime ('%Y-%m-%d %H:%M:%S' )
38- oldest_time_readable = datetime .fromtimestamp (oldest_time ).strftime ('%Y-%m-%d %H:%M:%S' )
39-
40- system .print_info (args , f"Current Time: { current_time_readable } " )
41- system .print_info (args , f"Fetching messages from the last { limit_mins } minutes (Oldest Time: { oldest_time_readable } , Unix: { int (oldest_time )} )" )
42-
4330 # Helper function to handle rate limits
4431 hawk_args = args
4532 def rate_limit_retry (func , * args , ** kwargs ):
@@ -77,7 +64,6 @@ def rate_limit_retry(func, *args, **kwargs):
7764 exclude_archived = not archived_channels
7865 )
7966 channels .extend (response .get ("channels" , []))
80-
8167 # Update the cursor for the next batch
8268 cursor = response .get ("response_metadata" , {}).get ("next_cursor" )
8369
@@ -106,10 +92,32 @@ def rate_limit_retry(func, *args, **kwargs):
10692 for channel in channels :
10793 channel_name = channel ["name" ]
10894 channel_id = channel ["id" ]
109-
95+ latest_time = int (time .time ())
96+
97+ if read_from == 'last_message' :
98+ system .print_info (args , "Fetching messages from the last message in the channel" )
99+ last_msg = get_last_msg (args , client , channel_id )
100+ if last_msg :
101+ latest_time = float (last_msg ['timestamp' ])
102+ # Add 1 second to the latest time to get latest message along with it
103+ latest_time += 1
104+ elif read_from :
105+ try :
106+ read_from = int (read_from )
107+ latest_time = read_from
108+ # Add 1 second to the latest time to get latest message along with it
109+ latest_time += 1
110+ except ValueError :
111+ system .print_error (args , "Invalid value for read_from in Slack configuration. It should be either 'last_message' or a valid Unix timestamp" )
112+ exit (1 )
113+ else :
114+ latest_time = int (time .time ())
115+ oldest_time = latest_time - (limit_mins * 60 )
110116 # Get messages from the channel within the time range
111117 system .print_info (args , f"Checking messages in channel { channel_name } ({ channel_id } )" )
112- messages = rate_limit_retry (client .conversations_history , channel = channel_id , oldest = oldest_time )["messages" ]
118+ system .print_info (args , f"Fetching messages from { time .strftime ('%Y-%m-%d %H:%M:%S' , time .gmtime (oldest_time ))} to { time .strftime ('%Y-%m-%d %H:%M:%S' , time .gmtime (latest_time ))} " )
119+ messages = rate_limit_retry (client .conversations_history , channel = channel_id , oldest = oldest_time , latest = latest_time )["messages" ]
120+ print (f"Found { len (messages )} messages in channel { channel_name } ({ channel_id } )" )
113121 for message in messages :
114122 user = message .get ("user" , "" )
115123 text = message .get ("text" )
@@ -205,8 +213,6 @@ def rate_limit_retry(func, *args, **kwargs):
205213 return results
206214
207215
208-
209-
210216def download_file (args , client , file_info , folder_path ) -> str :
211217 try :
212218 # Ensure the folder exists
@@ -241,6 +247,44 @@ def download_file(args, client, file_info, folder_path) -> str:
241247 system .print_error (args , f"An unexpected error occurred: { str (e )} " )
242248 return None
243249
250+ def get_last_msg (args , client , channel_id ):
251+ """
252+ Fetches the last message from the specified Slack channel.
253+ Handles rate limits and retries if necessary.
254+ """
255+ try :
256+ def rate_limit_retry (func , * args , ** kwargs ):
257+ while True :
258+ try :
259+ return func (* args , ** kwargs )
260+ except SlackApiError as e :
261+ if e .response ["error" ] == "ratelimited" :
262+ retry_after = int (e .response .headers .get ("Retry-After" , 1 ))
263+ system .print_info (args , f"Rate limited. Retrying after { retry_after } seconds..." )
264+ time .sleep (retry_after )
265+ else :
266+ raise
267+
268+ system .print_info (args , f"Fetching last message from channel { channel_id } " )
269+ response = rate_limit_retry (client .conversations_history , channel = channel_id , limit = 1 )
270+ messages = response .get ("messages" , [])
271+
272+ if messages :
273+ last_message = messages [0 ] # Get the latest message
274+ return {
275+ 'user' : last_message .get ("user" , "Unknown" ),
276+ 'text' : last_message .get ("text" , "" ),
277+ 'timestamp' : last_message .get ("ts" , "" ),
278+ 'message_link' : f"https://slack.com/archives/{ channel_id } /p{ last_message .get ('ts' , '' ).replace ('.' , '' )} " ,
279+ }
280+ else :
281+ system .print_info (args , f"No messages found in channel { channel_id } " )
282+ return None
283+
284+ except SlackApiError as e :
285+ system .print_error (args , f"Failed to fetch last message from channel { channel_id } with error: { e .response ['error' ]} " )
286+ return None
287+
244288
245289def execute (args ):
246290 results = []
@@ -255,6 +299,8 @@ def execute(args):
255299 patterns = system .get_fingerprint_file (args )
256300
257301 for key , config in slack_config .items ():
302+ current_unix_timestamp = int (time .time ())
303+ read_from = config .get ('read_from' , current_unix_timestamp )
258304 token = config .get ('token' )
259305 channel_types = config .get ('channel_types' , "public_channel,private_channel" )
260306 channel_ids = config .get ('channel_ids' , [])
@@ -269,7 +315,7 @@ def execute(args):
269315
270316 client = connect_slack (args , token )
271317 if client :
272- results += check_slack_messages (args , client , patterns , key , channel_types , channel_ids , limit_mins , archived_channels )
318+ results += check_slack_messages (args , client , patterns , key , channel_types , read_from , channel_ids , limit_mins , archived_channels )
273319 else :
274320 system .print_error (args , "No Slack connection details found in connection.yml" )
275321 else :
0 commit comments