def get_channel_from_name(self, name): "Decodes human-readable name into the Slack channel name" for c in self.channels.values(): if c.name.lower() == name.lower() or c.id.lower() == name.lower(): return c webclient = self.client._web_client # pylint: disable=protected-access try: channel_info = webclient.conversations_info( channel=name)["channel"] except slack_sdk.errors.SlackApiError: logging.warning('Error looking up Slack channel %s', name) return None channel_members = webclient.conversations_members(channel=name) now = time.time() members = { x: self.people[x] for x in channel_members.get("members", list()) if x in self.people } logging.debug("took %0.2f seconds to scan people data", time.time() - now) return Channel( name=channel_info.get("name", name), id=channel_info["id"], members=members, source=name, is_channel=False, is_group=False, is_im=channel_info["is_im"], is_private=True, )
def _update_channels(self, client=None): "Updates our internal list of channels. Kind of expensive." channels = {} if client: for page in client.conversations_list( limit=self.PAGE_LIMIT, exclude_archived=True, types="public_channel,private_channel,mpim,im", ): for channel in page["channels"]: members = {} for m in channel.get("members", list()): if m in self.people: members[m] = self.people[m] channels[channel["id"]] = Channel( id=channel["id"], name=channel.get("name", channel["id"]), source=clean_for_pickling(channel), members=members, ) if len(channels.keys()) == 0: # Server isn't set up yet, and we're likely in a processing thread, if self.load("slack_channel_cache", None): self._channels = self.load("slack_channel_cache", None) else: self._channels = channels self.save("slack_channel_cache", channels)
def _rest_channels_list(self): logging.debug('Getting channel list from Rocket.Chat') # Remember to paginate. ;) count = 50 passes = 0 headers = {'X-Auth-Token': self.token, 'X-User-Id': self.userid} fetched = 0 total = 0 channels = {} while fetched <= total: r = requests.get('{}channels.list'.format(self.rocketchat_api_url), headers=headers) resp_json = r.json() total = resp_json['total'] for channel in resp_json['channels']: members = {} for username in channel['usernames']: userid = self._get_userid_from_username(username) members[userid] = self.people[userid] channels[channel['_id']] = Channel( id=channel['_id'], name=channel['name'], source=clean_for_pickling(channel), members=members) passes += 1 fetched = count * passes self.channels = channels
def channels(self): if not hasattr(self, "_channels"): all_rooms = {} # Grab the first roster page, and populate all_rooms url = ALL_ROOMS_URL % { "server": settings.HIPCHAT_SERVER, "token": settings.HIPCHAT_V2_TOKEN, "start_index": 0, "max_results": 1000 } r = requests.get(url, **settings.REQUESTS_OPTIONS) for room in r.json()['items']: # print(room) all_rooms["%s" % (room['xmpp_jid'], )] = Channel( id=room["id"], name=room["name"], source=clean_for_pickling(room), members={}, ) # Keep going through the next pages until we're out of pages. while 'next' in r.json()['links']: url = "%s&auth_token=%s" % (r.json()['links']['next'], settings.HIPCHAT_V2_TOKEN) r = requests.get(url, **settings.REQUESTS_OPTIONS) for room in r.json()['items']: all_rooms["%s" % (room['xmpp_jid'], )] = Channel( id=room["id"], name=room["name"], source=clean_for_pickling(room), members={}) self._channels = all_rooms return self._channels
def _update_channels(self): channels = {} for c in self.client.server.channels: members = {} for m in c.members: members[m] = self.people[m] channels[c.id] = Channel(id=c.id, name=c.name, source=clean_for_pickling(c), members=members) if len(channels.keys()) == 0: # Server isn't set up yet, and we're likely in a processing thread, if self.load("slack_channel_cache", None): self._channels = self.load("slack_channel_cache", None) else: self._channels = channels self.save("slack_channel_cache", channels)
def normalize_incoming_event(self, event): logging.info('Normalizing incoming Rocket.Chat event') logging.debug('event: {}'.format(self.pp.pformat(event))) if event["type"] == "message": # Were we mentioned? will_is_mentioned = False for mention in event['mentions']: if mention['username'] == self.me.handle: will_is_mentioned = True break # Handle direct messages, which in Rocket.Chat are a rid # made up of both users' _ids. is_private_chat = False if self.me.id in event["rid"]: is_private_chat = True # Create a "Channel" to align with Rocket.Chat DM # paradigm. There might well be a better way of doing # this. See TODO in _rest_channels_list. sender_id = event['u']['_id'] ids = [sender_id, self.me.id] ids.sort() channel_id = '{}{}'.format(*ids) sender = self.people[sender_id] channel_members = {} channel_members[sender_id] = sender channel_members[self.me.id] = self.me channel = Channel(id=channel_id, name=channel_id, source=clean_for_pickling(channel_id), members=channel_members) else: if "rid" in event and event["rid"] in self.channels: channel = clean_for_pickling(self.channels[event["rid"]]) else: # Private channel, unknown members. Just do our best and try to route it. if "rid" in event: channel = Channel(id=event["rid"], name=event["rid"], source=clean_for_pickling( event["rid"]), members={}) logging.debug('channel: {}'.format(channel)) # Set various variables depending on whether @handle was # part of the message. interpolated_handle = "@%s " % self.handle logging.debug( 'interpolated_handle: {}'.format(interpolated_handle)) is_direct = False if is_private_chat or event['msg'].startswith(interpolated_handle): is_direct = True # Strip my handle from the start. NB Won't strip it from # elsewhere in the text, and won't strip other mentions. # This will stop regexes from working, not sure if it's a # feature or a bug. if event['msg'].startswith(interpolated_handle): event['msg'] = event['msg'][len(interpolated_handle):].strip() if interpolated_handle in event['msg']: will_is_mentioned = True # Determine if Will said it. logging.debug('self.people: {}'.format(self.pp.pformat( self.people))) sender = self.people[event['u']['_id']] logging.debug('sender: {}'.format(sender)) if sender['handle'] == self.me.handle: logging.debug('Will said it') will_said_it = True else: logging.debug('Will didnt say it') will_said_it = False m = Message(content=event['msg'], type=event.type, is_direct=is_direct, is_private_chat=is_private_chat, is_group_chat=not is_private_chat, backend=self.internal_name, sender=sender, channel=channel, will_is_mentioned=will_is_mentioned, will_said_it=will_said_it, backend_supports_acl=True, original_incoming_event=clean_for_pickling(event)) return m else: logging.debug( 'Passing, I dont know how to normalize this event of type ', event["type"]) pass