예제 #1
0
def open_channel(
    megatron_user_id: int, serialized_request_data: dict, arguments: dict
) -> dict:
    request_data = RequestData(**serialized_request_data)
    megatron_user = MegatronUser.objects.get(id=megatron_user_id)
    platform_user_id = arguments["targeted_platform_id"]
    integration = megatron_user.megatronintegration_set.first()
    connection = IntegrationService(integration).get_connection(as_user=False)

    # Ensure platform user exists
    if not PlatformUser.objects.filter(platform_id=platform_user_id).exists():
        user_info = connection._get_user_info(platform_user_id)
        try:
            workspace = CustomerWorkspace.objects.get(platform_id=user_info["user"]["team_id"])
        except (CustomerWorkspace.DoesNotExist, KeyError):
            return {"ok": False, "error": "Customer Workspace not found"}
        WorkspaceService(workspace).get_or_create_user_by_id(platform_user_id)

    new_msg = formatting.user_titled(platform_user_id, "Connecting...")
    response = connection.respond_to_url(request_data.response_url, new_msg)
    if not response.get("ok"):
        return response
    _update_channel_link.delay(
        megatron_user.id, platform_user_id, request_data.response_url
    )
    return {"ok": True}
예제 #2
0
def clear_context(
    megatron_user_id: int, serialized_request_data: dict, arguments: dict
) -> dict:
    request_data = RequestData(**serialized_request_data)
    megatron_user = MegatronUser.objects.get(id=megatron_user_id)
    platform_user_id = User.objects.get(id=arguments["platform_user_id"])
    command_url = getattr(megatron_user, "command_url", None)
    if not command_url:
        return {"ok": False, "error": "MegatronUser has not provided a command url."}
    # TODO: Use the command that called this to standardize the 'command' param
    response = requests.post(
        megatron_user.command_url,
        json={
            "command": "clear-context",
            "platform_user_id": platform_user_id,
            "megatron_verification_token": megatron_user.verification_token,
        },
    )
    if not response.status_code == 200:
        return {"ok": False, "error": response.content}

    # TODO: This is probably better suited to being part of the integration itself
    integration = megatron_user.megatronintegration_set.first()
    integration_connection = IntegrationService(integration).get_connection(
        as_user=False
    )
    platform_username = PlatformUser.objects.get(platform_id=platform_user_id).username
    msg = {"text": f"Context cleared for *{platform_username}*."}
    integration_response = integration_connection.ephemeral_message(request_data, msg)

    if not integration_response.get("ok"):
        return {"ok": False, "error": "Failed to post confirmation to slack."}

    return {"ok": True}
예제 #3
0
def do(megatron_user_id: int, serialized_request_data: dict, arguments: dict) -> dict:
    request_data = RequestData(**serialized_request_data)
    megatron_user = MegatronUser.objects.get(id=megatron_user_id)
    try:
        channel = MegatronChannel.objects.get(
            platform_channel_id=request_data.channel_id
        )
    except MegatronChannel.DoesNotExist:
        return {"ok": False, "error": "Channel is invalid."}
    workspace = channel.workspace
    connection = WorkspaceService(workspace).get_connection(as_user=False)
    response = connection.open_im(channel.platform_user_id)
    channel_id = response["channel"]["id"]
    msg = {
        "megatron_verification_token": settings.MEGATRON_VERIFICATION_TOKEN,
        "command": "push_message",
        "message": {"text": arguments["arguments"]},
        "channel_id": channel_id,
        "platform_user_id": channel.platform_user_id,
        "platform_channel_id": request_data.channel_id,
    }
    try:
        requests.post(megatron_user.command_url, json=msg, timeout=10)
    except requests.Timeout:
        LOGGER.error("Timeout on megatron do.")
    return {"ok": True}
예제 #4
0
def do(megatron_user_id: int, serialized_request_data: dict,
       arguments: dict) -> dict:
    request_data = RequestData(**serialized_request_data)
    megatron_user = MegatronUser.objects.get(id=megatron_user_id)
    try:
        channel = MegatronChannel.objects.get(
            platform_channel_id=request_data.channel_id)
    except MegatronChannel.DoesNotExist:
        return {'ok': False, 'error': 'Channel is invalid.'}
    workspace = channel.workspace
    connection = WorkspaceService(workspace).get_connection(
        as_user=False)
    response = connection.open_im(channel.platform_user_id)
    channel_id = response['channel']['id']
    msg = {
        'megatron_verification_token': settings.MEGATRON_VERIFICATION_TOKEN,
        'command': 'push_message',
        'message': {'text': arguments['arguments']},
        'channel_id': channel_id,
        'platform_user_id': channel.platform_user_id,
        'platform_channel_id': request_data.channel_id
    }
    try:
        requests.post(megatron_user.command_url, json=msg, timeout=10)
    except requests.Timeout:
        LOGGER.error("Timeout on megatron do.")
    return {'ok': True}
