Skip to content

Commit 3b132ea

Browse files
authored
(For David) Add support for Rescore User and Get User Score APIs (#30)
* Add support for Rescore User and Get User Score APIs * PR feedback * Use new StringUtils * More PR feedback
1 parent a138b07 commit 3b132ea

14 files changed

+500
-8
lines changed

CHANGES.MD

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1+
2.3.0 (2018-08-08)
2+
=================
3+
4+
- Add support for Rescore User and Get User Score APIs
5+
16
2.2.1 (2018-08-06)
7+
=================
8+
29
- Remove Guava dependency
310
- Replace use of internal Sun API class
411

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.siftscience;
2+
3+
import com.siftscience.model.AbuseScore;
4+
import com.siftscience.model.EntityScoreResponseBody;
5+
import okhttp3.Response;
6+
7+
import java.io.IOException;
8+
9+
public class EntityScoreResponse extends SiftResponse<EntityScoreResponseBody> {
10+
EntityScoreResponse(Response okResponse, FieldSet requestBody) throws IOException {
11+
super(okResponse, requestBody);
12+
}
13+
14+
@Override
15+
void populateBodyFromJson(String jsonBody) {
16+
body = EntityScoreResponseBody.fromJson(jsonBody);
17+
}
18+
19+
public AbuseScore getScoreResponse(String abuseType) {
20+
if (this.getBody() != null && this.getBody().getScores() != null) {
21+
return this.getBody().getScores().get(abuseType);
22+
}
23+
return null;
24+
}
25+
26+
public Double getScore(String abuseType) {
27+
AbuseScore abuseScore = getScoreResponse(abuseType);
28+
if (abuseScore != null) {
29+
return abuseScore.getScore();
30+
}
31+
return null;
32+
}
33+
}

src/main/java/com/siftscience/SiftClient.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ public ScoreRequest buildRequest(ScoreFieldSet fields) {
8282
return new ScoreRequest(baseUrl, okClient, fields);
8383
}
8484

85+
public UserScoreRequest buildRequest(UserScoreFieldSet fields) {
86+
setupApiKey(fields);
87+
return new UserScoreRequest(baseUrl, okClient, fields);
88+
}
89+
8590
public WorkflowStatusRequest buildRequest(WorkflowStatusFieldSet fields) {
8691
setupApiKey(fields);
8792
return new WorkflowStatusRequest(baseApi3Url, okClient, fields);
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.siftscience;
2+
3+
import com.siftscience.model.UserScoreFieldSet;
4+
import okhttp3.HttpUrl;
5+
import okhttp3.OkHttpClient;
6+
import okhttp3.Request;
7+
import okhttp3.RequestBody;
8+
import okhttp3.Response;
9+
10+
import java.io.IOException;
11+
12+
/**
13+
* UserScoreRequest is the request type of Sift User Score API requests.
14+
*
15+
* This includes:
16+
* 1. The get user score API, which returns the latest score(s) computed for a user.
17+
* See details here: https://siftscience.com/developers/docs/java/score-api/get-score
18+
* 2. The rescore user API, which recomputes scores for a user.
19+
* See details here: https://siftscience.com/developers/docs/java/score-api/rescore
20+
*/
21+
public class UserScoreRequest extends SiftRequest<EntityScoreResponse> {
22+
UserScoreRequest(HttpUrl baseUrl, OkHttpClient okClient, UserScoreFieldSet fields) {
23+
super(baseUrl, okClient, fields);
24+
}
25+
26+
/**
27+
* Use a POST request if this is a rescore user request, otherwise use a GET request.
28+
*/
29+
@Override
30+
protected void modifyRequestBuilder(Request.Builder builder) {
31+
if (((UserScoreFieldSet)fieldSet).getRescoreUser()) {
32+
builder.post(RequestBody.create(null, new byte[0]));
33+
} else {
34+
builder.get();
35+
}
36+
}
37+
38+
@Override
39+
EntityScoreResponse buildResponse(Response response, FieldSet requestFields)
40+
throws IOException {
41+
return new EntityScoreResponse(response, requestFields);
42+
}
43+
44+
/**
45+
* For user score requests, the api key and abuse types are encoded into the URL as query params
46+
*/
47+
@Override
48+
protected HttpUrl path(HttpUrl baseUrl) {
49+
UserScoreFieldSet userScoreFieldSet = (UserScoreFieldSet)fieldSet;
50+
HttpUrl.Builder builder = baseUrl.newBuilder().addPathSegment("v205");
51+
builder.addPathSegment("users")
52+
.addPathSegment(userScoreFieldSet.getUserId())
53+
.addPathSegment("score")
54+
.addQueryParameter("api_key", userScoreFieldSet.getApiKey());
55+
if (userScoreFieldSet.getAbuseTypes() != null
56+
&& !userScoreFieldSet.getAbuseTypes().isEmpty()) {
57+
String queryParamVal = StringUtils.joinWithComma(userScoreFieldSet.getAbuseTypes());
58+
builder.addQueryParameter("abuse_types", queryParamVal);
59+
}
60+
return builder.build();
61+
}
62+
}

src/main/java/com/siftscience/model/AbuseScore.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
public class AbuseScore {
99
@Expose @SerializedName("score") private Double score;
1010
@Expose @SerializedName("reasons") private List<Reason> reasons;
11+
@Expose @SerializedName("status") private int status;
12+
@Expose @SerializedName("error_message") private String errorMessage;
13+
@Expose @SerializedName("time") private long time;
1114

1215
public Double getScore() {
1316
return score;
@@ -26,4 +29,31 @@ public AbuseScore setReasons(List<Reason> reasons) {
2629
this.reasons = reasons;
2730
return this;
2831
}
32+
33+
public int getStatus() {
34+
return status;
35+
}
36+
37+
public AbuseScore setStatus(int status) {
38+
this.status = status;
39+
return this;
40+
}
41+
42+
public String getErrorMessage() {
43+
return errorMessage;
44+
}
45+
46+
public AbuseScore setErrorMessage(String errorMessage) {
47+
this.errorMessage = errorMessage;
48+
return this;
49+
}
50+
51+
public long getTime() {
52+
return time;
53+
}
54+
55+
public AbuseScore setTime(long time) {
56+
this.time = time;
57+
return this;
58+
}
2959
}

src/main/java/com/siftscience/model/Decision.java

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,14 @@
33
import com.google.gson.annotations.Expose;
44
import com.google.gson.annotations.SerializedName;
55

6+
import java.util.Objects;
7+
68
public class Decision {
79
@Expose @SerializedName("id") private String id;
10+
@Expose @SerializedName("category") private String category;
11+
@Expose @SerializedName("time") private long time;
12+
@Expose @SerializedName("source") private String source;
13+
@Expose @SerializedName("description") private String description;
814

915
public String getId() {
1016
return id;
@@ -14,4 +20,54 @@ public Decision setId(String id) {
1420
this.id = id;
1521
return this;
1622
}
23+
24+
public String getCategory() {
25+
return category;
26+
}
27+
28+
public Decision setCategory(String category) {
29+
this.category = category;
30+
return this;
31+
}
32+
33+
public long getTime() {
34+
return time;
35+
}
36+
37+
public Decision setTime(long time) {
38+
this.time = time;
39+
return this;
40+
}
41+
42+
public String getSource() {
43+
return source;
44+
}
45+
46+
public Decision setSource(String source) {
47+
this.source = source;
48+
return this;
49+
}
50+
51+
public String getDescription() {
52+
return description;
53+
}
54+
55+
public Decision setDescription(String description) {
56+
this.description = description;
57+
return this;
58+
}
59+
60+
@Override
61+
public boolean equals(Object other) {
62+
if (!(other instanceof Decision)) {
63+
return false;
64+
}
65+
66+
Decision o = (Decision) other;
67+
return Objects.equals(getId(), o.getId())
68+
&& Objects.equals(getCategory(), o.getCategory())
69+
&& getTime() == o.getTime()
70+
&& Objects.equals(getSource(), o.getSource())
71+
&& Objects.equals(getDescription(), o.getDescription());
72+
}
1773
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package com.siftscience.model;
2+
3+
import com.google.gson.annotations.Expose;
4+
import com.google.gson.annotations.SerializedName;
5+
6+
import java.util.List;
7+
import java.util.Map;
8+
9+
public class EntityScoreResponseBody extends BaseResponseBody<EntityScoreResponseBody> {
10+
public static EntityScoreResponseBody fromJson(String json) {
11+
return gson.fromJson(json, EntityScoreResponseBody.class);
12+
}
13+
14+
@Expose @SerializedName("entity_type") private String entityType;
15+
@Expose @SerializedName("entity_id") private String entityId;
16+
@Expose @SerializedName("scores") private Map<String, AbuseScore> scores;
17+
@Expose @SerializedName("latest_labels") private Map<String, Label> latestLabels;
18+
@Expose @SerializedName("latest_decisions") private Map<String, Decision> latestDecisions;
19+
@Expose @SerializedName("workflow_statuses") private List<WorkflowStatus> workflowStatuses;
20+
21+
public String getEntityType() {
22+
return entityType;
23+
}
24+
25+
public EntityScoreResponseBody setEntityType(String entityType) {
26+
this.entityType = entityType;
27+
return this;
28+
}
29+
30+
public String getEntityId() {
31+
return entityId;
32+
}
33+
34+
public EntityScoreResponseBody setEntityId(String entityId) {
35+
this.entityId = entityId;
36+
return this;
37+
}
38+
39+
public Map<String, AbuseScore> getScores() {
40+
return scores;
41+
}
42+
43+
public EntityScoreResponseBody setScores(Map<String, AbuseScore> scores) {
44+
this.scores = scores;
45+
return this;
46+
}
47+
48+
public Map<String, Label> getLatestLabels() {
49+
return latestLabels;
50+
}
51+
52+
public EntityScoreResponseBody setLatestLabels(Map<String, Label> latestLabels) {
53+
this.latestLabels = latestLabels;
54+
return this;
55+
}
56+
57+
public Map<String, Decision> getLatestDecisions() {
58+
return latestDecisions;
59+
}
60+
61+
public EntityScoreResponseBody setLatestDecisions(Map<String, Decision> latestDecisions) {
62+
this.latestDecisions = latestDecisions;
63+
return this;
64+
}
65+
66+
public List<WorkflowStatus> getWorkflowStatuses() {
67+
return workflowStatuses;
68+
}
69+
70+
public EntityScoreResponseBody setWorkflowStatuses(List<WorkflowStatus> workflowStatuses) {
71+
this.workflowStatuses = workflowStatuses;
72+
return this;
73+
}
74+
75+
public WorkflowStatus getWorkflowStatus(int i) {
76+
return workflowStatuses.get(i);
77+
}
78+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.siftscience.model;
2+
3+
import com.google.gson.annotations.Expose;
4+
import com.google.gson.annotations.SerializedName;
5+
import com.siftscience.FieldSet;
6+
7+
import java.util.List;
8+
9+
public class UserScoreFieldSet extends FieldSet<UserScoreFieldSet> {
10+
@Expose @SerializedName(USER_ID) private String userId;
11+
private List<String> abuseTypes;
12+
private boolean rescoreUser = false;
13+
14+
public String getUserId() {
15+
return userId;
16+
}
17+
18+
public UserScoreFieldSet setUserId(String userId) {
19+
this.userId = userId;
20+
return this;
21+
}
22+
23+
public List<String> getAbuseTypes() {
24+
return abuseTypes;
25+
}
26+
27+
public UserScoreFieldSet setAbuseTypes(List<String> abuseTypes) {
28+
this.abuseTypes = abuseTypes;
29+
return this;
30+
}
31+
32+
public boolean getRescoreUser() {
33+
return rescoreUser;
34+
}
35+
36+
public UserScoreFieldSet setRescoreUser(boolean rescoreUser) {
37+
this.rescoreUser = rescoreUser;
38+
return this;
39+
}
40+
41+
}

src/test/java/com/siftscience/ContentDecisionStatusTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,6 @@ public void testContentDecisionStatus() throws Exception {
6161
// Verify the response was parsed correctly.
6262
Assert.assertEquals(HTTP_OK, siftResponse.getHttpStatusCode());
6363
JSONAssert.assertEquals(response.getBody().readUtf8(),
64-
siftResponse.getBody().toJson(), true);
64+
siftResponse.getBody().toJson(), false);
6565
}
6666
}

src/test/java/com/siftscience/DecisionStatusTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public void testDecisionStatus() throws Exception {
8686
// Verify the response was parsed correctly.
8787
Assert.assertEquals(HTTP_OK, siftResponse.getHttpStatusCode());
8888
JSONAssert.assertEquals(response.getBody().readUtf8(),
89-
siftResponse.getBody().toJson(), true);
89+
siftResponse.getBody().toJson(), false);
9090
}
9191

9292
@Test
@@ -136,6 +136,6 @@ public void testContentDecisionStatus() throws Exception {
136136
// Verify the response was parsed correctly.
137137
Assert.assertEquals(HTTP_OK, siftResponse.getHttpStatusCode());
138138
JSONAssert.assertEquals(response.getBody().readUtf8(),
139-
siftResponse.getBody().toJson(), true);
139+
siftResponse.getBody().toJson(), false);
140140
}
141141
}

0 commit comments

Comments
 (0)