Skip to content

Commit

Permalink
Merge pull request #103 from chrisBrookes93/fix-for-pmxbot-making-dm-…
Browse files Browse the repository at this point in the history
…to-users

Fix to allow pmxbot to DM slack users
  • Loading branch information
jaraco committed Nov 11, 2022
2 parents 62f112b + a87dbaa commit 932d5e2
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 16 deletions.
6 changes: 6 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
v1122.14.0
==========

* #103: Reintroduce the feature allowing a username or email to be used
in place of a channel ID, in order for pmxbot to DM users

v1122.13.1
==========

Expand Down
56 changes: 40 additions & 16 deletions pmxbot/slack.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,19 +98,25 @@ def transmit(self, channel, message):
message = self._expand_references(message)

# If this action was generated from a slack message event then we should have
# the channel_id already. For other cases we need to query the Slack API
if getattr(channel, "channel_id", None):
channel_id = channel.channel_id
else:
channel_id = self._get_id_for_channel(channel)

self.slack.web_client.chat_postMessage(
channel=channel_id,
text=message,
thread_ts=getattr(channel, 'thread', None),
as_user=True,
# the channel_id already. For other cases we need to query the Slack API using
# the channel name, or the username or email (for DMs)
channel_id = (
getattr(channel, "channel_id", None)
or self._get_id_for_channel_name(channel)
or self._get_id_for_user_name(channel)
or self._get_id_for_user_email(channel)
)

if channel_id:
self.slack.web_client.chat_postMessage(
channel=channel_id,
text=message,
thread_ts=getattr(channel, 'thread', None),
as_user=True,
)
else:
log.error("Failed to resolve a channel ID for: '{}'".format(channel))

@staticmethod
def search_dicts(key, dicts):
"""
Expand All @@ -130,23 +136,41 @@ def _get_channel_mappings(self):
for convo in iter_cursor(convos)
)

def _get_user_mappings(self):
def _get_user_name_to_id_mappings(self):
users = functools.partial(self.slack.web_client.users_list)
return (
{user['name']: user['id'] for user in user_list['members']}
for user_list in iter_cursor(users)
)

def _get_user_email_to_id_mappings(self):
users = functools.partial(self.slack.web_client.users_list)
return (
{
user['profile']['email']: user['id']
for user in user_list['members']
if user['profile'].get('email')
}
for user_list in iter_cursor(users)
)

@functools.lru_cache()
def _get_id_for_user_name(self, user_name):
return self.search_dicts(user_name, self._get_user_name_to_id_mappings())

@functools.lru_cache()
def _get_id_for_user(self, user_name):
return self.search_dicts(user_name, self._get_user_mappings())
def _get_id_for_user_email(self, user_email):
return self.search_dicts(user_email, self._get_user_email_to_id_mappings())

@functools.lru_cache()
def _get_id_for_channel(self, channel_name):
def _get_id_for_channel_name(self, channel_name):
return self.search_dicts(channel_name.strip('#'), self._get_channel_mappings())

def _expand_references(self, message):
resolvers = {'@': self._get_id_for_user, '#': self._get_id_for_channel}
resolvers = {
'@': self._get_id_for_user_name,
'#': self._get_id_for_channel_name,
}

def _expand(match):
match_type = match.groupdict()['type']
Expand Down

0 comments on commit 932d5e2

Please sign in to comment.