Skip to content
Closed
Show file tree
Hide file tree
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
18 changes: 18 additions & 0 deletions slackbot/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,24 @@ def handle(self, message, user=None, channel=None, ts=None, raw=None) -> Optiona
"""
raise NotImplementedError("abstract method")

def process_file(
self, files, message, user=None, channel=None, ts=None, raw=None
) -> Optional[Union[int, tuple[int, int]]]:
"""
Handle file share events. Override this method to process file uploads.

:param files: List of file objects from Slack
:param message: Optional text message accompanying the files
:param user: User ID who uploaded the files
:param channel: Channel where files were uploaded
:param ts: Timestamp of the event
:param raw: Raw event data from Slack

:return: None, self.STOP, self.PROCESSED, or tuple PROCESSED,STOP
"""
# Default implementation falls back to regular message processing
return self.handle(message, user=user, channel=channel, ts=ts, raw=raw)


class NoMatchSlackCommand(Exception):
pass
Expand Down
59 changes: 58 additions & 1 deletion slackbot/management/commands/run_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,61 @@ def handle_message_really(self, **payload):

return processed_at_least_one

def handle_file_share(self, **payload):
"""
Handle file share events (when users upload files)
"""
event = payload.get("event")

channel = event.get("channel")
user = event.get("user")
ts = event.get("event_ts", event.get("ts", ""))

if not channel:
return False

# Don't process bot's own file uploads
if user == self.my_id:
return False

# Get file information
files = event.get("files", [])
message = event.get("text", "")

# Log the file share event
self.stdout.write(f"File share event: User {user} uploaded {len(files)} file(s) in channel {channel}")
if message:
self.stdout.write(f"Message: {message}")

# Process files through processors
processed_at_least_one = False
for p in self.processors:
try:
# Call a new method for file processing if it exists
if hasattr(p, "process_file"):
r = p.process_file(files, message, user=user, channel=channel, ts=ts, raw=event)
if r:
if not isinstance(r, tuple):
r = (r,)
if MessageProcessor.PROCESSED in r:
processed_at_least_one = True
if MessageProcessor.STOP in r:
break
else:
# Fallback to regular message processing for backward compatibility
r = p.process(message, user=user, channel=channel, ts=ts, raw=event)
if r:
if not isinstance(r, tuple):
r = (r,)
if MessageProcessor.PROCESSED in r:
processed_at_least_one = True
if MessageProcessor.STOP in r:
break
except Exception as e:
self.log_exception("Processor failed for file share event: %s %s", files, str(e))

return processed_at_least_one

def set_up(self, **payload):
data = self.web.auth_test()
self.my_id = data.get("user_id")
Expand All @@ -137,8 +192,10 @@ def process(self, client: SocketModeClient, req: SocketModeRequest):

event = req.payload["event"]

if event["type"] == "message" and (event.get("subtype") is None or event.get("subtype") == "file_share") :
if event["type"] == "message" and (event.get("subtype") is None or event.get("subtype") == "file_share"):
return self.handle_message(**req.payload)
elif event["type"] == "message" and event.get("subtype") == "file_share":
return self.handle_file_share(**req.payload)

def process_reaction(self, client: SocketModeClient, req: SocketModeRequest):
if req.type == "events_api":
Expand Down
13 changes: 13 additions & 0 deletions testapp/testapp/slack.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,16 @@ def handle(self, message, user=None, channel=None, ts=None, raw=None):
else:
self.post_message(channel=channel, text=f'Nothing for you to see :no_entry:', thread_ts=ts)
return self.PROCESSED

def process_file(self, files, message, user=None, channel=None, ts=None, raw=None):
"""
Handle file uploads - this will now be called when users upload files!
"""

# You can now process the files here
for file_info in files:
file_name = file_info.get('name', 'Unknown')
file_type = file_info.get('mimetype', 'Unknown')
file_size = file_info.get('size', 0)

return self.PROCESSED