Activity Feeds v3 is in beta — try it out!

Comments

Overview

Comments support voting, ranking, threading, images, URL previews, mentions and notifications.

Adding Comments

// 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',
  ),
);

Overview of the comment model

CommentResponse

NameTypeDescriptionConstraints
attachmentsAttachment[]--
confidence_scorenumberConfidence score of the commentRequired
controversy_scorenumberControversy score of the comment-
created_atnumberWhen the comment was createdRequired
customobjectCustom data for the comment-
deleted_atnumberWhen the comment was deleted-
downvote_countintegerNumber of downvotes for this commentRequired
idstringUnique identifier for the commentRequired
latest_reactionsFeedsReactionResponse[]Recent reactions to the comment-
mentioned_usersUserResponse[]Users mentioned in the commentRequired
moderationModerationV2Response--
object_idstringID of the object this comment is associated withRequired
object_typestringType of the object this comment is associated withRequired
own_reactionsFeedsReactionResponse[]Current user's reactions to this activityRequired
parent_idstringID of parent comment for nested replies-
reaction_countintegerNumber of reactions to this commentRequired
reaction_groupsobjectGrouped reactions by type-
reply_countintegerNumber of replies to this commentRequired
scoreintegerScore of the comment based on reactionsRequired
statusstringStatus of the comment (e.g., active, deleted)Required
textstringText content of the comment-
updated_atnumberWhen the comment was last updatedRequired
upvote_countintegerNumber of upvotes for this commentRequired
userUserResponseUser who created the commentRequired

Updating Comments

// Updating a comment
final updatedComment = await feed.updateComment(
  commentId: 'comment_123',
  request: const UpdateCommentRequest(
    comment: 'Not so great',
    custom: {'edited': true},
  ),
);

Removing Comments

await feed.deleteComment(commentId: 'comment_123');

Reading Comments

You’ll also want to show/return these comments. The most important is when reading the feed.

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);

Sort options

The following sort options are supported when reading comments:

  • last: newest comment returned first
  • first: oldest comment returned first
  • top: highest score returned first - computed from upvote - downvote reaction types
  • controversial: controversial comment returned first - mixed reactions (upvote and downvote) and lots of comments
  • best: 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
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();

Comment Queryable Built-In Fields

nametypedescriptionsupported operationsexample
idstring or list of stringsThe ID of the comment$in, $eq{ id: { $in: [ 'comment_123', 'comment_456' ] } }
user_idstring or list of stringsThe ID of the user who created the comment$in, $eq{ user_id: { $eq: 'user_123' } }
object_typestring or list of stringsThe type of object being commented on$eq, $ne, $in, $nin{ object_type: { $in: [ 'activity', 'post' ] } }
object_idstring or list of stringsThe ID of the object being commented on$in, $eq{ object_id: { $eq: 'activity_123' } }
parent_idstring or list of stringsThe parent comment ID for replies$in, $eq{ parent_id: { $eq: 'comment_parent_123' } }
comment_textstringThe text content of the comment$q{ comment_text: { $q: 'search terms' } }
statusstring or list of stringsThe status of the comment$eq, $ne, $in{ status: { $in: [ 'approved', 'pending' ] } }
reply_countnumberThe number of replies to this comment$gt, $gte, $lt, $lte{ reply_count: { $gte: 5 } }
upvote_countnumberThe number of upvotes on the comment$gt, $gte, $lt, $lte{ upvote_count: { $gte: 10 } }
downvote_countnumberThe number of downvotes on the comment$gt, $gte, $lt, $lte{ downvote_count: { $lt: 5 } }
scorenumberThe overall score of the comment$gt, $gte, $lt, $lte{ score: { $gte: 0 } }
confidence_scorenumberThe confidence score of the comment$gt, $gte, $lt, $lte{ confidence_score: { $gte: 0.5 } }
controversy_scorenumberThe controversy score of the comment$gt, $gte, $lt, $lte{ controversy_score: { $lt: 0.8 } }
created_atstring, must be formatted as an RFC3339 timestampThe 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.

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
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');

Overview of the reaction model

FeedsReactionResponse
NameTypeDescriptionConstraints
activity_idstringID of the activity that was reacted toRequired
comment_idstringID of the comment that was reacted to-
created_atnumberWhen the reaction was createdRequired
customobjectCustom data for the reaction-
typestringType of reactionRequired
updated_atnumberWhen the reaction was last updatedRequired
userUserResponseUser who created the reactionRequired

Comment Threading

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();

Reading comment replies supports the same sort parameters as reading comments does.

© Getstream.io, Inc. All Rights Reserved.