Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
85 changes: 85 additions & 0 deletions MIGRATION_v10_to_v11.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Migrating from v10 to v11

v11 regenerates the client from protocol tag `openapi-v239.93.2` (chat **v239.93.2**, FLU-1105). **HTTP JSON is unchanged.** Most request and response fields stay `String`. The compile breaks are the ones below.

## Installation

```xml
<dependency>
<groupId>io.getstream</groupId>
<artifactId>stream-sdk-java</artifactId>
<version>11.0.0</version>
</dependency>
```

```groovy
implementation 'io.getstream:stream-sdk-java:11.0.0'
```

## Named enum constants

New types such as `PushLevel`, `VotingVisibility`, `BlocklistBehavior`, and `ChannelModerationBehavior` are classes of `public static final String` constants. Fields that use them are still `String`, so existing string assignments keep compiling.

```java
request.setPushLevel(PushLevel.ALL);
request.setAutomodBehavior(ChannelModerationBehavior.FLAG);
```

## Own capabilities

`OwnCapability`, `ChannelOwnCapability`, and `FeedOwnCapability` are no longer wrapper objects. They are `String` constants, and the list fields are `List<String>`.

```java
// v10
List<OwnCapability> caps = channel.getOwnCapabilities();
if (caps.contains(OwnCapability.JOIN_CALL)) { }

// v11
List<String> caps = channel.getOwnCapabilities();
if (caps.contains(OwnCapability.JOIN_CALL)) { }
```

The same change applies to channel and feed capability lists, and to call responses that returned `List<OwnCapability>` (`GetCallResponse`, `GetOrCreateCallResponse`, `UpdateCallResponse`, `QueryCallParticipantsResponse`, `CallStateResponseFields`, `UpdatedCallPermissionsEvent`).

`OwnCapability.JOIN_CALL.toString()` is no longer valid. The constant is already a `String`.

## Campaigns

`updateCampaign` returns `UpdateCampaignResponse`. `stopCampaign` returns `StopCampaignResponse`. The campaign itself is nested.

```java
// v10
CampaignResponse campaign = client.chat().updateCampaign(id, request).execute().getData();

// v11
CampaignResponse campaign =
client.chat().updateCampaign(id, request).execute().getData().getCampaign();
```

`stopCampaign` is the same shape: `StopCampaignResponse.getCampaign()`.

## Feeds retention policies

`GetFeedsRetentionPolicyResponse.getPolicies()` is `List<FeedsRetentionPolicy>`. `SetFeedsRetentionPolicyResponse.getPolicy()` is `FeedsRetentionPolicy`. Both were `RetentionPolicy`.

## Moderation check response

`CheckResponse` no longer has `intentMatchedTopic`, `intentScore`, `intentScoreThreshold`, or `intentWouldFire`. Scores are `List<IntentScoreResponse> getIntentScores()`.

## Reaction timestamps

`EnrichedReaction.getCreatedAt()` and `getUpdatedAt()` are `String`. They were `Time`. `Time` is removed.

## Removed types

These classes are gone:

- `Time`
- `IntentBufferedItem`, `IntentDetectedEvent`
- `VideoEndCallRequestPayload`, `VideoKickUserRequestPayload`

`moderation.intent_detected` is no longer a known webhook type. It arrives as `UnknownEvent`.

## HTTP JSON

