def outgoing(request) -> MegatronResponse: user_id = request.data['user'] message = request.data['message'] try: message['attachments'] = json.loads(message['attachments']) except TypeError: pass try: megatron_channel = MegatronChannel.objects.get( platform_user_id=user_id) except MegatronChannel.DoesNotExist: return MegatronResponse({'ok': True, 'track': False}, 200) if megatron_channel.is_archived: return MegatronResponse({'ok': True, 'track': False}, 200) megatron_integration = megatron_channel.megatron_integration interpreter = IntegrationService(megatron_integration).get_interpreter() customer_workspace_id = megatron_channel.workspace.platform_id response = interpreter.outgoing(message, megatron_channel) if response.get('ok'): if response.get('watched_channel'): front_integration.outgoing_message.delay(user_id, customer_workspace_id, message) megatron_msg = MegatronMessage(integration_msg_id=response['ts'], customer_msg_id=request.data['ts'], megatron_channel=megatron_channel) megatron_msg.save() return MegatronResponse({'ok': True, 'track': True}, 200) return MegatronResponse({ 'error': response.get('error'), 'track': False }, 500)
def safe_requests(self, method, url, *args, **kwargs): if not kwargs.get('timeout'): timeout = 10 else: timeout = kwargs.get('timeout') try: response = requests.request(method, url, *args, **kwargs, timeout=timeout) except requests.Timeout: LOGGER.exception("Megatron request timed out.") return MegatronResponse({ 'ok': False, 'error': 'Timeout error' }, 500) try: verified = self.response_verification(response) response_data = self.get_response_data(response) except: LOGGER.exception( "Error attempting to verify response from platform.") return response if not verified: LOGGER.exception("Recieved error response from platform.", extra={'response': response_data}) return response
def broadcast(request) -> MegatronResponse: warnings: list = [] required_params = ["text", "broadcasts"] for param in required_params: if param not in request.data: return MegatronResponse( {"error": f"Missing required param '{param}'."}, 400) text = request.data.get("text") broadcasts = request.data.get("broadcasts") try: message = json.loads(text) except ValueError: return raise_error(BroadcastError.malformed_broadcast, status=status.HTTP_400_BAD_REQUEST) try: capture_feedback = request.data["capture_feedback"] except KeyError: capture_feedback = False org_errors = {} for broadcast in broadcasts: bot_type = BotType[broadcast["platform_type"]] org_platform_id = broadcast["org_id"] user_ids = broadcast["user_ids"] connection = bot_type.get_bot_connection_from_platform_id( org_platform_id) # deepcopy prevents direct mutation of original broadcast action = Action( ActionType.BROADCAST, { "broadcast": deepcopy(message), "user_ids": user_ids, "capture_feedback": capture_feedback, }, ) response = connection.take_action(action) if not response.get("ok"): org_errors.update({org_platform_id: response.get("errors")}) if org_errors: return MegatronResponse({"errors": org_errors}, 200) elif warnings: return MegatronResponse({"ok": True, "warnings": warnings}, 200) else: return OK_RESPONSE
def broadcast(request) -> MegatronResponse: warnings: list = [] required_params = ['text', 'broadcasts'] for param in required_params: if param not in request.data: return MegatronResponse( {'error': f"Missing required param '{param}'."}, 400) text = request.data.get('text') broadcasts = request.data.get('broadcasts') try: message = json.loads(text) except ValueError: return raise_error(BroadcastError.malformed_broadcast, status=status.HTTP_400_BAD_REQUEST) try: capture_feedback = request.data['capture_feedback'] except KeyError: capture_feedback = False org_errors = {} for broadcast in broadcasts: bot_type = BotType[broadcast['platform_type']] org_platform_id = broadcast['org_id'] user_ids = broadcast['user_ids'] connection = bot_type.get_bot_connection_from_platform_id( org_platform_id) # deepcopy prevents direct mutation of original broadcast action = Action( ActionType.BROADCAST, { 'broadcast': deepcopy(message), 'user_ids': user_ids, 'capture_feedback': capture_feedback, }) response = connection.take_action(action) if not response.get('ok'): org_errors.update({org_platform_id: response.get('errors')}) if org_errors: return MegatronResponse({'errors': org_errors}, 200) elif warnings: return MegatronResponse({'ok': True, 'warnings': warnings}, 200) else: return OK_RESPONSE
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 register_workspace(request) -> MegatronResponse: workspace_data = json.loads(request.body) try: platform_name = workspace_data['platform_type'].capitalize() platform_type_id = PlatformType[platform_name].value except AttributeError: return MegatronResponse("Unknown platform type.", 400) try: workspace, _ = CustomerWorkspace.objects.get_or_create( connection_token=workspace_data['connection_token'], platform_type=platform_type_id, defaults={ 'platform_id': workspace_data['platform_id'], 'name': workspace_data['name'], 'domain': workspace_data['domain'] }) except: LOGGER.exception("Failed to create Workspace.") return MegatronResponse("Unknown error.", 500) return OK_RESPONSE
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 incoming(request) -> MegatronResponse: msg = request.data['message'] megatron_user = request.user integration = megatron_user.megatronintegration_set.first() team_interpreter = IntegrationService(integration).get_interpreter() channel = MegatronChannel.objects.filter( platform_user_id=msg['user']).first() if not channel or channel.is_archived: return MegatronResponse({'ok': True, 'track': False}, 200) response = team_interpreter.incoming(msg, channel) if response.get('ok'): if response.get('watched_channel'): front_integration.incoming_message.delay(msg) channel = MegatronChannel.objects.filter( platform_user_id=request.data['message']['user']).first() MegatronMessage.objects.create( integration_msg_id=response['ts'], customer_msg_id=request.data['message']['ts'], megatron_channel=channel) return OK_RESPONSE return MegatronResponse(response.get('error'), 500)
def message(request, user_id) -> MegatronResponse: msg = request.data bot_type = BotType.slack try: user = User.objects.get(id=int(user_id)) except User.DoesNotExist: return raise_error(BroadcastError.user_not_found, status=status.HTTP_400_BAD_REQUEST) organization = user.profile.organization connection = bot_type.get_bot_connection(organization) response = connection.dm_user(user.slackuser.slack_id, msg) if response.get('ok'): return OK_RESPONSE return MegatronResponse(response.get('error'), response.get('status'))
def outgoing(request) -> MegatronResponse: user_id = request.data["user"] message = request.data["message"] try: message["attachments"] = json.loads(message["attachments"]) except TypeError: pass try: megatron_channel = MegatronChannel.objects.get( platform_user_id=user_id) except MegatronChannel.DoesNotExist: return MegatronResponse({"ok": True, "track": False}, 200) if megatron_channel.is_archived: return MegatronResponse({"ok": True, "track": False}, 200) megatron_integration = megatron_channel.megatron_integration interpreter = IntegrationService(megatron_integration).get_interpreter() customer_workspace_id = megatron_channel.workspace.platform_id response = interpreter.outgoing(message, megatron_channel) if response.get("ok"): if response.get("watched_channel"): front_integration.outgoing_message.delay(user_id, customer_workspace_id, message) megatron_msg = MegatronMessage( integration_msg_id=response["ts"], customer_msg_id=request.data["ts"], megatron_channel=megatron_channel, ) megatron_msg.save() return MegatronResponse({"ok": True, "track": True}, 200) return MegatronResponse({ "error": response.get("error"), "track": False }, 500)
def incoming(request) -> MegatronResponse: msg = request.data["message"] megatron_user = request.user integration = megatron_user.megatronintegration_set.first() team_interpreter = IntegrationService(integration).get_interpreter() channel = MegatronChannel.objects.filter( platform_user_id=msg["user"]).first() if not channel or channel.is_archived: return MegatronResponse({"ok": True, "track": False}, 200) response = team_interpreter.incoming(msg, channel) if response.get("ok"): if response.get("watched_channel"): front_integration.incoming_message.delay(msg) channel = MegatronChannel.objects.filter( platform_user_id=request.data["message"]["user"]).first() MegatronMessage.objects.create( integration_msg_id=response["ts"], customer_msg_id=request.data["message"]["ts"], megatron_channel=channel, ) return OK_RESPONSE return MegatronResponse(response.get("error"), 500)
def get_a_human(request): payload = json.loads(request.body) requesting_user = payload['requesting_user'] workspace_id = payload['workspace_id'] integration = MegatronIntegration.objects.get( megatron_user__id=request.user.id) team_connection = IntegrationService(integration).get_connection( as_user=False) # TODO: This should all be integration dependent channel = settings.NOTIFICATIONS_CHANNELS[ NotificationChannels.customer_service] slack_name = requesting_user['with_team_domain'] attach = { "color": '1f355e', "text": f"🆘 *{slack_name}* requested some help!", "callback_id": f"open", "actions": [{ "name": "categorize", "text": "Open engagement channel", "type": "button", "value": f'{workspace_id}-{requesting_user["slack_id"]}' }], "mrkdwn_in": ["text"] } msg = ({'text': ' ', 'attachments': [attach]}) msg_action = Action(ActionType.POST_MESSAGE, { 'channel': channel, 'message': msg }) response = team_connection.take_action(msg_action) if response.get('ok'): return OK_RESPONSE return MegatronResponse(response.get('error'), response.get('status'))
def test(request): return MegatronResponse({'ok': True}, 200)
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"))
def test(request): return MegatronResponse({"ok": True}, 200)