@POST @ApiOperation(value = "Collect bulk events from remote", request = BulkEventRemote.class, response = Integer.class) @ApiResponses(value = {@ApiResponse(code = 409, message = PARTIAL_ERROR_MESSAGE, response = int[].class)}) @Path("/bulk/remote") public void bulkEventsRemote(RakamHttpRequest request) { bulkEventsRemote(request, true); }
@ApiOperation(value = "Set user properties", request = User.class, response = Integer.class) @ApiResponses(value = {@ApiResponse(code = 404, message = "User does not exist.")}) @Path("/set_properties") @POST public void setProperties(RakamHttpRequest request) { setPropertiesInline(request, (project, user) -> service.setUserProperties(project, user.id, user.properties)); }
@JsonRequest @ApiOperation(value = "Get user", authorizations = @Authorization(value = "read_key")) @ApiResponses(value = {@ApiResponse(code = 404, message = "User does not exist.")}) @Path("/get") public CompletableFuture<User> getUser(@Named("project") RequestContext context, @ApiParam("user") Object user) { return service.getUser(context, user); }
@POST @JsonRequest @ApiOperation(value = "Get events of the user", authorizations = @Authorization(value = "read_key")) @ApiResponses(value = {@ApiResponse(code = 404, message = "User does not exist.")}) @Path("/get_events") public CompletableFuture<List<CollectionEvent>> getEvents(@Named("project") RequestContext context, @ApiParam("user") String user, @ApiParam(value = "limit", required = false) Integer limit, @ApiParam(value = "properties", required = false) List<String> properties, @ApiParam(value = "offset", required = false) Instant offset) { return service.getEvents(context, user, properties == null ? Optional.empty() : Optional.of(properties), limit == null ? 15 : limit, offset); }
@Path("/get") @JsonRequest @ApiOperation(value = "Get user mailbox", notes = "Returns the last mails sent to the user", response = Message.class, responseContainer = "List", authorizations = @Authorization(value = "read_key") ) @ApiResponses(value = {@ApiResponse(code = 404, message = "User does not exist.")}) public List<Message> getMailbox(@Named("project") RequestContext context, @ApiParam(value = "user", description = "User id") String user, @ApiParam(value = "parent", description = "Parent message id", required = false) Integer parent, @ApiParam(value = "limit", description = "Message query result limit", allowableValues = "range[1,100]", required = false) Integer limit, @ApiParam(value = "offset", description = "Message query result offset", required = false) Long offset) { return storage.getConversation(context.project, user, parent, firstNonNull(limit, 100), firstNonNull(offset, 0L)); }
@JsonRequest @ApiOperation(value = "Mark mail as read", notes = "Marks the specified mails as read.", authorizations = @Authorization(value = "write_key") ) @ApiResponses(value = {@ApiResponse(code = 404, message = "Message does not exist."), @ApiResponse(code = 404, message = "User does not exist.")}) @Path("/mark_as_read") public SuccessMessage markAsRead( @Named("project") RequestContext context, @ApiParam(value = "user", description = "User id") String user, @ApiParam(value = "message_ids", description = "The list of of message ids that will be marked as read") int[] message_ids) { storage.markMessagesAsRead(context.project, user, message_ids); return SuccessMessage.success(); }
@POST @ApiOperation(notes = "Returns 1 if the events are collected.", value = "Collect multiple events", request = EventList.class, response = Integer.class) @ApiResponses(value = { @ApiResponse(code = 409, message = PARTIAL_ERROR_MESSAGE, response = int[].class) })
@Path("/action/mailbox/single") @POST @JsonRequest @ApiOperation(value = "Send message to user", notes = "Sends a mail to users mailbox", authorizations = @Authorization(value = "write_key") ) @ApiResponses(value = {@ApiResponse(code = 404, message = "User does not exist.")}) public Message sendMail(@Named("project") RequestContext context, @ApiParam("from_user") String fromUser, @ApiParam("to_user") String toUser, @ApiParam(value = "parent", description = "Parent message id", required = false) Integer parent, @ApiParam(value = "message", description = "The content of the message", required = false) String message, @ApiParam(value = "timestamp", description = "The timestamp of the message") long datetime) { try { return mailboxStorage.send(context.project, fromUser, toUser, parent, message, Instant.ofEpochMilli(datetime)); } catch (Exception e) { throw new RakamException("Error while sending message: " + e.getMessage(), HttpResponseStatus.BAD_REQUEST); } }
@JsonRequest @POST @ApiOperation(value = "Get report", authorizations = @Authorization(value = "read_key")) @ApiResponses(value = {@ApiResponse(code = 400, message = "Report does not exist.")}) @Path("/get") public CompletableFuture<RealTimeQueryResult> queryTable( @Named("project") RequestContext context, @ApiParam("table_name") String tableName, @ApiParam(value = "filter", required = false) String filter, @ApiParam("measure") RealTimeReport.Measure measure, @ApiParam(value = "dimensions", required = false) List<String> dimensions, @ApiParam(value = "aggregate", required = false) Boolean aggregate, @ApiParam(value = "date_start", required = false) Instant dateStart, @ApiParam(value = "date_end", required = false) Instant dateEnd) { return realtimeService.query(context.project, tableName, filter, measure, dimensions, aggregate, dateStart, dateEnd); }
@ApiOperation(value = "Batch operation on a single user properties", request = SingleUserBatchOperationRequest.class, response = Integer.class, authorizations = {@Authorization(value = "write_key")}) @ApiResponses(value = {@ApiResponse(code = 404, message = "User does not exist.")}) @Path("/batch") @JsonRequest public void batchSingleUserOperations(RakamHttpRequest request) { request.bodyHandler(s -> { SingleUserBatchOperationRequest req; try { req = JsonHelper.read(s, SingleUserBatchOperationRequest.class); } catch (Exception e) { returnError(request, e.getMessage(), BAD_REQUEST); return; } String project = apiKeyService.getProjectOfApiKey(req.api.apiKey, WRITE_KEY); InetAddress socketAddress = ((InetSocketAddress) request.context().channel() .remoteAddress()).getAddress(); DefaultFullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, wrappedBuffer(OK_MESSAGE)); List<Cookie> cookies = mapEvent(mapper -> mapper.map(project, req.data, new HttpRequestParams(request), socketAddress)); service.batch(project, req.data); setBrowser(request, response); if (cookies != null && !cookies.isEmpty()) { response.headers().add(SET_COOKIE, STRICT.encode(cookies)); } request.response(response).end(); }); }
@POST @JsonRequest @ApiOperation(value = "Get events of the user", authorizations = @Authorization(value = "master_key")) @ApiResponses(value = {@ApiResponse(code = 404, message = "User does not exist.")}) @Path("/create_segment") public SuccessMessage createSegment(@Named("project") RequestContext context, @ApiParam("name") String name, @ApiParam("table_name") String tableName, @ApiParam(value = "filter_expression", required = false) String filterExpression, @ApiParam(value = "event_filters", required = false) List<UserStorage.EventFilter> eventFilters, @ApiParam("cache_eviction") Duration duration) { if (filterExpression == null && (eventFilters == null || eventFilters.isEmpty())) { throw new RakamException("At least one predicate is required", BAD_REQUEST); } Expression expression = null; if (filterExpression != null) { synchronized (sqlParser) { expression = sqlParser.createExpression(filterExpression); } } service.createSegment(context, name, tableName, expression, eventFilters, duration); return SuccessMessage.success(); }
@JsonRequest @ApiOperation(value = "Merge user with anonymous id", authorizations = @Authorization(value = "write_key")) @ApiResponses(value = {@ApiResponse(code = 404, message = "User does not exist.")}) @Path("/merge") @IgnoreApi @AllowCookie public void mergeUser(RakamHttpRequest request, @BodyParam MergeRequest mergeRequest) { // TODO: what if a user sends real user ids instead of its previous anonymous id? if (!config.getEnableUserMapping()) { throw new RakamException("The feature is not supported", PRECONDITION_FAILED); } Object anonymousId = mergeRequest.anonymousId; DefaultFullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, wrappedBuffer(OK_MESSAGE)); setBrowser(request, response); if (anonymousId == null) { throw new RakamException("Anonymous id is required", BAD_REQUEST); } String project = apiKeyService.getProjectOfApiKey(mergeRequest.api.apiKey, WRITE_KEY); service.merge(project, mergeRequest.id, anonymousId, Instant.ofEpochMilli(mergeRequest.createdAt), Instant.ofEpochMilli(mergeRequest.mergedAt)); request.response(response).end(); }
@JsonRequest @ApiOperation(value = "Unset user property") @ApiResponses(value = {@ApiResponse(code = 404, message = "User does not exist.")}) @Path("/unset_properties") @AllowCookie public SuccessMessage unsetProperty(@ApiParam("api") User.UserContext api, @ApiParam("id") Object id, @ApiParam("properties") List<String> properties) { String project = apiKeyService.getProjectOfApiKey(api.apiKey, WRITE_KEY); service.unsetProperties(project, id, properties); return SuccessMessage.success(); }
@JsonRequest @ApiOperation(value = "Set user properties once", request = User.class, response = Integer.class) @ApiResponses(value = {@ApiResponse(code = 404, message = "User does not exist.")}) @Path("/set_properties_once") public void setPropertiesOnce(RakamHttpRequest request) { request.bodyHandler(s -> { User req; try { req = JsonHelper.readSafe(s, User.class); } catch (IOException e) { returnError(request, e.getMessage(), BAD_REQUEST); return; } String project = apiKeyService.getProjectOfApiKey(req.api.apiKey, WRITE_KEY); DefaultFullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, wrappedBuffer(OK_MESSAGE)); response.headers().set(ACCESS_CONTROL_ALLOW_ORIGIN, request.headers().get(ORIGIN)); List<Cookie> cookies = mapProperties(project, req, request); if (cookies != null) { response.headers().add(SET_COOKIE, STRICT.encode(cookies)); } String headerList = getHeaderList(response.headers().iterator()); if (headerList != null) { response.headers().set(ACCESS_CONTROL_EXPOSE_HEADERS, headerList); } // TODO: we may cache these values and reduce the db hit. service.setUserPropertiesOnce(project, req.id, req.properties); request.response(OK_MESSAGE).end(); }); }
@JsonRequest @ApiOperation(value = "Set user property", authorizations = @Authorization(value = "master_key")) @ApiResponses(value = {@ApiResponse(code = 404, message = "User does not exist.")}) @Path("/increment_property") @AllowCookie public SuccessMessage incrementProperty(@ApiParam("api") User.UserContext api, @ApiParam("id") String user, @ApiParam("property") String property, @ApiParam("value") double value) { String project = apiKeyService.getProjectOfApiKey(api.apiKey, WRITE_KEY); service.incrementProperty(project, user, property, value); return SuccessMessage.success(); }
@ApiOperation(value = "Batch operations on user properties", request = BatchUserOperationRequest.class, response = Integer.class, authorizations = @Authorization(value = "master_key")) @ApiResponses(value = {@ApiResponse(code = 404, message = "User does not exist.")}) @Path("/batch_operations") @JsonRequest