diff --git a/docs/migration-from-stream-chat-go/05-moderation.md b/docs/migration-from-stream-chat-go/05-moderation.md index 82240df..f2ea11d 100644 --- a/docs/migration-from-stream-chat-go/05-moderation.md +++ b/docs/migration-from-stream-chat-go/05-moderation.md @@ -430,6 +430,156 @@ func main() { - `UnmuteUser` becomes `Unmute` with `UnmuteRequest` - `TargetIds` is a slice, allowing batch unmuting +## Block a User + +User blocking is a per-user block list, separate from banning. + +**Before (stream-chat-go):** + +```go +resp, err := client.BlockUser(ctx, "target-user", "acting-user") + +resp, err = client.UnblockUser(ctx, "target-user", "acting-user") + +blocked, err := client.GetBlockedUser(ctx, "acting-user") +``` + +**After (getstream-go):** + +```go +resp, err := client.BlockUsers(ctx, &getstream.BlockUsersRequest{ + BlockedUserID: "target-user", + UserID: getstream.PtrTo("acting-user"), +}) + +resp, err = client.UnblockUsers(ctx, &getstream.UnblockUsersRequest{ + BlockedUserID: "target-user", + UserID: getstream.PtrTo("acting-user"), +}) + +blocked, err := client.GetBlockedUsers(ctx, &getstream.GetBlockedUsersRequest{ + UserID: getstream.PtrTo("acting-user"), +}) +``` + +**Key changes:** +- Method names are plural: `BlockUser` becomes `BlockUsers`, `GetBlockedUser` becomes `GetBlockedUsers` +- Positional arguments become fields on a request struct +- Do not confuse these with `client.Video().UnblockUser(...)`, which removes a user from a call + +## Blocklists + +**Before (stream-chat-go):** + +```go +err := client.CreateBlocklist(ctx, &stream.BlocklistCreateRequest{ + BlocklistBase: stream.BlocklistBase{ + Name: "profanity", + Words: []string{"badword"}, + }, +}) + +list, err := client.GetBlocklist(ctx, "profanity") +_, err = client.UpdateBlocklist(ctx, "profanity", []string{"badword", "worse"}) +all, err := client.ListBlocklists(ctx) +_, err = client.DeleteBlocklist(ctx, "profanity") +``` + +**After (getstream-go):** + +```go +resp, err := client.CreateBlockList(ctx, &getstream.CreateBlockListRequest{ + Name: "profanity", + Words: []string{"badword"}, +}) + +list, err := client.GetBlockList(ctx, "profanity", &getstream.GetBlockListRequest{}) +_, err = client.UpdateBlockList(ctx, "profanity", &getstream.UpdateBlockListRequest{ + Words: []string{"badword", "worse"}, +}) +all, err := client.ListBlockLists(ctx, &getstream.ListBlockListsRequest{}) +_, err = client.DeleteBlockList(ctx, "profanity", &getstream.DeleteBlockListRequest{}) +``` + +**Key changes:** +- The type is spelled `BlockList` (capital L), not `Blocklist`. Every method renames accordingly: `CreateBlocklist` to `CreateBlockList`, `ListBlocklists` to `ListBlockLists`, and so on +- Every method takes a request struct, even where the legacy call took only a name +- `UpdateBlockList` carries `Words` on the request instead of a positional slice +- The new request supports matching options the legacy SDK did not expose: `Type` (`word`, `regex`, `domain`, `email`, and the allowlist variants), `IsSubstringMatchingEnabled`, `IsLeetCheckEnabled`, `IsPluralCheckEnabled`, `IsConfusableFoldingEnabled` + +## Flagging Content + +> **Read this before migrating flags.** The legacy flag methods write to the **v1 chat flags** store. `getstream-go` exposes the **v2 moderation** API, and the two stores are not the same: content flagged through `Moderation().Flag()` may not appear in `Chat().QueryMessageFlags()`, which still reads v1. Swapping the call alone can therefore leave a flagging workflow that writes to one store and reads from another. Migrate the whole workflow (flag, query, review) to v2 together, or keep using v1 until you can. + +**Before (stream-chat-go):** + +```go +_, err := client.FlagMessage(ctx, "message-id", "acting-user") +_, err = client.FlagUser(ctx, "target-user", "acting-user") + +flags, err := client.QueryMessageFlags(ctx, &stream.QueryOption{ + Filter: map[string]interface{}{"channel_cid": "messaging:general"}, +}) +``` + +**After (getstream-go):** + +```go +_, err := client.Moderation().Flag(ctx, &getstream.FlagRequest{ + EntityType: "message", + EntityID: "message-id", + UserID: getstream.PtrTo("acting-user"), +}) + +_, err = client.Moderation().Flag(ctx, &getstream.FlagRequest{ + EntityType: "user", + EntityID: "target-user", + UserID: getstream.PtrTo("acting-user"), +}) + +flags, err := client.Chat().QueryMessageFlags(ctx, &getstream.QueryMessageFlagsRequest{ + Payload: &getstream.QueryMessageFlagsPayload{ + FilterConditions: map[string]any{"channel_cid": "messaging:general"}, + }, +}) +``` + +**Key changes:** +- `FlagMessage` and `FlagUser` collapse into one `Moderation().Flag()` call; the target is described by `EntityType` plus `EntityID` instead of a dedicated method +- `QueryMessageFlags` stays on the Chat sub-client and takes its filter under `Payload` +- Flag reads and writes can cross the v1/v2 boundary described above; verify your flags are visible where you expect before relying on them + +## Reviewing Flagged Content + +The v1 flag-report workflow has no drop-in replacement. `QueryFlagReports` and `ReviewFlagReport` are replaced by the v2 **review queue**, which is a different model rather than a rename, so this needs rework instead of a call swap. + +**Before (stream-chat-go):** + +```go +reports, err := client.QueryFlagReports(ctx, &stream.QueryFlagReportsRequest{}) +_, err = client.ReviewFlagReport(ctx, "report-id", &stream.ReviewFlagReportRequest{ + ReviewResult: "reviewed", +}) +``` + +**After (getstream-go):** + +```go +queue, err := client.Moderation().QueryReviewQueue(ctx, &getstream.QueryReviewQueueRequest{}) + +item, err := client.Moderation().GetReviewQueueItem(ctx, "item-id", &getstream.GetReviewQueueItemRequest{}) + +_, err = client.Moderation().SubmitAction(ctx, &getstream.SubmitActionRequest{ + ItemID: getstream.PtrTo("item-id"), + ActionType: "mark_reviewed", +}) +``` + +**Key changes:** +- Flag reports become review-queue items: query with `QueryReviewQueue`, read one with `GetReviewQueueItem` +- Reviewing is an action submitted against an item via `SubmitAction` rather than a single review call +- Because the underlying model changed, treat this as a redesign of the moderation workflow and confirm the behavior you need against the moderation documentation + ## Method Mapping Summary | Legacy (stream-chat-go) | New (getstream-go) | @@ -443,3 +593,16 @@ func main() { | `client.MuteUser(ctx, target, by, opts...)` | `client.Moderation().Mute(ctx, &MuteRequest{...})` | | `client.UnmuteUser(ctx, target, by)` | `client.Moderation().Unmute(ctx, &UnmuteRequest{...})` | | `client.QueryBannedUsers(ctx, opts)` | `client.Chat().QueryBannedUsers(ctx, &QueryBannedUsersRequest{...})` | +| `client.BlockUser(ctx, target, by)` | `client.BlockUsers(ctx, &BlockUsersRequest{...})` | +| `client.UnblockUser(ctx, target, by)` | `client.UnblockUsers(ctx, &UnblockUsersRequest{...})` | +| `client.GetBlockedUser(ctx, by)` | `client.GetBlockedUsers(ctx, &GetBlockedUsersRequest{...})` | +| `client.CreateBlocklist(ctx, req)` | `client.CreateBlockList(ctx, &CreateBlockListRequest{...})` | +| `client.GetBlocklist(ctx, name)` | `client.GetBlockList(ctx, name, &GetBlockListRequest{})` | +| `client.UpdateBlocklist(ctx, name, words)` | `client.UpdateBlockList(ctx, name, &UpdateBlockListRequest{Words: words})` | +| `client.ListBlocklists(ctx)` | `client.ListBlockLists(ctx, &ListBlockListsRequest{})` | +| `client.DeleteBlocklist(ctx, name)` | `client.DeleteBlockList(ctx, name, &DeleteBlockListRequest{})` | +| `client.FlagMessage(ctx, msgID, by)` | `client.Moderation().Flag(ctx, &FlagRequest{EntityType: "message", ...})` (v1 to v2, see note) | +| `client.FlagUser(ctx, target, by)` | `client.Moderation().Flag(ctx, &FlagRequest{EntityType: "user", ...})` (v1 to v2, see note) | +| `client.QueryMessageFlags(ctx, q)` | `client.Chat().QueryMessageFlags(ctx, &QueryMessageFlagsRequest{...})` | +| `client.QueryFlagReports(ctx, req)` | `client.Moderation().QueryReviewQueue(ctx, ...)` (different model) | +| `client.ReviewFlagReport(ctx, id, req)` | `client.Moderation().SubmitAction(ctx, ...)` (different model) | diff --git a/docs/migration-from-stream-chat-go/README.md b/docs/migration-from-stream-chat-go/README.md index 5d1ac6c..4dcaa09 100644 --- a/docs/migration-from-stream-chat-go/README.md +++ b/docs/migration-from-stream-chat-go/README.md @@ -77,7 +77,7 @@ func main() { | 2 | [Users](02-users.md) | Upsert, query, update, delete | | 3 | [Channels](03-channels.md) | Create, query, members, update | | 4 | [Messages and Reactions](04-messages-and-reactions.md) | Send, reply, react | -| 5 | [Moderation](05-moderation.md) | Ban, mute, moderators | +| 5 | [Moderation](05-moderation.md) | Ban, mute, moderators, user blocking, blocklists, flags, review queue | | 6 | [Devices](06-devices.md) | Push device management | ## Notes