예제 #5
0
def slash_command(request):
    data = request.POST
    response_channel = data['channel_id']
    response_user = data['user_id']
    # Slash command response urls are associated with a "channel" rather than
    # a message. Responding to this url will generate new posts in a channel
    response_url = data['response_url']
    request_data = RequestData(channel_id=response_channel,
                               user_id=response_user,
                               response_url=response_url)

    # TODO: There is only ever one megatron user, remove it
    megatron_user = MegatronUser.objects.first()

    args = data['text'].split(' ')
    command_str = args[0]
    command = Command.get_command(command_str)
    if not command:
        return JsonResponse({'text': "I don't recognize that command."})

    try:
        arguments = command.parse(args[1:], command, response_channel)
    except MegatronException as e:
        return JsonResponse(e.platform_message)
    command.action.delay(megatron_user.id, request_data, arguments)

    return HttpResponse(b'')
예제 #6
0
def pause_channel(megatron_user_id: int, serialized_request_data: dict,
                  arguments: dict) -> dict:
    request_data = RequestData(**serialized_request_data)
    megatron_user = MegatronUser.objects.get(id=megatron_user_id)
    platform_user = PlatformUser.objects.get(platform_id=arguments['targeted_platform_id'])
    response = _change_pause_state(
        megatron_user, platform_user, request_data, True)
    return response
예제 #7
0
def open_channel(megatron_user_id: int, serialized_request_data: dict, arguments: dict) -> dict:
    request_data = RequestData(**serialized_request_data)
    megatron_user = MegatronUser.objects.get(id=megatron_user_id)
    platform_user_id = arguments['targeted_platform_id']
    integration = megatron_user.megatronintegration_set.first()
    connection = IntegrationService(integration).get_connection(as_user=False)
    new_msg = formatting.user_titled(platform_user_id, "Connecting....")
    response = connection.respond_to_url(request_data.response_url, new_msg)
    if not response.get('ok'):
        return response
    _update_channel_link.delay(megatron_user.id, platform_user_id,
                               request_data.response_url)
    return {'ok': True}
예제 #8
0
def close_channel(megatron_user_id: int, serialized_request_data: dict,
                  arguments: dict) -> dict:
    request_data = RequestData(**serialized_request_data)
    megatron_user = MegatronUser.objects.get(id=megatron_user_id)
    targeted_slack_id = arguments['targeted_platform_id']
    try:
        megatron_channel = MegatronChannel.objects.get(
            platform_user_id=targeted_slack_id)
    except MegatronChannel.DoesNotExist:
        return {'ok': False, 'error': 'Channel not found'}

    response = _unpause_channel(megatron_user.id, request_data, arguments)
    if not response.get('ok'):
        return response

    response = MegatronChannelService(megatron_channel).archive()
    if not response.get('ok'):
        return response
    return {'ok': True}
예제 #9
0
def notify_user(request) -> MegatronResponse:
    msg = request.data['message']
    user_id = request.data['user_id']
    channel_id = request.data['channel_id']
    platform_type = request.data['platform_type']
    request_data = RequestData(channel_id=channel_id,
                               user_id=user_id,
                               response_url="")
    platform_type = PlatformType[platform_type.capitalize()].value
    megatron_channel = MegatronChannel.objects.get(
        platform_channel_id=channel_id, workspace__platform_type=platform_type)
    connection = IntegrationService(
        megatron_channel.megatron_integration).get_connection(as_user=False)
    response = connection.ephemeral_message(request_data, msg)
    if response.get('ok'):
        return MegatronResponse({'ok': True, 'track': True}, 200)
    return MegatronResponse({
        'error': response.get('error'),
        'track': False
    }, 500)
예제 #10
0
파일: api.py 프로젝트: ryptozee/megatron
def notify_user(request) -> MegatronResponse:
    msg = request.data["message"]
    user_id = request.data["user_id"]
    channel_id = request.data["channel_id"]
    platform_type = request.data["platform_type"]
    request_data = RequestData(channel_id=channel_id,
                               user_id=user_id,
                               response_url="")
    platform_type = PlatformType[platform_type.capitalize()].value
    megatron_channel = MegatronChannel.objects.get(
        platform_channel_id=channel_id, workspace__platform_type=platform_type)
    connection = IntegrationService(
        megatron_channel.megatron_integration).get_connection(as_user=False)
    response = connection.ephemeral_message(request_data, msg)
    if response.get("ok"):
        return MegatronResponse({"ok": True, "track": True}, 200)
    return MegatronResponse({
        "error": response.get("error"),
        "track": False
    }, 500)
예제 #11
0
def unpause_channel(
    megatron_user_id: int, serialized_request_data: dict, arguments: dict
) -> dict:
    request_data = RequestData(**serialized_request_data)
    return _unpause_channel(megatron_user_id, request_data, arguments)
