Example #1
0
def handle_reaction_event(event: ReactionAdded):
    user = slack_api_client.get_user(event.user)
    channel = slack_api_client.get_channel(event.item.channel)
    item_user = slack_api_client.get_user(event.item_user)
    added = event.type == 'reaction_added'

    message_text = None
    if not channel.is_private:
        message = slack_api_client.get_message(channel, event.item.ts)
        if message is not None:
            if len(message.text) > 0:
                message_text = sanitize_message_text(message.text)
            elif message.files is not None and len(message.files) > 0:
                message_text = message.files[0].permalink

    else:
        logger.debug(
            'Did not query api for message, because we are in a private channel'
        )

    frisky.handle_reaction(ReactionEvent(
        emoji=event.reaction,
        username=user.get_short_name(),
        added=added,
        message=MessageEvent(
            username=item_user.get_short_name(),
            channel_name=channel.name,
            text=message_text,
        ),
    ),
                           reply_channel=lambda reply: slack_api_client.
                           post_message(channel, reply))
Example #2
0
 def test_unhandled_reaction_returns_none(self):
     message_event = MessageEvent(
         username='******',
         channel_name='general',
         text='?hello world'
     )
     reaction_event = ReactionEvent(
         emoji='bacon',
         username='******',
         added=True,
         message=message_event
     )
     response = self.plugin.handle_reaction(reaction_event)
     self.assertIsNone(response)
Example #3
0
    def test_handle_reaction(self):
        expected = ReactionEvent(
            emoji='poop',
            username='******',
            added=True,
            message=MessageEvent(
                username='******',
                channel_name='general',
                text=
                'I find you punny and would like to smell your nose letter',
            ))
        result = None

        def mock_handle_reaction(_, reaction: ReactionEvent,
                                 reply_channel: Callable[[str], bool]):
            nonlocal result
            result = reaction

        patcher = mock.patch(target='frisky.bot.Frisky.handle_reaction',
                             new=mock_handle_reaction)

        with responses.RequestsMock() as rm:
            rm.add('GET', f'{URL}/users.info?user=W012A3CDE', body=USER_OK)
            rm.add('GET',
                   f'{URL}/conversations.info?channel=123',
                   body=conversation)
            api = f'{URL}/conversations.history?channel=C012AB3CD&oldest=123&latest=123&inclusive=true&limit=1'
            rm.add('GET', api, body=message)
            try:
                patcher.start()
                handle_reaction_event(event=ReactionAdded(
                    type='reaction_added',
                    user='******',
                    item=ReactionItem(type='message', channel='123', ts='123'),
                    reaction='poop',
                    item_user='******',
                    event_ts='123'))
                self.assertEqual(expected, result)
            finally:
                patcher.stop()
Example #4
0
    def send_reaction(self,
                      reaction,
                      from_user,
                      to_user,
                      reacted_message='yolo',
                      channel='testing',
                      reaction_removed=False):
        result = None
        event = ReactionEvent(emoji=reaction,
                              username=from_user,
                              added=not reaction_removed,
                              message=MessageEvent(
                                  username=to_user,
                                  channel_name=channel,
                                  text=reacted_message,
                              ))

        def callback(response: str) -> bool:
            nonlocal result
            result = response
            return True

        self.frisky.handle_reaction(event, callback)
        return result
Example #5
0
def process_event(data):
    slack_api_client = SlackApiClient(settings.SLACK_ACCESS_TOKEN)
    # noinspection PyBroadException
    try:
        if data['event'].get('subtype') in SUBTYPE_BLACKLIST:
            logger.debug(f'Ignoring {data["event"]["event_id"]}, subtype was in blacklist')
            return
        event_wrapper: Event = Event.from_dict(data)
        event = event_wrapper.get_event()
        # team = slack_api_client.get_workspace(data['team_id'])
        frisky = Frisky(
            name=settings.FRISKY_NAME,
            prefix=settings.FRISKY_PREFIX,
            ignored_channels=settings.FRISKY_IGNORED_CHANNELS,
        )

        if isinstance(event, ReactionAdded):
            user = slack_api_client.get_user(event.user)
            channel = slack_api_client.get_channel(event.item.channel)
            item_user = slack_api_client.get_user(event.item_user)
            added = event.type == 'reaction_added'
            message = slack_api_client.get_message(channel, event.item.ts)

            frisky.handle_reaction(
                ReactionEvent(
                    emoji=event.reaction,
                    username=user.get_short_name(),
                    added=added,
                    message=MessageEvent(
                        username=item_user.get_short_name(),
                        channel_name=channel.name,
                        text=message.text,
                        command='',
                        args=tuple(),
                    ),
                ),
                reply_channel=lambda reply: slack_api_client.post_message(channel, reply)
            )
        elif isinstance(event, MessageSent):
            user = slack_api_client.get_user(event.user)
            if event.channel_type == 'im':
                # TODO: Is there an api method (or a reason) to look this up?
                channel = Conversation(id=event.channel, name=user.name)
            elif event.channel_type == 'channel':
                channel = slack_api_client.get_channel(event.channel)
            else:
                return
            frisky.handle_message(
                MessageEvent(
                    username=user.get_short_name(),
                    channel_name=channel.name,
                    text=event.text,
                    command='',
                    args=tuple(),
                ),
                reply_channel=lambda res: reply(slack_api_client, channel, res)
            )
    except KeyError as err:
        stacktrace = traceback.format_exc()
        slack_api_client.emergency_log(stacktrace)
        slack_api_client.emergency_log(f'Trouble deserializing this event:\n{str(data)}')
        logger.warning('KeyError thrown deserializing event', exc_info=err)
    except Exception as err:
        stacktrace = traceback.format_exc()
        log_message = f'{stacktrace}\nCaused by:\n{str(data)}'
        slack_api_client.emergency_log(log_message)
        logger.warning('General exception thrown handling event', exc_info=err)