Skip to content

Commit dbac346

Browse files
Merge pull request #151 from GetStream/moderation
[MOD-195] add moderation endpoints
2 parents 3951db9 + 2b24dae commit dbac346

12 files changed

Lines changed: 435 additions & 16 deletions

File tree

src/main/java/io/getstream/client/Client.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,10 @@ public ReactionsClient reactions() {
250250
return new ReactionsClient(secret, stream.reactions());
251251
}
252252

253+
public ModerationClient moderation() {
254+
return new ModerationClient(secret, stream.moderation());
255+
}
256+
253257
public FileStorageClient files() {
254258
return new FileStorageClient(secret, stream.files());
255259
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package io.getstream.client;
2+
3+
import static io.getstream.core.utils.Auth.buildReactionsToken;
4+
import static io.getstream.core.utils.Routes.*;
5+
import static io.getstream.core.utils.Serialization.*;
6+
7+
import io.getstream.core.Moderation;
8+
import io.getstream.core.exceptions.StreamException;
9+
import io.getstream.core.http.Response;
10+
import io.getstream.core.http.Token;
11+
import io.getstream.core.utils.Auth;
12+
import java.util.Map;
13+
import java8.util.concurrent.CompletableFuture;
14+
15+
public class ModerationClient {
16+
private final String secret;
17+
private final Moderation mod;
18+
19+
ModerationClient(String secret, Moderation mod) {
20+
this.secret = secret;
21+
this.mod = mod;
22+
}
23+
24+
public CompletableFuture<Response> flagUser(
25+
String flaggedUserId, String reason, Map<String, Object> options) throws StreamException {
26+
return flag("stream:user", flaggedUserId, "", reason, options);
27+
}
28+
29+
public CompletableFuture<Response> flagActivity(
30+
String entityId, String entityCreatorId, String reason, Map<String, Object> options)
31+
throws StreamException {
32+
return flag("stream:feeds:v2:activity", entityId, entityCreatorId, reason, options);
33+
}
34+
35+
public CompletableFuture<Response> flagReaction(
36+
String entityId, String entityCreatorId, String reason, Map<String, Object> options)
37+
throws StreamException {
38+
return flag("stream:feeds:v2:reaction", entityId, entityCreatorId, reason, options);
39+
}
40+
41+
private CompletableFuture<Response> flag(
42+
String entityType,
43+
String entityId,
44+
String entityCreatorId,
45+
String reason,
46+
Map<String, Object> options)
47+
throws StreamException {
48+
final Token token = buildReactionsToken(secret, Auth.TokenAction.WRITE);
49+
return mod.flag(token, entityType, entityId, entityCreatorId, reason, options);
50+
}
51+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package io.getstream.core;
2+
3+
import static io.getstream.core.utils.Request.buildPost;
4+
import static io.getstream.core.utils.Routes.*;
5+
import static io.getstream.core.utils.Serialization.*;
6+
7+
import com.fasterxml.jackson.core.JsonProcessingException;
8+
import io.getstream.core.exceptions.StreamException;
9+
import io.getstream.core.http.HTTPClient;
10+
import io.getstream.core.http.Response;
11+
import io.getstream.core.http.Token;
12+
import java.net.MalformedURLException;
13+
import java.net.URISyntaxException;
14+
import java.net.URL;
15+
import java.util.Map;
16+
import java8.util.concurrent.CompletableFuture;
17+
import java8.util.concurrent.CompletionException;
18+
19+
public class Moderation {
20+
private final String key;
21+
private final URL baseURL;
22+
private final HTTPClient httpClient;
23+
24+
public Moderation(String key, URL baseURL, HTTPClient httpClient) {
25+
this.key = key;
26+
this.baseURL = baseURL;
27+
this.httpClient = httpClient;
28+
}
29+
30+
public CompletableFuture<Response> flag(
31+
Token token,
32+
String entityType,
33+
String entityId,
34+
String entityCreatorId,
35+
String reason,
36+
Map<String, Object> options)
37+
throws StreamException {
38+
try {
39+
final byte[] payload =
40+
toJSON(
41+
new Object() {
42+
public final String UserId = entityCreatorId;
43+
public final String EntityType = entityType;
44+
public final String EntityId = entityId;
45+
public final String Reason = reason;
46+
});
47+
48+
final URL url = buildModerationFlagURL(baseURL);
49+
return httpClient.execute(buildPost(url, key, token, payload));
50+
} catch (JsonProcessingException | MalformedURLException | URISyntaxException e) {
51+
throw new CompletionException(e);
52+
}
53+
}
54+
}

src/main/java/io/getstream/core/Stream.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ public StreamReactions reactions() {
5959
return new StreamReactions(key, baseURL, httpClient);
6060
}
6161

62+
public Moderation moderation() {
63+
return new Moderation(key, baseURL, httpClient);
64+
}
65+
6266
public StreamFiles files() {
6367
return new StreamFiles(key, baseURL, httpClient);
6468
}

src/main/java/io/getstream/core/StreamReactions.java

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,9 @@ public CompletableFuture<Reaction> add(
235235
if (reaction.getExtra() != null) {
236236
payloadBuilder.put("data", reaction.getExtra());
237237
}
238+
if (reaction.getModerationTemplate() != null) {
239+
payloadBuilder.put("moderation_template", reaction.getModerationTemplate());
240+
}
238241
final byte[] payload = toJSON(payloadBuilder.build());
239242
final URL url = buildReactionsURL(baseURL);
240243
return httpClient
@@ -284,26 +287,29 @@ public CompletableFuture<Void> update(Token token, Reaction reaction, FeedID...
284287
}
285288
}
286289

287-
public CompletableFuture<Void> delete(Token token, String id, Boolean soft) throws StreamException {
290+
public CompletableFuture<Void> delete(Token token, String id, Boolean soft)
291+
throws StreamException {
288292
checkNotNull(id, "Reaction id can't be null");
289293
checkArgument(!id.isEmpty(), "Reaction id can't be empty");
290294

291295
try {
292296
final URL url = buildReactionsURL(baseURL, id + '/');
293-
294-
final Request deleteRequest = soft ? buildDelete(url, key, token, new CustomQueryParameter("soft", "true"))
295-
: buildDelete(url, key, token);
297+
298+
final Request deleteRequest =
299+
soft
300+
? buildDelete(url, key, token, new CustomQueryParameter("soft", "true"))
301+
: buildDelete(url, key, token);
296302

297303
return httpClient
298-
.execute(deleteRequest)
299-
.thenApply(
300-
response -> {
301-
try {
302-
return deserializeError(response);
303-
} catch (StreamException | IOException e) {
304-
throw new CompletionException(e);
305-
}
306-
});
304+
.execute(deleteRequest)
305+
.thenApply(
306+
response -> {
307+
try {
308+
return deserializeError(response);
309+
} catch (StreamException | IOException e) {
310+
throw new CompletionException(e);
311+
}
312+
});
307313
} catch (MalformedURLException | URISyntaxException e) {
308314
throw new StreamException(e);
309315
}

src/main/java/io/getstream/core/http/Request.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,4 +155,4 @@ public Request build() throws MalformedURLException, URISyntaxException {
155155
return new Request(this);
156156
}
157157
}
158-
}
158+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package io.getstream.core.models;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
6+
public class APIError {
7+
private String Code;
8+
private String Message;
9+
private String Status;
10+
11+
public String toString() {
12+
return "{Code='" + Code + "', Message=" + Message + "}";
13+
}
14+
15+
// Default constructor
16+
public APIError() {}
17+
18+
// Constructor with parameters
19+
@JsonCreator
20+
public APIError(
21+
@JsonProperty("code") String code,
22+
@JsonProperty("message") String message,
23+
@JsonProperty("status") String status) {
24+
this.Code = code;
25+
this.Message = message;
26+
this.Status = status;
27+
}
28+
29+
// Getters
30+
public String getCode() {
31+
return Code;
32+
}
33+
34+
public String getMessage() {
35+
return Message;
36+
}
37+
}

src/main/java/io/getstream/core/models/Activity.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
@JsonInclude(Include.NON_NULL)
2020
@JsonDeserialize(builder = Activity.Builder.class)
2121
public class Activity {
22+
2223
private final String id;
2324
private final String actor;
2425
private final String verb;
@@ -31,6 +32,8 @@ public class Activity {
3132
private final List<FeedID> to;
3233
private final Double score;
3334
private final Map<String, Object> extra;
35+
private final String moderationTemplate;
36+
private final ModerationResponse moderationResponse;
3437

3538
private Activity(Builder builder) {
3639
id = builder.id;
@@ -44,6 +47,8 @@ private Activity(Builder builder) {
4447
to = builder.to;
4548
score = builder.score;
4649
extra = builder.extra;
50+
moderationTemplate = builder.moderationTemplate;
51+
moderationResponse = builder.moderationResponse;
4752
}
4853

4954
public String getID() {
@@ -97,6 +102,16 @@ public Map<String, Object> getExtra() {
97102
return extra;
98103
}
99104

105+
@JsonProperty("moderation")
106+
public ModerationResponse getModerationResponse() {
107+
return moderationResponse;
108+
}
109+
110+
@JsonProperty("moderation_template")
111+
public String getModerationTemplate() {
112+
return moderationTemplate;
113+
}
114+
100115
@Override
101116
public boolean equals(Object o) {
102117
if (this == o) return true;
@@ -154,12 +169,19 @@ public static final class Builder {
154169
private List<FeedID> to;
155170
private Double score;
156171
private Map<String, Object> extra;
172+
private String moderationTemplate;
173+
private ModerationResponse moderationResponse;
157174

158175
public Builder id(String id) {
159176
this.id = id;
160177
return this;
161178
}
162179

180+
public Builder moderationTemplate(String moderationTemplate) {
181+
this.moderationTemplate = moderationTemplate;
182+
return this;
183+
}
184+
163185
public Builder actor(String actor) {
164186
this.actor = actor;
165187
return this;
@@ -181,6 +203,12 @@ public Builder foreignID(String foreignID) {
181203
return this;
182204
}
183205

206+
@JsonProperty("moderation")
207+
public Builder setModerationResponse(ModerationResponse mod) {
208+
this.moderationResponse = mod;
209+
return this;
210+
}
211+
184212
public Builder target(String target) {
185213
this.target = target;
186214
return this;
@@ -250,6 +278,8 @@ public Builder fromActivity(Activity activity) {
250278
this.to = activity.to;
251279
this.score = activity.score;
252280
this.extra = activity.extra;
281+
this.moderationTemplate = activity.moderationTemplate;
282+
this.moderationResponse = activity.moderationResponse;
253283
return this;
254284
}
255285

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package io.getstream.core.models;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
6+
public class ModerationResponse {
7+
private String Status;
8+
private String RecommendedAction;
9+
private APIError APIError;
10+
private String OriginFeed;
11+
12+
// Default constructor
13+
public ModerationResponse() {}
14+
15+
// Constructor with parameters
16+
@JsonCreator
17+
public ModerationResponse(
18+
@JsonProperty("status") String status,
19+
@JsonProperty("recommended_action") String recommendedAction,
20+
@JsonProperty("api_error") APIError apiError,
21+
@JsonProperty("origin_feed") String originFeed) {
22+
this.Status = status;
23+
this.RecommendedAction = recommendedAction;
24+
this.APIError = apiError;
25+
this.OriginFeed = originFeed;
26+
}
27+
28+
// Getters
29+
public String getStatus() {
30+
return Status;
31+
}
32+
33+
public String getRecommendedAction() {
34+
return RecommendedAction;
35+
}
36+
37+
public APIError getAPIError() {
38+
return APIError;
39+
}
40+
41+
public String getOriginFeed() {
42+
return OriginFeed;
43+
}
44+
}

0 commit comments

Comments
 (0)