Skip to content

Commit 9710692

Browse files
authored
Support unsolicitied direct file uploads (#440)
* Support sending files directly to user via direct message * Cleaning filenames caused files to lose extension * Update Authors, added @BrianGallew
1 parent 40c1102 commit 9710692

3 files changed

Lines changed: 46 additions & 10 deletions

File tree

AUTHORS

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,9 @@ acommasplice, https://github.com/acommasplice
5151
TaunoTinits, https://github.com/TaunoTinits
5252
ostracon, https://github.com/ostracon
5353
mattcl, https://github.com/mattcl
54-
Ahmed Osman, https://github.com/Ashex
54+
Evelyn Osman, https://github.com/Ashex
5555
Boris Peterbarg, https://github.com/reist
5656
unicolet, https://github.com/unicolet
5757
Rob Salmond, https://github.com/rsalmond
58-
Jeremy Logan, https://github.com/fixedd
58+
Jeremy Logan, https://github.com/fixedd
59+
Brian Gallew, https://github.com/BrianGallew

will/backends/io_adapters/slack.py

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ def get_channel_from_name(self, name):
7878
for c in self.channels.values():
7979
if c.name.lower() == name.lower() or c.id.lower() == name.lower():
8080
return c
81+
# We need to check if a user id was passed as a channel
82+
# and get the correct IM channel if it was.
83+
elif name.startswith('U') or name.startswith('W'):
84+
return self.open_direct_message(name)
8185
webclient = self.client._web_client # pylint: disable=protected-access
8286
try:
8387
channel_info = webclient.conversations_info(channel=name)["channel"]
@@ -103,6 +107,11 @@ def get_channel_from_name(self, name):
103107
is_private=True,
104108
)
105109

110+
def get_channel_name_from_id(self, name):
111+
for k, c in self.channels.items():
112+
if c.name.lower() == name.lower() or c.id.lower() == name.lower():
113+
return c.name
114+
106115
def normalize_incoming_event(self, event):
107116
"Makes a Slack event look like all the other events we handle"
108117
event_type = event.get("type")
@@ -141,8 +150,21 @@ def normalize_incoming_event(self, event):
141150
# u'type': u'message', u'bot_id': u'B5HL9ABFE'},
142151
# u'type': u'message', u'hidden': True, u'channel': u'D5HGP0YE7'}
143152
logging.debug("we like that event!")
144-
sender = self.people[event["user"]]
145-
channel = self.get_channel_from_name(event["channel"])
153+
if event_subtype == "bot_message":
154+
sender = Person(
155+
id=event["bot_id"],
156+
mention_handle="<@%s>" % event["bot_id"],
157+
handle=event["username"],
158+
source=event,
159+
name=event["username"],
160+
)
161+
else:
162+
sender = self.people[event["user"]]
163+
try:
164+
channel = self.get_channel_from_name(event["channel"])
165+
except KeyError:
166+
self._update_channels()
167+
channel = self.get_channel_from_name(event["channel"])
146168
is_private_chat = getattr(channel, "is_private", False)
147169
is_direct = getattr(getattr(channel, "source", None), 'is_im', False)
148170
channel = clean_for_pickling(channel)
@@ -169,7 +191,7 @@ def normalize_incoming_event(self, event):
169191
if will_is_mentioned and event["text"][0] == ":":
170192
event["text"] = event["text"][1:]
171193

172-
if event["user"] == self.me.id:
194+
if event.get("user") == self.me.id:
173195
will_said_it = True
174196

175197
m = Message(
@@ -206,10 +228,14 @@ def send_file(self, event):
206228

207229
try:
208230
logging.info('EVENT: %s', str(event))
209-
data = {
231+
data = {}
232+
if hasattr(event, "kwargs"):
233+
data.update(event.kwargs)
234+
235+
data.update({
210236
'filename': event.filename,
211237
'filetype': event.filetype
212-
}
238+
})
213239
self.set_data_channel_and_thread(event, data)
214240
# This is just *silly*
215241
if 'thread_ts' in data:
@@ -303,6 +329,10 @@ def handle_outgoing_event(self, event, retry=5):
303329
@staticmethod
304330
def set_data_channel_and_thread(event, data=None):
305331
"Update data with the channel/thread information from event"
332+
if event.type == "file.upload":
333+
# We already know what to do when it's a file DM
334+
if event.kwargs.get("is_direct") is True:
335+
return
306336
if data is None:
307337
data = dict()
308338
if "channel" in event:
@@ -489,6 +519,13 @@ def send_message(self, event):
489519
"chat.postMessage", data=data
490520
)
491521

522+
def open_direct_message(self, user_id):
523+
"""Opens a DM channel."""
524+
return self.client._web_client.api_call( # pylint: disable=protected-access
525+
"conversations.open",
526+
users=[user_id]
527+
)['channel']['id']
528+
492529
def update_message(self, event):
493530
"Update a Slack message"
494531
if event.content == "" or event.content is None:

will/plugin.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
from will.mixins import NaturalTimeMixin, ScheduleMixin, StorageMixin, SettingsMixin, \
1111
EmailMixin, PubSubMixin
1212

13-
FILENAME_CLEANER = re.compile(r'[^-_0-9a-zA-Z]+')
14-
1513

1614
class WillPlugin(EmailMixin, StorageMixin, NaturalTimeMixin,
1715
ScheduleMixin, SettingsMixin, PubSubMixin):
@@ -114,7 +112,7 @@ def send_file(self, message, content, filename, text=None, filetype='text',
114112
e = Event(
115113
type="file.upload",
116114
file=content,
117-
filename=FILENAME_CLEANER.sub('_', filename),
115+
filename=filename,
118116
filetype=filetype,
119117
source_message=message,
120118
title=text,

0 commit comments

Comments
 (0)