The server still sends and accepts the same strings (`"join-call"`, `"all"`, `"flag"`). Stay on **10.5.0** until you are ready to fix the compile errors above.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ Maven (`pom.xml`):
</dependency>
```

## Upgrading from v10?

See [v10 → v11](MIGRATION_v10_to_v11.md). HTTP JSON is unchanged. Capability lists, campaign responses, and a few types changed.

## Migrating from stream-chat-java?

If you are currently using [`stream-chat-java`](https://github.com/GetStream/stream-chat-java), we have a detailed migration guide with side-by-side code examples for common Chat use cases. See the [Migration Guide](docs/migration-from-stream-chat-java/README.md).
Expand Down
63 changes: 59 additions & 4 deletions src/main/java/io/getstream/Webhook.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import io.getstream.models.AsyncBulkImageModerationEvent;
import io.getstream.models.AsyncExportChannelsEvent;
import io.getstream.models.AsyncExportErrorEvent;
import io.getstream.models.AsyncExportLabelResultsEvent;
import io.getstream.models.AsyncExportModerationLogsEvent;
import io.getstream.models.AsyncExportReviewQueueEvent;
import io.getstream.models.AsyncExportUsersEvent;
Expand Down Expand Up @@ -67,6 +68,7 @@
import io.getstream.models.CallRecordingStoppedEvent;
import io.getstream.models.CallRejectedEvent;
import io.getstream.models.CallRingEvent;
import io.getstream.models.CallRingSettledEvent;
import io.getstream.models.CallRtmpBroadcastFailedEvent;
import io.getstream.models.CallRtmpBroadcastStartedEvent;
import io.getstream.models.CallRtmpBroadcastStoppedEvent;
Expand All @@ -89,9 +91,11 @@
import io.getstream.models.ChannelBatchStartedEvent;
import io.getstream.models.ChannelCreatedEvent;
import io.getstream.models.ChannelDeletedEvent;
import io.getstream.models.ChannelForkedEvent;
import io.getstream.models.ChannelFrozenEvent;
import io.getstream.models.ChannelHiddenEvent;
import io.getstream.models.ChannelMutedEvent;
import io.getstream.models.ChannelRewoundEvent;
import io.getstream.models.ChannelTruncatedEvent;
import io.getstream.models.ChannelUnFrozenEvent;
import io.getstream.models.ChannelUnmutedEvent;
Expand All @@ -100,6 +104,7 @@
import io.getstream.models.ClosedCaptionEvent;
import io.getstream.models.CommentAddedEvent;
import io.getstream.models.CommentDeletedEvent;
import io.getstream.models.CommentFeedbackEvent;
import io.getstream.models.CommentReactionAddedEvent;
import io.getstream.models.CommentReactionDeletedEvent;
import io.getstream.models.CommentReactionUpdatedEvent;
Expand All @@ -123,7 +128,6 @@
import io.getstream.models.IngressErrorEvent;
import io.getstream.models.IngressStartedEvent;
import io.getstream.models.IngressStoppedEvent;
import io.getstream.models.IntentDetectedEvent;
import io.getstream.models.KickedUserEvent;
import io.getstream.models.MaxStreakChangedEvent;
import io.getstream.models.MemberAddedEvent;
Expand All @@ -149,6 +153,12 @@
import io.getstream.models.NotificationThreadMessageNewEvent;
import io.getstream.models.PendingMessageEvent;
import io.getstream.models.PermissionRequestEvent;
import io.getstream.models.PollClosedEvent;
import io.getstream.models.PollDeletedEvent;
import io.getstream.models.PollUpdatedEvent;
import io.getstream.models.PollVoteCastedEvent;
import io.getstream.models.PollVoteChangedEvent;
import io.getstream.models.PollVoteRemovedEvent;
import io.getstream.models.ReactionDeletedEvent;
import io.getstream.models.ReactionNewEvent;
import io.getstream.models.ReactionUpdatedEvent;
Expand All @@ -158,11 +168,14 @@
import io.getstream.models.ReminderUpdatedEvent;
import io.getstream.models.ReviewQueueItemNewEvent;
import io.getstream.models.ReviewQueueItemUpdatedEvent;
import io.getstream.models.ScheduledMessageFailedEvent;
import io.getstream.models.ScheduledMessageSentEvent;
import io.getstream.models.StoriesFeedUpdatedEvent;
import io.getstream.models.ThreadUpdatedEvent;
import io.getstream.models.UnblockedUserEvent;
import io.getstream.models.UpdatedCallPermissionsEvent;
import io.getstream.models.UserBannedEvent;
import io.getstream.models.UserClaimedEvent;
import io.getstream.models.UserDeactivatedEvent;
import io.getstream.models.UserDeletedEvent;
import io.getstream.models.UserFlaggedEvent;
Expand Down Expand Up @@ -245,6 +258,7 @@ public static class EventType {
public static final String CALL_RECORDING_STOPPED = "call.recording_stopped";
public static final String CALL_REJECTED = "call.rejected";
public static final String CALL_RING = "call.ring";
public static final String CALL_RING_SETTLED = "call.ring_settled";
public static final String CALL_RTMP_BROADCAST_FAILED = "call.rtmp_broadcast_failed";
public static final String CALL_RTMP_BROADCAST_STARTED = "call.rtmp_broadcast_started";
public static final String CALL_RTMP_BROADCAST_STOPPED = "call.rtmp_broadcast_stopped";
Expand All @@ -267,10 +281,12 @@ public static class EventType {
public static final String CAMPAIGN_STARTED = "campaign.started";
public static final String CHANNEL_CREATED = "channel.created";
public static final String CHANNEL_DELETED = "channel.deleted";
public static final String CHANNEL_FORKED = "channel.forked";
public static final String CHANNEL_FROZEN = "channel.frozen";
public static final String CHANNEL_HIDDEN = "channel.hidden";
public static final String CHANNEL_MAX_STREAK_CHANGED = "channel.max_streak_changed";
public static final String CHANNEL_MUTED = "channel.muted";
public static final String CHANNEL_REWOUND = "channel.rewound";
public static final String CHANNEL_TRUNCATED = "channel.truncated";
public static final String CHANNEL_UNFROZEN = "channel.unfrozen";
public static final String CHANNEL_UNMUTED = "channel.unmuted";
Expand All @@ -285,6 +301,8 @@ public static class EventType {
"export.bulk_image_moderation.success";
public static final String EXPORT_CHANNELS_ERROR = "export.channels.error";
public static final String EXPORT_CHANNELS_SUCCESS = "export.channels.success";
public static final String EXPORT_LABEL_RESULTS_ERROR = "export.label_results.error";
public static final String EXPORT_LABEL_RESULTS_SUCCESS = "export.label_results.success";
public static final String EXPORT_MODERATION_LOGS_ERROR = "export.moderation_logs.error";
public static final String EXPORT_MODERATION_LOGS_SUCCESS = "export.moderation_logs.success";
public static final String EXPORT_REVIEW_QUEUE_ERROR = "export.review_queue.error";
Expand All @@ -311,6 +329,7 @@ public static class EventType {
public static final String FEEDS_BOOKMARK_FOLDER_UPDATED = "feeds.bookmark_folder.updated";
public static final String FEEDS_COMMENT_ADDED = "feeds.comment.added";
public static final String FEEDS_COMMENT_DELETED = "feeds.comment.deleted";
public static final String FEEDS_COMMENT_FEEDBACK = "feeds.comment.feedback";
public static final String FEEDS_COMMENT_REACTION_ADDED = "feeds.comment.reaction.added";
public static final String FEEDS_COMMENT_REACTION_DELETED = "feeds.comment.reaction.deleted";
public static final String FEEDS_COMMENT_REACTION_UPDATED = "feeds.comment.reaction.updated";
Expand Down Expand Up @@ -352,7 +371,6 @@ public static class EventType {
public static final String MODERATION_FLAGGED = "moderation.flagged";
public static final String MODERATION_IMAGE_ANALYSIS_COMPLETE =
"moderation.image_analysis.complete";
public static final String MODERATION_INTENT_DETECTED = "moderation.intent_detected";
public static final String MODERATION_MARK_REVIEWED = "moderation.mark_reviewed";
public static final String MODERATION_TEXT_ANALYSIS_COMPLETE =
"moderation.text_analysis.complete";
Expand All @@ -361,6 +379,12 @@ public static class EventType {
public static final String NOTIFICATION_MARK_UNREAD = "notification.mark_unread";
public static final String NOTIFICATION_REMINDER_DUE = "notification.reminder_due";
public static final String NOTIFICATION_THREAD_MESSAGE_NEW = "notification.thread_message_new";
public static final String POLL_CLOSED = "poll.closed";
public static final String POLL_DELETED = "poll.deleted";
public static final String POLL_UPDATED = "poll.updated";
public static final String POLL_VOTE_CASTED = "poll.vote_casted";
public static final String POLL_VOTE_CHANGED = "poll.vote_changed";
public static final String POLL_VOTE_REMOVED = "poll.vote_removed";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feeds poll webhook types unmapped

Medium Severity

New poll webhook mappings only register poll.* type strings, but poll operations also emit feeds.poll.* events and the new poll event models carry both chat (cid, message_id) and feeds (activity_id) fields. A feeds poll webhook therefore misses getEventClass, so parseWebhookEvent fails and parseEvent falls back to UnknownEvent instead of the typed poll payload.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit e3b3542. Configure here.

public static final String REACTION_DELETED = "reaction.deleted";
public static final String REACTION_NEW = "reaction.new";
public static final String REACTION_UPDATED = "reaction.updated";
Expand All @@ -369,8 +393,11 @@ public static class EventType {
public static final String REMINDER_UPDATED = "reminder.updated";
public static final String REVIEW_QUEUE_ITEM_NEW = "review_queue_item.new";
public static final String REVIEW_QUEUE_ITEM_UPDATED = "review_queue_item.updated";
public static final String SCHEDULED_MESSAGE_FAILED = "scheduled_message.failed";
public static final String SCHEDULED_MESSAGE_SENT = "scheduled_message.sent";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scheduled message deleted event missing

Medium Severity

Scheduled-message support adds webhook types for scheduled_message.failed and scheduled_message.sent only. DeleteScheduledMessageRequest documents that cancel/remove sends scheduled_message.deleted, which has no constant or getEventClass case, so that webhook is treated as unknown.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit e3b3542. Configure here.

public static final String THREAD_UPDATED = "thread.updated";
public static final String USER_BANNED = "user.banned";
public static final String USER_CLAIMED = "user.claimed";
public static final String USER_DEACTIVATED = "user.deactivated";
public static final String USER_DELETED = "user.deleted";
public static final String USER_FLAGGED = "user.flagged";
Expand Down Expand Up @@ -556,6 +583,8 @@ private static Class<?> getEventClass(String eventType) {
return CallRejectedEvent.class;
case "call.ring":
return CallRingEvent.class;
case "call.ring_settled":
return CallRingSettledEvent.class;
case "call.rtmp_broadcast_failed":
return CallRtmpBroadcastFailedEvent.class;
case "call.rtmp_broadcast_started":
Expand Down Expand Up @@ -598,6 +627,8 @@ private static Class<?> getEventClass(String eventType) {
return ChannelCreatedEvent.class;
case "channel.deleted":
return ChannelDeletedEvent.class;
case "channel.forked":
return ChannelForkedEvent.class;
case "channel.frozen":
return ChannelFrozenEvent.class;
case "channel.hidden":
Expand All @@ -606,6 +637,8 @@ private static Class<?> getEventClass(String eventType) {
return MaxStreakChangedEvent.class;
case "channel.muted":
return ChannelMutedEvent.class;
case "channel.rewound":
return ChannelRewoundEvent.class;
case "channel.truncated":
return ChannelTruncatedEvent.class;
case "channel.unfrozen":
Expand All @@ -630,6 +663,10 @@ private static Class<?> getEventClass(String eventType) {
return AsyncExportErrorEvent.class;
case "export.channels.success":
return AsyncExportChannelsEvent.class;
case "export.label_results.error":
return AsyncExportErrorEvent.class;
case "export.label_results.success":
return AsyncExportLabelResultsEvent.class;
case "export.moderation_logs.error":
return AsyncExportErrorEvent.class;
case "export.moderation_logs.success":
Expand Down Expand Up @@ -680,6 +717,8 @@ private static Class<?> getEventClass(String eventType) {
return CommentAddedEvent.class;
case "feeds.comment.deleted":
return CommentDeletedEvent.class;
case "feeds.comment.feedback":
return CommentFeedbackEvent.class;
case "feeds.comment.reaction.added":
return CommentReactionAddedEvent.class;
case "feeds.comment.reaction.deleted":
Expand Down Expand Up @@ -760,8 +799,6 @@ private static Class<?> getEventClass(String eventType) {
return ModerationFlaggedEvent.class;
case "moderation.image_analysis.complete":
return ModerationImageAnalysisCompleteEvent.class;
case "moderation.intent_detected":
return IntentDetectedEvent.class;
case "moderation.mark_reviewed":
return ModerationMarkReviewedEvent.class;
case "moderation.text_analysis.complete":
Expand All @@ -776,6 +813,18 @@ private static Class<?> getEventClass(String eventType) {
return ReminderNotificationEvent.class;
case "notification.thread_message_new":
return NotificationThreadMessageNewEvent.class;
case "poll.closed":
return PollClosedEvent.class;
case "poll.deleted":
return PollDeletedEvent.class;
case "poll.updated":
return PollUpdatedEvent.class;
case "poll.vote_casted":
return PollVoteCastedEvent.class;
case "poll.vote_changed":
return PollVoteChangedEvent.class;
case "poll.vote_removed":
return PollVoteRemovedEvent.class;
case "reaction.deleted":
return ReactionDeletedEvent.class;
case "reaction.new":
Expand All @@ -792,10 +841,16 @@ private static Class<?> getEventClass(String eventType) {
return ReviewQueueItemNewEvent.class;
case "review_queue_item.updated":
return ReviewQueueItemUpdatedEvent.class;
case "scheduled_message.failed":
return ScheduledMessageFailedEvent.class;
case "scheduled_message.sent":
return ScheduledMessageSentEvent.class;
case "thread.updated":
return ThreadUpdatedEvent.class;
case "user.banned":
return UserBannedEvent.class;
case "user.claimed":
return UserClaimedEvent.class;
case "user.deactivated":
return UserDeactivatedEvent.class;
case "user.deleted":
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/io/getstream/models/AIAudioConfigRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,12 @@ public class AIAudioConfigRequest {
@Nullable
@JsonProperty("rules")
private List<BodyguardRule> rules;

@Nullable
@JsonProperty("ai_text_config")
private AITextConfig aiTextConfig;

@Nullable
@JsonProperty("llm_config")
private LLMConfig llmConfig;
}
9 changes: 9 additions & 0 deletions src/main/java/io/getstream/models/AIAudioConfigResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
import org.jetbrains.annotations.Nullable;

@lombok.Data
@lombok.Builder
Expand All @@ -29,4 +30,12 @@ public class AIAudioConfigResponse {

@JsonProperty("rules")
private List<BodyguardRule> rules;

@Nullable
@JsonProperty("ai_text_config")
private AITextConfig aiTextConfig;

@Nullable
@JsonProperty("llm_config")
private LLMConfig llmConfig;
}
4 changes: 4 additions & 0 deletions src/main/java/io/getstream/models/APIError.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ public class APIError {
@JsonProperty("details")
private List<Integer> details;

@Nullable
@JsonProperty("cooldown_remaining_ms")
private Integer cooldownRemainingMs;

@Nullable
@JsonProperty("unrecoverable")
private Boolean unrecoverable;
Expand Down
Loading
Loading