def test_team(): _team = Team.get_team_by_name('testteam') _bot = Bot.get_bot_by_name(_team, 'echobot') assert _bot.name == 'echobot' assert _bot.bot_id == 'A12345678' assert _bot.team == _team assert _bot.oauth_user_token == '1234' assert _bot.oauth_bot_token == '1234' assert _bot.verification_token == '1234' _team = Team.get_team_by_id(team_id='TABCDEF12') _bot = Bot.get_bot_by_bot_id(_team, 'A98765432') assert _bot.name == 'echobot' assert _bot.bot_id == 'A98765432' assert _bot.team == _team assert _bot.oauth_user_token == '1234' assert _bot.oauth_bot_token == '' assert _bot.verification_token == '1234' _team = Team.get_team_by_name('testteam') _bot = Bot.get_bot_by_verification_token('5555') assert _bot.name == 'pingbot' assert _bot.bot_id == 'AABCDEF12' assert _bot.team == _team assert _bot.oauth_user_token == '5555' assert _bot.oauth_bot_token == '5555' assert _bot.verification_token == '5555' with pytest.raises(BotInitializationError): _bot = Bot.get_bot_by_name(_team, 'fakebot') with pytest.raises(BotInitializationError): _bot = Bot.get_bot_by_bot_id(_team, 'BADBOTID')
def test_team(): _team = Team.get_team_by_name('testteam') assert _team.name == 'testteam' assert _team.team_id == 'T12345678' _team = Team.get_team_by_id('TABCDEF12') assert _team.name == 'test2ndteam' assert _team.team_id == 'TABCDEF12' with pytest.raises(TeamInitializationError): _team = Team.get_team_by_name('faketeam') with pytest.raises(TeamInitializationError): _team = Team.get_team_by_id(team_id='BADTEAMID')
def watch_channels(): try: redis_client = omniredis.get_redis_client(decode_responses=False) last_run_key = "watch:channels:last_run_datetime" if not _is_allowed_to_run(redis_client, last_run_key): return statsd = stats.get_statsd_client() with redis_lock.Lock(redis_client, 'watch_channels', expire=LOCK_EXPIRATION, auto_renewal=True): with statsd.timer('watch.channels'): for team_name, bot_name in settings.PRIMARY_SLACK_BOT.items(): logger.info( 'Updating slack channel list.', extra={ 'team': team_name, 'bot': bot_name }, ) team = Team.get_team_by_name(team_name) bot = Bot.get_bot_by_name(team, bot_name) slack.update_channels(bot) redis_client.set(last_run_key, datetime.now().isoformat()) except Exception: logger.exception('Failed to update slack channel list.', exc_info=True) finally: return gevent.spawn_later(settings.WATCHER_SPAWN_WAIT_TIME_IN_SEC, watch_channels)
def get_bot_ims(team_name, bot_name): """ Returns list of IMs (DMs with a bot), for the provided `bot_name` and `team_name`. .. :quickref: Get a list of IMs for a bot within a team **Example request**: .. sourcecode:: http GET /api/v1/slack/get_ims/myteam/mybot **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json {"ims": [ { "id": 'D1234567', "created": 1518129625, "is_im": true, "is_org_shared": true, "user": "******" "is_user_deleted": false, "priority": 0.01234567 } ] } :param team_name: The team to search for this user, as configured in omnibot. :type team_name: str :param bot_name: The bot to use for the request, as configured in omnibot. :type bot_name: str """ try: team = Team.get_team_by_name(team_name) except TeamInitializationError: return jsonify({'error': 'provided team name was not found.'}), 404 try: bot = Bot.get_bot_by_name(team, bot_name) except BotInitializationError: return jsonify({'error': 'provided bot name was not found.'}), 404 raw_ims = slack.get_ims(bot) ims = [] for im in raw_ims: # each im is a tuple where im[0] is the channel id and im[1] is the im object ims.append(json.loads(im[1])) return jsonify({'ims': ims})
def get_bot_by_verification_token(cls, verification_token): name = None _bot_data = {} for team_name, bots in settings.SLACK_BOT_TOKENS.items(): for bot_name, bot_data in bots.items(): if verification_token == bot_data['verification_token']: name = bot_name _bot_data = bot_data break if not _bot_data: raise BotInitializationError('Invalid bot') team = Team.get_team_by_name(team_name) return cls(team, name, _bot_data)
def test_interactive_block_component(mocker): _team = Team.get_team_by_name('testteam') _bot = Bot.get_bot_by_name(_team, 'echobot') component = { 'type': 'block_actions', 'response_url': 'https://hooks.slack.com/app/T999999/375455994771/iMW9hNKFI739hGOw9FCXMlf4', # noqa:E501 'actions': [{ 'block_id': 'echobot_action_test', 'action_ts': '1561559117.130541' }] } event_trace = { 'callback_id': 'echobot_action_test', 'app_id': _bot.bot_id, 'team_id': _bot.team.team_id, 'bot_receiver': _bot.name, 'component_type': 'message_action' } _component = InteractiveComponent(_bot, component, event_trace) assert _component.callback_id == 'echobot_action_test'
def decorated(*args, **kwargs): bot_name = request.view_args.get('bot_name') team_name = request.view_args.get('team_name') try: team = Team.get_team_by_name(team_name) except TeamInitializationError: logger.warning('Failed to validate bot', extra={ 'bot': bot_name, 'team': team_name, }) return abort(404) try: Bot.get_bot_by_name(team, bot_name) except BotInitializationError: logger.warning('Failed to validate bot', extra={ 'bot': bot_name, 'team': team_name, }) return abort(404) return f(*args, **kwargs)
def get_team_id_by_name(team_name): """ Get a team_id, from its `team_name`. .. :quickref: Team ID; Get team_id from team_name **Example request**: .. sourcecode:: http GET /api/v1/slack/get_team/myteam HTTP/1.1 **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json {"team_id": "T123456"} :param team_name: The team to search for this user, as configured in omnibot. :type team_name: str :reqheader x-envoy-internal: Header that indicates whether or not this request is coming from an internal service or not. This is auto-set by envoy and doesn't need to be explicitly set. :resheader Content-Type: application/json :statuscode 200: success :statuscode 404: team is not configured """ logger.debug('Getting team id', extra={'team': team_name}) try: team = Team.get_team_by_name(team_name) return jsonify({'team_id': team.team_id}) except TeamInitializationError: return jsonify({'error': 'provided team_name is not configured.'}), 404
def help_callback(container): """ Callback for omnibot help info. """ payload = container.payload logger.debug('Help callback text: {}'.format(payload['text'])) logger.debug('Help callback payload: {}'.format( json.dumps(payload, indent=2))) ret_action = {'action': 'chat.postMessage', 'kwargs': {'attachments': []}} ret = {'actions': [ret_action]} command_fields = [] regex_fields = [] team = Team.get_team_by_name(payload['team']['name']) bot = Bot.get_bot_by_name(team, payload['bot']['name']) for handler in bot.message_handlers: if handler['match_type'] == 'command': command_fields.append({ 'title': handler['match'], 'value': handler.get('description', ''), 'short': False }) if handler['match_type'] == 'regex': regex_fields.append({ 'title': handler['match'], 'value': handler.get('description', ''), 'short': False }) if command_fields: ret_action['kwargs']['attachments'].append({ 'title': 'Commands:', 'fields': command_fields }) if regex_fields: ret_action['kwargs']['attachments'].append({ 'title': 'Regex matches:', 'fields': regex_fields }) return ret
def test_interactive_component(mocker): _team = Team.get_team_by_name('testteam') _bot = Bot.get_bot_by_name(_team, 'echobot') component = { 'type': 'message_action', 'callback_id': 'echobot_action_test', 'action_ts': '1234567.12', 'trigger_id': '376604117319.165116859648.515402022613c2893a80d6268c463e54', # noqa:E501 'response_url': 'https://hooks.slack.com/app/T999999/375455994771/iMW9hNKFI739hGOw9FCXMlf4', # noqa:E501 'user': { 'id': 'A12345678', 'name': 'echobot' }, 'team': { 'id': 'T999999', 'domain': 'omnibot-test-domain' }, 'channel': { 'id': 'C123456AB', 'name': 'channel-channel' }, 'message': { 'type': 'message', 'user': '******', 'text': '<@A12345678> echo I am <!here|here> in <#C123456AB|channel-channel>. See: <http://example.com> :simple_smile:', # noqa:E501 'ts': '1230000.00' } } event_trace = { 'callback_id': 'echobot_action_test', 'app_id': _bot.bot_id, 'team_id': _bot.team.team_id, 'bot_receiver': _bot.name, 'component_type': 'message_action' } get_user_mock = mocker.patch('omnibot.services.slack.get_user') user_ret = {'A12345678': {}} get_user_mock.return_value = user_ret get_channel_mock = mocker.patch('omnibot.services.slack.get_channel') channel_ret = {'C123456AB': {}} get_channel_mock.return_value = channel_ret extract_users_mock = mocker.patch( 'omnibot.services.slack.parser.extract_users') users_ret = {'<@A12345678>': 'echobot'} extract_users_mock.return_value = users_ret replace_users_mock = mocker.patch( 'omnibot.services.slack.parser.replace_users') replace_users_mock.return_value = '@echobot echo I am <!here|here> in <#C123456AB|channel-channel>. See: <http://example.com> :simple_smile:' # noqa:E501 extract_channels_mock = mocker.patch( 'omnibot.services.slack.parser.extract_channels') channels_ret = {'<#C123456AB|channel-channel>': 'channel-channel'} extract_channels_mock.return_value = channels_ret replace_channels_mock = mocker.patch( 'omnibot.services.slack.parser.replace_channels') replace_channels_mock.return_value = '@echobot echo I am <!here|here> in #channel-channel. See: <http://example.com> :simple_smile:' # noqa:E501 extract_subteams_mock = mocker.patch( 'omnibot.services.slack.parser.extract_subteams') extract_subteams_mock.return_value = {} extract_specials_mock = mocker.patch( 'omnibot.services.slack.parser.extract_specials') special_ret = {'<!here|here>': '@here'} extract_specials_mock.return_value = special_ret replace_specials_mock = mocker.patch( 'omnibot.services.slack.parser.replace_specials') replace_specials_mock.return_value = '@echobot echo I am @here in #channel-channel. See: <http://example.com> :simple_smile:' # noqa:E501 extract_emojis_mock = mocker.patch( 'omnibot.services.slack.parser.extract_emojis') emoji_ret = {':simple-smile': 'simple_smile'} extract_emojis_mock.return_value = emoji_ret extract_emails_mock = mocker.patch( 'omnibot.services.slack.parser.extract_emails') extract_emails_mock.return_value = {} replace_emails_mock = mocker.patch( 'omnibot.services.slack.parser.replace_emails') replace_emails_mock.return_value = '@echobot echo I am @here in #channel-channel. See: <http://example.com> :simple_smile:' # noqa:E501 extract_urls_mock = mocker.patch( 'omnibot.services.slack.parser.extract_urls') url_ret = {'<http://example.com>': 'http://example.com'} extract_urls_mock.return_value = url_ret replace_urls_mock = mocker.patch( 'omnibot.services.slack.parser.replace_urls') replace_urls_mock.return_value = '@echobot echo I am @here in #channel-channel. See: http://example.com :simple_smile:' # noqa:E501 extract_mentions_mock = mocker.patch( 'omnibot.services.slack.parser.extract_mentions') extract_mentions_mock.return_value = True extract_command_mock = mocker.patch( 'omnibot.services.slack.parser.extract_command') extract_command_mock.return_value = 'echo I am @here in #channel-channel. See: http://example.com :simple_smile:' # noqa:E501 _component = InteractiveComponent(_bot, component, event_trace) assert _component.event_trace == event_trace assert _component.bot == _bot assert _component.component_type == 'message_action' assert _component.callback_id == 'echobot_action_test' assert _component.action_ts == '1234567.12' assert _component.trigger_id == '376604117319.165116859648.515402022613c2893a80d6268c463e54' # noqa:E501 assert _component.response_url == 'https://hooks.slack.com/app/T999999/375455994771/iMW9hNKFI739hGOw9FCXMlf4' # noqa:E501 assert _component.submission is None assert _component.channel['id'] == 'C123456AB' assert _component.parsed_channel == channel_ret assert _component.user == component['user'] assert _component.team == { 'name': _bot.team.name, 'team_id': _bot.team.team_id } assert _component.message['parsed_user'] == user_ret assert _component.message['users'] == users_ret assert _component.message[ 'parsed_text'] == '@echobot echo I am @here in #channel-channel. See: http://example.com :simple_smile:' # noqa:E501 assert _component.message.get('bot_id') is None assert _component.message['channels'] == channels_ret assert _component.message['specials'] == special_ret assert _component.message['emails'] == {} assert _component.message['urls'] == url_ret
def send_bot_im(team_name, bot_name, email): """ Sends a message as a bot user to an IM (direct message) channel between a team member and a bot user, for the provided `team_name`, `bot_name`, and `email`. .. :quickref: Send an IM message between bot and user **Example request**: .. sourcecode:: http GET /api/v1/slack/send_im/myteam/mybot/[email protected] **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json { "channel": "DC1234567", "message": { "bot_id": "BC1234567", "subtype": "bot_message", "text": "HI!", "ts": "1538593287.000100", "type": "message", "username": "******" }, "ok": true, "ts": "1538593287.000100" } :param team_name: The team to search for the given bot, as configured in omnibot. :type team_name: str :param bot_name: The bot sending the IM to the user, as configured in omnibot. :type bot_name: str :param email: The email address of user to send message to :type email: str :resheader Content-Type: application/json :statuscode 200: success :statuscode 400: slack call returned a non-OK status :statuscode 404: team, bot, IM unable to be found, or user deleted from slack team """ data = request.json try: team = Team.get_team_by_name(team_name) bot = Bot.get_bot_by_name(team, bot_name) except TeamInitializationError: return jsonify({ 'error': 'provided team name was not found.', 'team_name': team_name, 'bot_name': bot_name, 'email': email }), 404 except BotInitializationError: return jsonify({ 'error': 'provided bot name was not found.', 'team_name': team_name, 'bot_name': bot_name, 'email': email }), 404 user = slack.get_user_by_email(bot, email) if not user: return jsonify({ 'error': 'unable to find slack user for given email.', 'team_name': team_name, 'bot_name': bot_name, 'email': email }), 404 im_id = slack.get_im_channel_id(bot, user['id']) if im_id is None: return jsonify({ 'error': 'unable to find IM channel.', 'team_name': team_name, 'bot_name': bot_name, 'email': email }), 404 data['kwargs']['channel'] = im_id ret = _perform_action(bot, data) if ret['ok']: return jsonify(ret), 200 else: return jsonify(ret), 400
def slack_action_v2(team_name, bot_name): """ Perform an action against slack, as the provided `bot_name` in the provided `team_name`. .. :quickref: SlackAction; Perform a slack action in a specified team as a specified bot. **Example request**: .. sourcecode:: http POST /api/v1/slack/action/myteam/mybot HTTP/1.1 Content-Type: application/json { "action": "chat.postMessage", "kwargs": { "channel": "test-omnibot", "text": "@example see #general and use @here", "as_user": true, "omnibot_parse": { "text": ["channels", "users", "specials"] } } } :<json string action: slack api action to perform. example: `chat.postMessage` :<json dict kwargs: keyword arguments you'd pass into the associated slack api action. example: `"text": "@example see #general and use @here"` :<json dict omnibot_parse: The keyword argument you'd like omnibot to parse, with a list of things to parse. example: {"text": ["channels", "users", "specials"]} **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json { "channel": "C12345", "message": { "bot_id": "B456123", "subtype": "bot_message", "text": "<@UABC123|example> see <#C12345|general> and use <!here|here>", "ts": "1523557397.000335", "type": "message", "username": "******" }, "ok": true, "ts": "1523557397.000335" } :param team_name: The team to perform this action against, as configured in omnibot. :type team_name: str :param bot_name: The bot to use for the request, as configured in omnibot. :type bot_name: str :reqheader x-envoy-internal: Header that indicates whether or not this request is coming from an internal service or not. This is auto-set by envoy and doesn't need to be explicitly set. :resheader Content-Type: application/json :statuscode 200: success :statuscode 400: slack call returned a non-OK status """ data = request.json try: team = Team.get_team_by_name(team_name) except TeamInitializationError: return jsonify({'error': 'provided team name was not found.'}), 404 try: bot = Bot.get_bot_by_name(team, bot_name) except BotInitializationError: return jsonify({'error': 'provided bot name was not found.'}), 404 ret = _perform_action(bot, data) if ret['ok']: return jsonify(ret), 200 else: return jsonify(ret), 400
def get_channel_by_name(team_name, bot_name, channel_name): """ Returns a channel object from slack, for the provided `channel_name` in the `team_name` using the specified `bot_name`. .. :quickref: Channel; Get a channel from a team, via the channel_name **Example request**: .. sourcecode:: http GET /api/v1/slack/get_channel/myteam/mybot/general HTTP/1.1 **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json { "channel": { "id": "C4VQ6NUNN", "name": "general", "is_channel": true, "created": 1491515285, "creator": "U4WF56QGP", "is_archived": false, "is_general": true, "unlinked": 0, "name_normalized": "general", "is_shared": false, "is_org_shared": false, "is_member": false, "is_private": false, "is_mpim": false, "members": [ "U4WF56QGP", "U6HQQ19EC", "U6J3LTKSQ", "U6J4EGP44", "U6JDF1JBU", "U6JEGTFDZ", "U6JERPMJ7", "U6JG691MJ", "U6JGEQ0J0", "U6SAVUK44", "U750C7B37", "U7DH0H802" ], "topic": { "value": "test123", "creator": "U6J3LTKSQ", "last_set": 1507156612 }, "purpose": { "value": "This channel is for team-wide communication.", "creator": "", "last_set": 0 }, "previous_names": [], "num_members": 9 } } :param team_name: The team to search for this channel, as configured in omnibot. :type team_name: str :param bot_name: The bot to use for the request, as configured in omnibot. :type bot_name: str :param channel_name: The name of the channel to get. :type channel_name: str :reqheader x-envoy-internal: Header that indicates whether or not this request is coming from an internal service or not. This is auto-set by envoy and doesn't need to be explicitly set. :resheader Content-Type: application/json :statuscode 200: success :statuscode 404: channel with specified channel_name could not be found in the specified team using the specified bot. """ logger.debug( 'Getting channel for team={} bot={} channel={}.', extra={ 'team': team_name, 'bot': bot_name, 'channel': channel_name, }, ) try: team = Team.get_team_by_name(team_name) except TeamInitializationError: return jsonify({'error': 'provided team name was not found.'}), 404 try: bot = Bot.get_bot_by_name(team, bot_name) except BotInitializationError: return jsonify({'error': 'provided bot name was not found.'}), 404 channel = slack.get_channel_by_name(bot, channel_name) if channel is None: logger.debug( 'Failed to get channel', extra=merge_logging_context( {'channel': channel_name}, bot.logging_context, ), ) return jsonify({'error': 'provided channel_name was not found.'}), 404 return jsonify(channel)
def get_user_v2(team_name, bot_name, email): """ Returns basic user information, for the provided `email` in the `team_name` using the specified `bot_name`. .. :quickref: User; Get a user from a team, via their email **Example request**: .. sourcecode:: http GET /api/v1/slack/get_user/myteam/mybot/[email protected] HTTP/1.1 **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json {"email": "*****@*****.**", "name": "Test User", "team_id": "T123456", "user_id": "U123ABC"} :param team_name: The team to search for this user, as configured in omnibot. :type team_name: str :param bot_name: The bot to use for the request, as configured in omnibot. :type bot_name: str :param email: The email address of the user to get. :type email: str :reqheader x-envoy-internal: Header that indicates whether or not this request is coming from an internal service or not. This is auto-set by envoy and doesn't need to be explicitly set. :resheader Content-Type: application/json :statuscode 200: success :statuscode 404: user with specified email could not be found using the specified bot. """ logger.debug('Getting user team={} bot={} email={}.', extra={ 'team': team_name, 'bot': bot_name, 'email': email, }) try: team = Team.get_team_by_name(team_name) except TeamInitializationError: return jsonify({'error': 'provided team name was not found.'}), 404 try: bot = Bot.get_bot_by_name(team, bot_name) except BotInitializationError: return jsonify({'error': 'provided bot name was not found.'}), 404 user = slack.get_user_by_email(bot, email) if not user: return jsonify({'error': 'user not found'}, ), 404 name = slack.get_name_from_user(user) return jsonify({ 'user': { 'email': email, 'name': name, 'team_id': team.team_id, 'user_id': user['id'] } })
def test_message(mocker): _team = Team.get_team_by_name('testteam') _bot = Bot.get_bot_by_name(_team, 'echobot') event = { 'ts': '1234567.12', 'thread_ts': None, 'user': '******', 'text': '<@A12345678> echo I am <!here|here> in <#C123456AB|channel-channel>. See: <http://example.com> :simple_smile:', # noqa:E501 'channel': 'C123456AB', } event_trace = { 'event_ts': '1234567.12', 'event_type': 'message', 'app_id': _bot.bot_id, 'team_id': _bot.team.team_id, 'bot_receiver': _bot.name } get_user_mock = mocker.patch('omnibot.services.slack.get_user') user_ret = {'A12345678': {}} get_user_mock.return_value = user_ret get_channel_mock = mocker.patch('omnibot.services.slack.get_channel') channel_ret = {'C123456AB': {}} get_channel_mock.return_value = channel_ret extract_users_mock = mocker.patch( 'omnibot.services.slack.parser.extract_users') user_ret = {'<@A12345678>': 'echobot'} extract_users_mock.return_value = user_ret replace_users_mock = mocker.patch( 'omnibot.services.slack.parser.replace_users') replace_users_mock.return_value = '@echobot echo I am <!here|here> in <#C123456AB|channel-channel>. See: <http://example.com> :simple_smile:' # noqa:E501 extract_channels_mock = mocker.patch( 'omnibot.services.slack.parser.extract_channels') channels_ret = {'<#C123456AB|channel-channel>': 'channel-channel'} extract_channels_mock.return_value = channels_ret replace_channels_mock = mocker.patch( 'omnibot.services.slack.parser.replace_channels') replace_channels_mock.return_value = '@echobot echo I am <!here|here> in #channel-channel. See: <http://example.com> :simple_smile:' # noqa:E501 extract_subteams_mock = mocker.patch( 'omnibot.services.slack.parser.extract_subteams') extract_subteams_mock.return_value = {} extract_specials_mock = mocker.patch( 'omnibot.services.slack.parser.extract_specials') special_ret = {'<!here|here>': '@here'} extract_specials_mock.return_value = special_ret replace_specials_mock = mocker.patch( 'omnibot.services.slack.parser.replace_specials') replace_specials_mock.return_value = '@echobot echo I am @here in #channel-channel. See: <http://example.com> :simple_smile:' # noqa:E501 extract_emojis_mock = mocker.patch( 'omnibot.services.slack.parser.extract_emojis') emoji_ret = {':simple-smile': 'simple_smile'} extract_emojis_mock.return_value = emoji_ret extract_emails_mock = mocker.patch( 'omnibot.services.slack.parser.extract_emails') extract_emails_mock.return_value = {} replace_emails_mock = mocker.patch( 'omnibot.services.slack.parser.replace_emails') replace_emails_mock.return_value = '@echobot echo I am @here in #channel-channel. See: <http://example.com> :simple_smile:' # noqa:E501 extract_urls_mock = mocker.patch( 'omnibot.services.slack.parser.extract_urls') url_ret = {'<http://example.com>': 'http://example.com'} extract_urls_mock.return_value = url_ret replace_urls_mock = mocker.patch( 'omnibot.services.slack.parser.replace_urls') replace_urls_mock.return_value = '@echobot echo I am @here in #channel-channel. See: http://example.com :simple_smile:' # noqa:E501 extract_mentions_mock = mocker.patch( 'omnibot.services.slack.parser.extract_mentions') extract_mentions_mock.return_value = True extract_command_mock = mocker.patch( 'omnibot.services.slack.parser.extract_command') extract_command_mock.return_value = 'echo I am @here in #channel-channel. See: http://example.com :simple_smile:' # noqa:E501 _message = Message(_bot, event, event_trace) assert _message.event == event assert _message.event_trace == event_trace assert _message.bot == _bot assert _message.subtype is None assert _message.text == event['text'] assert _message.parsed_text == '@echobot echo I am @here in #channel-channel. See: http://example.com :simple_smile:' # noqa:E501 assert _message.command_text == 'echo I am @here in #channel-channel. See: http://example.com :simple_smile:' # noqa:E501 assert _message.directed is True assert _message.mentioned is True assert _message.channel_id == 'C123456AB' assert _message.channel == channel_ret assert _message.user == event['user'] assert _message.ts == event['ts'] assert _message.thread_ts == event['thread_ts'] assert _message.team == { 'name': _bot.team.name, 'team_id': _bot.team.team_id } assert _message.bot_id is None assert _message.channels == channels_ret assert _message.users == user_ret assert _message.specials == special_ret assert _message.emails == {} assert _message.urls == url_ret assert _message.match_type is None assert _message.match is None assert _message.event_trace == event_trace _message.set_match('command', 'echo') assert _message.match_type == 'command' assert _message.match == 'echo' assert _message.payload['command'] == 'echo' assert _message.payload[ 'args'] == 'I am @here in #channel-channel. See: http://example.com :simple_smile:' # noqa:E501 _message.set_match('regex', None) assert _message.match_type == 'regex' event_copy = copy.deepcopy(event) event_copy['bot_id'] = 'A12345678' with pytest.raises(MessageUnsupportedError): _message = Message(_bot, event_copy, event_trace) event_copy = copy.deepcopy(event) event_copy['thread_ts'] = '1234568.00' with pytest.raises(MessageUnsupportedError): _message = Message(_bot, event_copy, event_trace) event_copy = copy.deepcopy(event) event_copy['subtype'] = 'some_subtype' with pytest.raises(MessageUnsupportedError): _message = Message(_bot, event_copy, event_trace)