// Adding a comment to an activity
let comment = try await feed.addComment(
request: .init(
id: "comment_123", // id is optional, but must be unique. will be auto-generated if not provided
comment: "So great!",
custom: ["sentiment": "positive"],
objectId: "activity_123",
objectType: "activity",
)
)
// Adding a reply to a comment
let reply = try await feed.addComment(
request: .init(
comment: "I agree!",
parentId: "comment_456"
)
)Comments
Overview
Comments support voting, ranking, threading, images, URL previews, mentions and notifications.
Adding Comments
// Adding a comment to an activity
val comment: Result<CommentData> = feed.addComment(
request = ActivityAddCommentRequest(
id = "comment_123", // id is optional, but must be unique. will be auto-generated if not provided
comment = "So great!",
custom = mapOf("sentiment" to "positive"),
activityId = "activity_123"
)
)
// Adding a reply to a comment
val reply: Result<CommentData> = feed.addComment(
request = ActivityAddCommentRequest(
comment = "I agree!",
parentId = "comment_456"
)
)// Adding a comment to an activity
await client.addComment({
id: "comment_123", // id is optional, but must be unique. will be auto-generated if not provided
comment: "So great!",
object_id: "activity_123",
object_type: "activity",
custom: {
sentiment: "positive",
},
});
// Adding a reply to a comment
await client.addComment({
comment: "I agree!",
parent_id: "comment_456",
});
// Adding a comment without triggering push notifications
await client.addComment({
comment: "Silent comment",
object_id: "activity_123",
object_type: "activity",
skip_push: true,
});// Adding a comment to an activity
final comment = await feed.addComment(
request: const ActivityAddCommentRequest(
id: 'comment_123', // id is optional, but must be unique. will be auto-generated if not provided
comment: 'So great!',
custom: {'sentiment': 'positive'},
activityId: 'activity_123',
activityType: 'activity',
),
);
// Adding a reply to a comment
final reply = await feed.addComment(
request: const ActivityAddCommentRequest(
comment: 'I agree!',
parentId: 'comment_456',
),
);// Adding a comment to an activity
await serverClient.feeds.addComment({
id: "comment_123", // id is optional, but must be unique. will be auto-generated if not provided
comment: "So great!",
object_id: "activity_123",
object_type: "activity",
user_id: "<user_id>",
custom: {
sentiment: "positive",
},
});
// Adding a reply to a comment
await serverClient.feeds.addComment({
comment: "I agree!",
parent_id: "comment_456",
user_id: "<user_id>",
});
// Adding a comment without triggering push notifications
await serverClient.feeds.addComment({
comment: "Silent comment",
object_id: "activity_123",
object_type: "activity",
user_id: "<user_id>",
skip_push: true,
});// Get feed instance
feed := client.Feeds().Feed("user", "john")
feedResponse, err := feed.GetOrCreate(context.Background(), &getstream.GetOrCreateFeedRequest{
UserID: getstream.PtrTo("john"),
})
activity := feedResponse.Data.Activities[0]
activityID := activity.ID
commentID := "6b6dd9df-13b0-4b47-8d73-a45a00d04fa7"
// folderID := "11e7d97a-e461-47f0-8d24-cd8a86168a60"
// Adding a comment to an activity
_, err = client.Feeds().AddComment(context.Background(), &getstream.AddCommentRequest{
ID: getstream.PtrTo("comment_123"), // ID is optional, but must be unique. will be auto-generated if not provided
Comment: "So great!",
ObjectID: activityID,
ObjectType: "activity",
UserID: getstream.PtrTo("john"),
Custom: map[string]any{
"sentiment": "positive",
},
})
if err != nil {
log.Fatal("Error adding comment:", err)
}
// Adding a reply to a comment
_, err = client.Feeds().AddComment(context.Background(), &getstream.AddCommentRequest{
Comment: "I agree!",
ParentID: getstream.PtrTo(commentID),
UserID: getstream.PtrTo("john"),
})
if err != nil {
log.Fatal("Error adding reply:", err)
}
// Adding a comment without triggering push notifications
_, err = client.Feeds().AddComment(context.Background(), &getstream.AddCommentRequest{
Comment: "Silent comment",
ObjectID: activityID,
ObjectType: "activity",
UserID: getstream.PtrTo("john"),
SkipPush: getstream.PtrTo(true),
})
if err != nil {
log.Fatal("Error adding silent comment:", err)
}AddCommentRequest commentRequest =
AddCommentRequest.builder()
.id("comment_123") // id is optional, but must be unique. will be auto-generated if not provided
.comment("This is a test comment from Java SDK")
.objectID(activityId)
.objectType("activity")
.userID(testUserId)
.build();
AddCommentResponse response = feeds.addComment(commentRequest).execute().getData();// Adding a comment to an activity
$response = $feedsClient->addComment(
new GeneratedModels\AddCommentRequest(
id: 'comment_123', // id is optional, but must be unique. will be auto-generated if not provided
comment: 'So great!',
objectID: 'activity_123',
objectType: 'activity',
userID: 'user123',
custom: (object)[
'sentiment' => 'positive'
]
)
);
// Adding a reply to a comment
$response = $feedsClient->addComment(
new GeneratedModels\AddCommentRequest(
comment: 'I agree!',
parentID: 'comment_456',
userID: 'user123'
)
);
// Adding a comment without triggering push notifications
$response = $feedsClient->addComment(
new GeneratedModels\AddCommentRequest(
comment: 'Silent comment',
objectID: 'activity_123',
objectType: 'activity',
userID: 'user123',
skipPush: true
)
);var response = await _feedsV3Client.AddCommentAsync(
new AddCommentRequest
{
ID = "comment_123", // id is optional, but must be unique. will be auto-generated if not provided
Comment = "This is a test comment from .NET SDK",
ObjectID = activityId,
ObjectType = "activity",
UserID = _testUserId
}
);response = self.client.feeds.add_comment(
id="comment_123", # id is optional, but must be unique. will be auto-generated if not provided
comment="This is a test comment from Python SDK",
object_id=activity_id,
object_type="activity",
user_id=self.test_user_id,
)# Adding a comment to an activity
comment_request = GetStream::Generated::Models::AddCommentRequest.new(
id: 'comment_123', # id is optional, but must be unique. will be auto-generated if not provided
comment: 'So great!',
object_id: 'activity_123',
object_type: 'activity',
user_id: 'user123',
custom: {
sentiment: 'positive'
}
)
response = client.feeds.add_comment(comment_request)
# Adding a reply to a comment
reply_request = GetStream::Generated::Models::AddCommentRequest.new(
comment: 'I agree!',
parent_id: 'comment_456',
user_id: 'user123'
)
response = client.feeds.add_comment(reply_request)
# Adding a comment without triggering push notifications
silent_comment_request = GetStream::Generated::Models::AddCommentRequest.new(
comment: 'Silent comment',
object_id: 'activity_123',
object_type: 'activity',
user_id: 'user123',
skip_push: true
)
response = client.feeds.add_comment(silent_comment_request)Overview of the comment model
CommentResponse
| Name | Type | Description | Constraints |
|---|---|---|---|
attachments | Attachment[] | - | - |
confidence_score | number | Confidence score of the comment | Required |
controversy_score | number | Controversy score of the comment | - |
created_at | number | When the comment was created | Required |
custom | object | Custom data for the comment | - |
deleted_at | number | When the comment was deleted | - |
downvote_count | integer | Number of downvotes for this comment | Required |
id | string | Unique identifier for the comment | Required |
latest_reactions | FeedsReactionResponse[] | Recent reactions to the comment | - |
mentioned_users | UserResponse[] | Users mentioned in the comment | Required |
moderation | ModerationV2Response | - | - |
object_id | string | ID of the object this comment is associated with | Required |
object_type | string | Type of the object this comment is associated with | Required |
own_reactions | FeedsReactionResponse[] | Current user's reactions to this activity | Required |
parent_id | string | ID of parent comment for nested replies | - |
reaction_count | integer | Number of reactions to this comment | Required |
reaction_groups | object | Grouped reactions by type | - |
reply_count | integer | Number of replies to this comment | Required |
score | integer | Score of the comment based on reactions | Required |
status | string | Status of the comment (e.g., active, deleted) | Required |
text | string | Text content of the comment | - |
updated_at | number | When the comment was last updated | Required |
upvote_count | integer | Number of upvotes for this comment | Required |
user | UserResponse | User who created the comment | Required |
Updating Comments
try await feed.updateComment(
commentId: "comment_123",
request: .init(
comment: "Not so great",
custom: ["edited": true]
)
)feed.updateComment(
commentId = "comment_123",
request = UpdateCommentRequest(
comment = "Not so great",
custom = mapOf("edited" to true)
)
)// Update a comment
await client.updateComment({
id: "comment_123",
comment: "Updated comment",
custom: {
edited: true,
},
});// Updating a comment
final updatedComment = await feed.updateComment(
commentId: 'comment_123',
request: const UpdateCommentRequest(
comment: 'Not so great',
custom: {'edited': true},
),
);// Update a comment
await client.feeds.updateComment({
id: "comment_123",
comment: "Updated comment",
custom: {
edited: true,
},
});_, err = client.Feeds().UpdateComment(context.Background(), commentID, &getstream.UpdateCommentRequest{
Comment: getstream.PtrTo("Updated comment"),
Custom: map[string]any{
"edited": true,
},
})
if err != nil {
log.Fatal("Error updating comment:", err)
}AddCommentRequest commentRequest =
AddCommentRequest.builder()
.comment("This is a test comment from Java SDK")
.objectID(activityId)
.objectType("activity")
.userID(testUserId)
.build();
AddCommentResponse response = feeds.addComment(commentRequest).execute().getData();// Update a comment
$response = $feedsClient->updateComment(
'comment_123',
new GeneratedModels\UpdateCommentRequest(
comment: 'Updated comment',
custom: (object)[
'edited' => true
]
)
);var response = await _feedsV3Client.AddCommentAsync(
new AddCommentRequest
{
Comment = "This is a test comment from .NET SDK",
ObjectID = activityId,
ObjectType = "activity",
UserID = _testUserId
}
);response = self.client.feeds.add_comment(
comment="This is a test comment from Python SDK",
object_id=activity_id,
object_type="activity",
user_id=self.test_user_id,
)Removing Comments
try await feed.deleteComment(
commentId: "comment_123"
)feed.deleteComment(commentId = "comment_123")client.deleteComment({
id: "comment_123",
});await feed.deleteComment(commentId: 'comment_123');client.feeds.deleteComment({
id: "comment_123",
});_, err = client.Feeds().DeleteComment(context.Background(), commentID, &getstream.DeleteCommentRequest{})
if err != nil {
log.Fatal("Error deleting comment:", err)
}UpdateCommentRequest updateRequest =
UpdateCommentRequest.builder().comment("Updated comment text from Java SDK").build();
UpdateCommentResponse response =
feeds.updateComment(commentId, updateRequest).execute().getData();// Delete a comment (soft delete)
$response = $feedsClient->deleteComment('comment_123', false);var response = await _feedsV3Client.UpdateCommentAsync(
commentId,
new UpdateCommentRequest
{
Comment = "Updated comment text from .NET SDK"
}
);response = self.client.feeds.update_comment(
comment_id, comment="Updated comment text from Python SDK"
)# Update a comment
update_request = GetStream::Generated::Models::UpdateCommentRequest.new(
comment: 'Updated comment text from Ruby SDK',
custom: {
edited: true
}
)
response = client.feeds.update_comment(comment_id, update_request)Reading Comments
You’ll also want to show/return these comments. The most important is when reading the feed.
try await feed.getOrCreate()
print(feed.state.activities[0].comments)
// or
let activity = client.activity(
for: "activity_123",
in: FeedId(group: "user", id: "john")
)
try await activity.get()
print(activity.state.comments)feed.getOrCreate()
feed.state.activities.collect { it.first().comments }
// or
val activity = client.activity(
activityId = "activity_123",
fid = FeedId(group = "user", id = "john")
)
activity.get()
activity.state.commentsawait feed.getOrCreate();
const activity = feed.state.getLatestValue().activities?.[0]!;
// Supported values for sort: first, last, top, controversial, best
// Loads the activity comments (first or next page) and stores them in feed state
await feed.loadNextPageActivityComments(activity, { sort: 'best' });
// To read comments without storing them in feed state
const response = client.getComments({
object_type: "activity",
object_id: "123",
limit: 10,
sort: "best",
});await feed.getOrCreate();
print(feed.state.activities[0].comments);
// or
final activity = client.activity(
fid: const FeedId(group: 'user', id: 'john'),
activityId: 'activity_123',
);
await activity.get();
print(activity.state.comments);const response = feed.getOrCreate({
user_id: "<user id>",
});
console.log(response.activities[0].comments);
// Or using the getComments endpoint
const comments = await client.feeds.getComments({
object_type: "activity",
object_id: "123",
limit: 10,
sort: "best",
});feed := client.Feeds().Feed("user", "john")
feedResponse, err := feed.GetOrCreate(context.Background(), &getstream.GetOrCreateFeedRequest{
UserID: getstream.PtrTo("john"),
})
if err != nil {
log.Fatal(err)
}
// Access comments from the first activity
activity := feedResponse.Data.Activities[0]
comments := activity.Comments
// Or using the getComments endpoint
commentsResponse, err := client.Feeds().GetComments(context.Background(), &getstream.GetCommentsRequest{
ObjectType: "activity",
ObjectID: "123",
Limit: getstream.PtrTo(10),
Sort: getstream.PtrTo("best"),
})
if err != nil {
log.Fatal(err)
}
commentsFromEndpoint := commentsResponse.Data.CommentsDeleteCommentRequest deleteRequest = DeleteCommentRequest.builder().build();
DeleteCommentResponse response =
feeds.deleteComment(commentId, deleteRequest).execute().getData();// Get comments for an activity
// activity id, object type, depth, sort, replies limit, limit, prev, next
$response = $feedsClient->getComments('activity_123', 'activity', 3, 'best', 10, 10, '', '');
echo json_encode($response->getData());
// Access comments from feed response
$feedResponse = $feedsClient->feed('user', 'eric')->getOrCreateFeed(
new GeneratedModels\GetOrCreateFeedRequest(
userID: 'eric'
)
);
$comments = $feedResponse->getData()->activities[0]->comments;var response = await _feedsV3Client.DeleteCommentAsync(
commentId,
new { user_id = _testUserId }
);response = self.client.feeds.delete_comment(
comment_id, hard_delete=False
) # soft delete# Delete a comment (soft delete)
response = client.feeds.delete_comment(comment_id, hard_delete: false)Sort options
The following sort options are supported when reading comments:
last: newest comment returned firstfirst: oldest comment returned firsttop: highest score returned first - computed fromupvote-downvotereaction typescontroversial: controversial comment returned first - mixed reactions (upvoteanddownvote) and lots of commentsbest: highest Wilson score returned first - Wilson score balances reaction score (upvote-downvote) with number of reactions (a comment with lower reaction score but more sum reactions is returned before a comment with higher score, but few sum reactions)
Search for Comments
You can also query the comments, the following examples show
- how to search across all comments by text
- query all comments of a given user
// Search in comment texts
let list1 = client.commentList(
for: .init(
filter: .query(.commentText, "oat")
)
)
let comments1 = try await list1.get()
// Comments from an user
let list2 = client.commentList(
for: .init(
filter: .equal(.userId, "jane")
)
)
let comments2 = try await list2.get()// Search in comment texts
val list1 = client.commentList(
query = CommentsQuery(
filter = CommentsFilterField.commentText.query("oat")
)
)
val comments1: Result<List<CommentData>> = list1.get()
// Comments from a user
val list2 = client.commentList(
query = CommentsQuery(
filter = CommentsFilterField.userId.equal("jane")
)
)
val comments2: Result<List<CommentData>> = list2.get()// Search in comment texts
await client.queryComments({
filter: { comment_text: { $q: "oat" } },
});
// Comments of a user
await client.queryComments({
filter: {
user_id: jane.id,
},
limit: 20,
});// Search in comment texts
final list1 = client.commentList(
const CommentsQuery(
filter: Filter.query(CommentsFilterField.commentText, 'oat'),
),
);
final comments1 = await list1.get();
// Comments from an user
final list2 = client.commentList(
const CommentsQuery(
filter: Filter.equal(CommentsFilterField.userId, 'jane'),
),
);
final comments2 = await list2.get();// Search in comment texts
await client.feeds.queryComments({
filter: { comment_text: { $q: "oat" } },
});
// Comments of a user
await client.feeds.queryComments({
filter: {
user_id: jane.id,
},
limit: 20,
});// Search in comment texts
_, err = client.Feeds().QueryComments(context.Background(), &getstream.QueryCommentsRequest{
Filter: map[string]any{
"comment_text": map[string]any{
"$q": "oat",
},
},
})
if err != nil {
log.Printf("Error searching comments: %v", err)
}
// Comments by user
_, err = client.Feeds().QueryComments(context.Background(), &getstream.QueryCommentsRequest{
Filter: map[string]any{
"user_id": "jane",
},
Limit: getstream.PtrTo(20),
})
if err != nil {
log.Printf("Error querying user comments: %v", err)
}Map<String, Object> filter = new HashMap<>();
filter.put("object_id", activityId);
QueryCommentsRequest queryRequest =
QueryCommentsRequest.builder().filter(filter).limit(10).build();
QueryCommentsResponse response = feeds.queryComments(queryRequest).execute().getData();// Search in comment texts
$response = $feedsClient->queryComments(
new GeneratedModels\QueryCommentsRequest(
filter: (object)['comment_text' => ['$q' => 'oat']],
limit: 10
)
);
// Comments of a user
$response = $feedsClient->queryComments(
new GeneratedModels\QueryCommentsRequest(
filter: (object)['user_id' => 'jane'],
limit: 20
)
);
// Query comments for an activity
$response = $feedsClient->queryComments(
new GeneratedModels\QueryCommentsRequest(
filter: (object)['object_id' => 'activity_123'],
limit: 10
)
);var response = await _feedsV3Client.QueryCommentsAsync(
new QueryCommentsRequest
{
Filter = new Dictionary<string, object> { ["object_id"] = activityId },
Limit = 10
}
);response = self.client.feeds.query_comments(
filter={"object_id": activity_id}, limit=10
)# Query comments for an activity
query_request = GetStream::Generated::Models::QueryCommentsRequest.new(
filter: {
object_id: activity_id
},
limit: 10
)
response = client.feeds.query_comments(query_request)
# Search in comment texts
search_request = GetStream::Generated::Models::QueryCommentsRequest.new(
filter: {
comment_text: { '$q' => 'oat' }
}
)
response = client.feeds.query_comments(search_request)
# Comments from a specific user
user_comments_request = GetStream::Generated::Models::QueryCommentsRequest.new(
filter: {
user_id: 'user123'
},
limit: 20
)
response = client.feeds.query_comments(user_comments_request)Comment Queryable Built-In Fields
| name | type | description | supported operations | example |
|---|---|---|---|---|
id | string or list of strings | The ID of the comment | $in, $eq | { id: { $in: [ 'comment_123', 'comment_456' ] } } |
user_id | string or list of strings | The ID of the user who created the comment | $in, $eq | { user_id: { $eq: 'user_123' } } |
object_type | string or list of strings | The type of object being commented on | $eq, $ne, $in, $nin | { object_type: { $in: [ 'activity', 'post' ] } } |
object_id | string or list of strings | The ID of the object being commented on | $in, $eq | { object_id: { $eq: 'activity_123' } } |
parent_id | string or list of strings | The parent comment ID for replies | $in, $eq | { parent_id: { $eq: 'comment_parent_123' } } |
comment_text | string | The text content of the comment | $q | { comment_text: { $q: 'search terms' } } |
status | string or list of strings | The status of the comment | $eq, $ne, $in | { status: { $in: [ 'approved', 'pending' ] } } |
reply_count | number | The number of replies to this comment | $gt, $gte, $lt, $lte | { reply_count: { $gte: 5 } } |
upvote_count | number | The number of upvotes on the comment | $gt, $gte, $lt, $lte | { upvote_count: { $gte: 10 } } |
downvote_count | number | The number of downvotes on the comment | $gt, $gte, $lt, $lte | { downvote_count: { $lt: 5 } } |
score | number | The overall score of the comment | $gt, $gte, $lt, $lte | { score: { $gte: 0 } } |
confidence_score | number | The confidence score of the comment | $gt, $gte, $lt, $lte | { confidence_score: { $gte: 0.5 } } |
controversy_score | number | The controversy score of the comment | $gt, $gte, $lt, $lte | { controversy_score: { $lt: 0.8 } } |
created_at | string, must be formatted as an RFC3339 timestamp | The time the comment was created | $eq, $gt, $gte, $lt, $lte | { created_at: { $gte: '2023-12-04T09:30:20.45Z' } } |
Comment sort options
All fields support 1 and -1 directions.
created_atscore: same astopsort optionconfidence_score- same asbestsort optioncontroversy_score- same ascontroversialsort optionupvote_countdownvote_count
Comment Reactions
When adding reactions and the enforce_unique flag is set to true, the existing reaction of a user will be overridden with the new reaction. Use this flag if you want to ensure users have a single reaction per each comment/activity. The default value is false, in which case users can have multiple reactions.
// Add a reaction to a comment
try await feed.addCommentReaction(
commentId: "comment_123",
request: .init(type: "like")
)
// Remove a reaction from a comment
try await feed.deleteCommentReaction(
commentId: "comment_123",
type: "like"
)// Add a reaction to a comment
feed.addCommentReaction(
commentId = "comment_123",
request = AddCommentReactionRequest(
type = "like",
// Optionally override existing reaction
enforceUnique = true
)
)
// Remove a reaction from a comment
feed.deleteCommentReaction(
commentId = "comment_123",
type = "like"
)// Add a reaction to a comment
const response = await client.addCommentReaction({
id: "comment_123",
type: "like",
// Optionally override existing reaction
enforce_unique: true,
});
await client.deleteCommentReaction({
id: "comment_123",
type: "like",
});// Add a reaction to a comment
await feed.addCommentReaction(
commentId: 'comment_123',
request: const AddCommentReactionRequest(
type: 'like',
// Optionally override existing reaction
enforceUnique: true,
),
);
// Remove a reaction from a comment
await feed.deleteCommentReaction(commentId: 'comment_123', type: 'like');// Add a reaction to a comment
const response = await client.feeds.addCommentReaction({
id: "comment_123",
type: "like",
user_id: "<user id>",
// Optionally override existing reaction
enforce_unique: true,
});
await client.feeds.deleteCommentReaction({
id: "comment_123",
type: "like",
user_id: "<user id>",
});// Add comment reaction
_, err = client.Feeds().AddCommentReaction(context.Background(), commentID, &getstream.AddCommentReactionRequest{
Type: "like",
UserID: getstream.PtrTo("john"),
})
if err != nil {
log.Fatal("Error adding comment reaction:", err)
}
// Delete comment reaction
_, err = client.Feeds().DeleteCommentReaction(context.Background(), commentID, "like", &getstream.DeleteCommentReactionRequest{
UserID: getstream.PtrTo("john"),
})
if err != nil {
log.Fatal("Error deleting comment reaction:", err)
}Map<String, Object> filter = new HashMap<>();
filter.put("object_id", activityId);
QueryCommentsRequest queryRequest =
QueryCommentsRequest.builder().filter(filter).limit(10).build();
QueryCommentsResponse response = feeds.queryComments(queryRequest).execute().getData();// Add a reaction to a comment
$response = $feedsClient->addCommentReaction(
$response->getData()->comment->id,
new GeneratedModels\AddCommentReactionRequest(
type: 'like',
userID: 'user123',
// Optionally override existing reaction
enforceUnique: true
)
);
// Remove a reaction from a comment
$response = $feedsClient->deleteCommentReaction(
$response->getData()->comment->id,
'like',
userID: 'user123'
);
var response = await _feedsV3Client.QueryCommentsAsync(
new QueryCommentsRequest
{
Filter = new Dictionary<string, object> { ["object_id"] = activityId },
Limit = 10
}
);response = self.client.feeds.query_comments(
filter={"object_id": activity_id}, limit=10
)# Query comments for an activity
query_request = GetStream::Generated::Models::QueryCommentsRequest.new(
filter: {
object_id: activity_id
},
limit: 10
)
response = client.feeds.query_comments(query_request)
# Search in comment texts
search_request = GetStream::Generated::Models::QueryCommentsRequest.new(
filter: {
comment_text: { '$q' => 'oat' }
}
)
response = client.feeds.query_comments(search_request)
# Comments from a specific user
user_comments_request = GetStream::Generated::Models::QueryCommentsRequest.new(
filter: {
user_id: 'user123'
},
limit: 20
)
response = client.feeds.query_comments(user_comments_request)Overview of the reaction model
FeedsReactionResponse
| Name | Type | Description | Constraints |
|---|---|---|---|
activity_id | string | ID of the activity that was reacted to | Required |
comment_id | string | ID of the comment that was reacted to | - |
created_at | number | When the reaction was created | Required |
custom | object | Custom data for the reaction | - |
type | string | Type of reaction | Required |
updated_at | number | When the reaction was last updated | Required |
user | UserResponse | User who created the reaction | Required |
Comment Threading
let commentList = client.activityCommentList(
for: .init(
objectId: "activity_123",
objectType: "activity",
depth: 3,
limit: 20
)
)
let comments = try await commentList.get()
// Get replies of a specific parent comment
let replyList = client.commentReplyList(
for: .init(
commentId: "parent_123"
)
)
let replies = try await replyList.get()val commentList = client.activityCommentList(
query = ActivityCommentsQuery(
objectId = "activity_123",
objectType = "activity",
depth = 3,
limit = 20
)
)
val comments: Result<List<ThreadedCommentData>> = commentList.get()
// Get replies of a specific parent comment
val replyList = client.commentReplyList(
query = CommentRepliesQuery(
commentId = "parent_123"
)
)
val replies: Result<List<ThreadedCommentData>> = replyList.get()await feed.getOrCreate();
// To store comments in feed state you can use the loadNextPageActivityComments and loadNextPageCommentReplies
const activity = feed.state.getLatestValue().activities?.[0]!;
await feed.loadNextPageActivityComments(activity, { limit: 20 });
const commentState =
feed.state.getLatestValue()?.comments_by_entity_id[activity.id];
const parentComment = commentState?.comments?.[0]!;
const firstPageOfReplies =
feed.state.getLatestValue()?.comments_by_entity_id[parentComment?.id];
// Load next page of replies (or first, if replies aren't yet initialized)
feed.loadNextPageCommentReplies(parentComment);
// To read comments without storing them in state use getComments and getCommentReplies
const response = client.getComments({
object_id: 'activity_123',
object_type: 'activity',
// Depth of the threaded comments
depth: 3,
limit: 20,
});
// Get replies of a specific parent comment
const response = client.getCommentReplies({
id: '<parent id>',
});final commentList = client.activityCommentList(
const ActivityCommentsQuery(
objectId: 'activity_123',
objectType: 'activity',
depth: 3,
limit: 20,
),
);
final comments = await commentList.get();
// Get replies of a specific parent comment
final replyList = client.commentReplyList(
const CommentRepliesQuery(commentId: 'parent_123'),
);
final replies = await replyList.get();const response = client.feeds.getComments({
object_id: "activity_123",
object_type: "activity",
// Depth of the threaded comments
depth: 3,
limit: 20,
});
// Get replies of a specific parent comment
const response = client.feeds.getCommentReplies({
id: "<parent id>",
});// Get comments for an activity
_, err = client.Feeds().GetComments(context.Background(), &getstream.GetCommentsRequest{
ObjectID: "activity_123",
ObjectType: "activity",
// Depth of the threaded comments
Depth: getstream.PtrTo(3),
Limit: getstream.PtrTo(20),
})
if err != nil {
log.Fatal("Error getting comments:", err)
}
// Get replies of a specific parent comment
_, err = client.Feeds().GetCommentReplies(context.Background(), parentID, &getstream.GetCommentRepliesRequest{})
if err != nil {
log.Fatal("Error getting comment replies:", err)
}DeleteCommentRequest deleteRequest = DeleteCommentRequest.builder().build();
DeleteCommentResponse response =
feeds.deleteComment(commentId, deleteRequest).execute().getData();// Get comments for an activity with threading
// activity id, object type, depth, sort, replies limit, limit, prev, next
$response = $feedsClient->getComments('activity_123', 'activity', 3, 'best', 20, 20, '', '');
// Get replies of a specific parent comment
// parent id, depth, sort, replies limit, limit, prev, next
$response = $feedsClient->getCommentReplies('parent_123', 3, 'best', 20, 20, '', '');var response = await _feedsV3Client.DeleteCommentAsync(
commentId,
new { user_id = _testUserId }
);response = self.client.feeds.delete_comment(
comment_id, hard_delete=False
) # soft delete# Delete a comment (soft delete)
response = client.feeds.delete_comment(comment_id, hard_delete: false)Reading comment replies supports the same sort parameters as reading comments does.
Restricting comment replies
Set who can add comments
When creating an activity it’s possible to set who can add comments. Possible options:
- Everyone (this is the default setting)
- Only people I follow
- Nobody
The activity author is always allowed to add comments regardless of the reply settings.
const response = await feed.addActivity({
type: "post",
text: "apple stock will go up",
restrict_replies: "people_i_follow", // Options: "everyone", "people_i_follow", "nobody"
});const response = await client.feeds.addActivity({
feeds: ["user:1"],
type: "post",
text: "apple stock will go up",
user_id: "<user id>",
restrict_replies: "people_i_follow", // Options: "everyone", "people_i_follow", "nobody"
});feedsClient := client.Feeds()
response, err := feedsClient.AddActivity(context.Background(), &getstream.AddActivityRequest{
Type: "post",
Feeds: []string{"user:john"},
Text: getstream.PtrTo("apple stock will go up"),
UserID: getstream.PtrTo("john"),
RestrictReplies: getstream.PtrTo("people_i_follow"), // Options: "everyone", "people_i_follow", "nobody"
})
if err != nil {
log.Fatal("Error adding activity:", err)
}AddActivityRequest activity =
AddActivityRequest.builder()
.type("post")
.feeds(List.of(testFeedId))
.text("apple stock will go up")
.userID(testUserId)
.restrictReplies(RestrictReplies.PEOPLE_I_FOLLOW) // Options: EVERYONE, PEOPLE_I_FOLLOW, NOBODY
.build();
AddActivityResponse response = feeds.addActivity(activity).execute().getData();$activity = new GeneratedModels\AddActivityRequest(
type: 'post',
feeds: ['user:1'],
text: 'apple stock will go up',
userID: '<user id>',
restrictReplies: 'people_i_follow' // Options: 'everyone', 'people_i_follow', 'nobody'
);
$response = $feedsClient->addActivity($activity);var activity = new AddActivityRequest
{
Type = "post",
Text = "apple stock will go up",
UserID = _testUserId,
Feeds = new List<string> { $"user:{_testFeedId}" },
RestrictReplies = "people_i_follow" // Options: "everyone", "people_i_follow", "nobody"
};
var response = await _feedsV3Client.AddActivityAsync(activity);response = self.client.feeds.add_activity(
type="post",
feeds=[self.test_feed.get_feed_identifier()],
text="apple stock will go up",
user_id=self.test_user_id,
restrict_replies="people_i_follow", # Options: "everyone", "people_i_follow", "nobody"
)activity_request = GetStream::Generated::Models::AddActivityRequest.new(
type: 'post',
text: 'apple stock will go up',
user_id: 'user123',
feeds: ['user:user123'],
restrict_replies: 'people_i_follow' # Options: 'everyone', 'people_i_follow', 'nobody'
)
response = client.feeds.add_activity(activity_request)Show/hide comment input
If a user isn’t allowed to add comments, it’s a good idea to hide the comment input.
When everyone/nobody can comment this is straightforward. However if only people the activity author follows can comment, we have to check if there are any feeds owned by the current user that is followed by the activity author, the code snippet below shows how to check this:
const activity: ActivityResponse = /* fetch a single activity or read a feed */;
// Lists follow relationships where
// - target feed is owned by current user
// - source feed is owned by activity author
const feed = client.feed(
activity.current_feed.group_id,
activity.current_feed.id,
);
console.log(feed.currentState.own_followings);own_followings is only set when reading a feed/activity from client-side, for server-side requests it will be empty.
- When fetching a single activity,
own_followingsis set by default - When reading a feed, you have to explicitly enable fetching
own_followings:
feed.getOrCreate({ enrichment_options: { enrich_own_followings: true } });