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}
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}
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}
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}
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'')
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
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}
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}
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)
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)
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)
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'))
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"))