예제 #12
0
def interactive_message(request):
    payload = json.loads(request.POST['payload'])
    megatron_user = MegatronIntegration.objects.get(
        platform_id=payload['team']['id']).megatron_user
    callback_id = payload['callback_id']
    action_type = payload['actions'][0]['type']
    command_str = callback_id.split('|')[0]
    command = Command.get_command(command_str)
    response_channel = payload['channel']['id']
    response_url = payload['response_url']
    response_user = payload['user']['id']

    request_data = RequestData(channel_id=response_channel,
                               user_id=response_user,
                               response_url=response_url)

    # TODO: Make all command.action calls async, at which point this is unneeded
    request_data = kombu_json.loads(kombu_json.dumps(request_data))

    if action_type == 'select':
        workspace_id, platform_user_id = payload['actions'][0][
            'selected_options'][0]['value'].split('-')
        workspace = CustomerWorkspace.objects.get(platform_id=workspace_id)
        platform_user = WorkspaceService(workspace).get_or_create_user_by_id(
            platform_user_id)
    elif action_type == 'button':
        workspace_id, platform_user_id = payload['actions'][0]['value'].split(
            '-')
        workspace = CustomerWorkspace.objects.get(platform_id=workspace_id)
        platform_user = WorkspaceService(workspace).get_or_create_user_by_id(
            platform_user_id)
    else:
        return MegatronResponse('Received unknown action type', 400)

    if not platform_user:
        LOGGER.error("Could not identify platform user to act on.",
                     extra={'platform_user_id': user_id})
        return

    arguments = {
        'targeted_user_id': platform_user.id,
        'targeted_platform_id': platform_user_id
    }

    if command_str == 'open':
        response = command.action(megatron_user.id, request_data, arguments)
        if response.get('ok'):
            return HttpResponse(b'')

    elif command_str == 'close':
        response = command.action(megatron_user.id, request_data, arguments)
        if response.get('ok'):
            msg = formatting.user_titled(platform_user, "Got it!")
        else:
            msg = formatting.user_titled(platform_user,
                                         "Couldn't find an open channel.")
        return JsonResponse(msg)

    elif command_str == 'pause':
        command.action(megatron_user.id, request_data, arguments)
        msg = formatting.get_pause_warning(workspace_id, platform_user_id)
        return JsonResponse(msg)

    elif command_str == 'unpause':
        command.action(megatron_user.id, request_data, arguments)
        msg = formatting.get_unpaused_warning(workspace_id, platform_user_id)
        return JsonResponse(msg)

    elif command_str == 'clear-context':
        response = command.action(megatron_user.id, request_data, arguments)
        if response['ok']:
            return HttpResponse(b'')

    else:
        return MegatronResponse('Unknown command', 400)

    return MegatronResponse(response.get('error'), response.get('status'))
예제 #13
0
def interactive_message(request):
    payload = json.loads(request.POST["payload"])
    megatron_user = MegatronIntegration.objects.get(
        platform_id=payload["team"]["id"]).megatron_user
    callback_id = payload["callback_id"]
    action_type = payload["actions"][0]["type"]
    command_str = callback_id.split("|")[0]
    command = Command.get_command(command_str)
    response_channel = payload["channel"]["id"]
    response_url = payload["response_url"]
    response_user = payload["user"]["id"]

    request_data = RequestData(channel_id=response_channel,
                               user_id=response_user,
                               response_url=response_url)

    # TODO: Make all command.action calls async, at which point this is unneeded
    request_data = kombu_json.loads(kombu_json.dumps(request_data))

    if action_type == "select":
        workspace_id, platform_user_id = payload["actions"][0][
            "selected_options"][0]["value"].split("-")
        workspace = CustomerWorkspace.objects.get(platform_id=workspace_id)
        platform_user = WorkspaceService(workspace).get_or_create_user_by_id(
            platform_user_id)
    elif action_type == "button":
        workspace_id, platform_user_id = payload["actions"][0]["value"].split(
            "-")
        workspace = CustomerWorkspace.objects.get(platform_id=workspace_id)
        platform_user = WorkspaceService(workspace).get_or_create_user_by_id(
            platform_user_id)
    else:
        return MegatronResponse("Received unknown action type", 400)

    if not platform_user:
        LOGGER.error(
            "Could not identify platform user to act on.",
            extra={"platform_user_id": platform_user_id},
        )
        return

    arguments = {
        "targeted_user_id": platform_user.id,
        "targeted_platform_id": platform_user_id,
    }

    if command_str == "open":
        response = command.action(megatron_user.id, request_data, arguments)
        if response.get("ok"):
            return HttpResponse(b"")

    elif command_str == "close":
        response = command.action(megatron_user.id, request_data, arguments)
        if response.get("ok"):
            msg = formatting.user_titled(platform_user, "Got it!")
        else:
            msg = formatting.user_titled(platform_user,
                                         "Couldn't find an open channel.")
        return JsonResponse(msg)

    elif command_str == "pause":
        command.action(megatron_user.id, request_data, arguments)
        msg = formatting.get_pause_warning(workspace_id, platform_user_id)
        return JsonResponse(msg)

    elif command_str == "unpause":
        command.action(megatron_user.id, request_data, arguments)
        msg = formatting.get_unpaused_warning(workspace_id, platform_user_id)
        return JsonResponse(msg)

    elif command_str == "clear-context":
        response = command.action(megatron_user.id, request_data, arguments)
        if response["ok"]:
            return HttpResponse(b"")

    else:
        return MegatronResponse("Unknown command", 400)

    return MegatronResponse(response.get("error"), response.get("status"))