// Here's a channel with some custom field data that might be useful
val channelClient = client.channel(channelType = "messaging", channelId = "general")
channelClient.create(
memberIds = listOf("thierry", "tomasso"),
extraData = mapOf(
"source" to "user",
"source_detail" to mapOf("user_id" to 123),
"channel_detail" to mapOf(
"topic" to "Plants and Animals",
"rating" to "pg"
)
)
).execute()
// let's change the source of this channel
channelClient.updatePartial(set = mapOf("source" to "system")).execute()
// since it's system generated we no longer need source_detail
channelClient.updatePartial(unset = listOf("source_detail")).execute()
// and finally update one of the nested fields in the channel_detail
channelClient.updatePartial(set = mapOf("channel_detail.topic" to "Nature")).execute()
// and maybe we decide we no longer need a rating
channelClient.updatePartial(unset = listOf("channel_detail.rating")).execute()Updating a Channel
There are two ways to update a channel with the Stream API: partial updates and full updates. A partial update preserves existing custom key–value data, while a full update replaces the entire channel object and removes any fields not included in the request.
Partial Update
A partial update lets you set or unset specific fields without affecting the rest of the channel’s custom data — essentially a patch-style update.
// Here's a channel with some custom field data that might be useful
const channel = client.channel(type, id, {
source: "user",
source_detail: { user_id: 123 },
channel_detail: { topic: "Plants and Animals", rating: "pg" },
});
// let's change the source of this channel
await channel.updatePartial({ set: { source: "system" } });
// since it's system generated we no longer need source_detail
await channel.updatePartial({ unset: ["source_detail"] });
// and finally update one of the nested fields in the channel_detail
await channel.updatePartial({ set: { "channel_detail.topic": "Nature" } });
// and maybe we decide we no longer need a rating
await channel.updatePartial({ unset: ["channel_detail.rating"] });// Here's a channel with some custom field data that might be useful
var channel = client.channel(type, id: id, extraData: {
"source": "user",
"source_detail" :{ "user_id": 123 },
"channel_detail" :{ "topic": "Plants and Animals", "rating": "pg" }
});
// let's change the source of this channel
await channel.updatePartial(set: { "source": "system" });
// since it's system generated we no longer need source_detail
await channel.updatePartial(unset: ["source_detail"]);
// and finally update one of the nested fields in the channel_detail
await channel.updatePartial(set: { "channel_detail.topic": "Nature" });
// and maybe we decide we no longer need a rating
await channel.updatePartial(unset: ["channel_detail.rating"]);from getstream.models import ChannelInput
# Here's a channel with some custom field data that might be useful
channel = client.chat.channel(type, id)
channel.get_or_create(
data=ChannelInput(
created_by_id="myuserid",
custom={
"source": "user",
"source_detail": {"user_id": 123},
"channel_detail": {"topic": "Plants and Animals", "rating": "pg"},
},
)
)
# let's change the source of this channel
channel.update_channel_partial(set={"source": "system"})
# since it's system generated we no longer need source_detail
channel.update_channel_partial(unset=["source_detail"])
# and finally update one of the nested fields in the channel_detail
channel.update_channel_partial(set={"channel_detail.topic": "Nature"})
# and maybe we decide we no longer need a rating
channel.update_channel_partial(unset=["channel_detail.rating"])use GetStream\ChatClient;
use GetStream\GeneratedModels as Models;
// Here's a channel with some custom field data that might be useful
$client->getOrCreateChannel("messaging", "thierry-jenny", new Models\ChannelGetOrCreateRequest(
data: new Models\ChannelInput(
createdByID: "thierry",
custom: (object)[
"source" => "user",
"source_detail" => (object)["user_id" => 123],
"channel_detail" => (object)["topic" => "Plants and Animals", "rating" => "pg"],
],
),
));
// let's change the source of this channel
$client->updateChannelPartial("messaging", "thierry-jenny", new Models\UpdateChannelPartialRequest(
set: (object)["source" => "system"],
));
// since it's system generated we no longer need source_detail
$client->updateChannelPartial("messaging", "thierry-jenny", new Models\UpdateChannelPartialRequest(
unset: ["source_detail"],
));
// and finally update one of the nested fields in the channel_detail
$client->updateChannelPartial("messaging", "thierry-jenny", new Models\UpdateChannelPartialRequest(
set: (object)["channel_detail.topic" => "Nature"],
));
// and maybe we decide we no longer need a rating
$client->updateChannelPartial("messaging", "thierry-jenny", new Models\UpdateChannelPartialRequest(
unset: ["channel_detail.rating"],
));using GetStream;
using GetStream.Models;
var client = new StreamClient("{{ api_key }}", "{{ api_secret }}");
var chat = new ChatClient(client);
// Create a channel with some custom data
var channelResp = await chat.GetOrCreateChannelAsync("messaging", "general",
new ChannelGetOrCreateRequest
{
Data = new ChannelInput
{
CreatedByID = createdByUserId,
Custom = new Dictionary<string, object>
{
["source"] = "user",
["source_detail"] = new Dictionary<string, object> { ["user_id"] = 123 },
["channel_detail"] = new Dictionary<string, object>
{
["topic"] = "Plants and Animals",
["rating"] = "pg"
}
}
}
});
// let's change the source of this channel
await chat.UpdateChannelPartialAsync("messaging", "general",
new UpdateChannelPartialRequest
{
Set = new Dictionary<string, object> { ["source"] = "system" }
});
// since it's system generated we no longer need source_detail
await chat.UpdateChannelPartialAsync("messaging", "general",
new UpdateChannelPartialRequest
{
Unset = new List<string> { "source_detail" }
});
// and finally update one of the nested fields in the channel_detail
await chat.UpdateChannelPartialAsync("messaging", "general",
new UpdateChannelPartialRequest
{
Set = new Dictionary<string, object> { ["channel_detail.topic"] = "Nature" }
});
// and maybe we decide we no longer need a rating
await chat.UpdateChannelPartialAsync("messaging", "general",
new UpdateChannelPartialRequest
{
Unset = new List<string> { "channel_detail.rating" }
});// Create a channel with some custom field data that might be useful
FChannelProperties Props = FChannelProperties{Type, Id};
// Set extra data using dynamic JSON. You'd more likely want to use statically typed structs.
Props.ExtraData.SetString(TEXT("source"), TEXT("user"));
const TSharedRef<FJsonObject> SourceDetail = MakeShared<FJsonObject>();
SourceDetail->SetNumberField(TEXT("user_id"), 123);
Props.ExtraData.SetJsonValue(TEXT("source_detail"), MakeShared<FJsonValueObject>(SourceDetail));
const TSharedRef<FJsonObject> ChannelDetail = MakeShared<FJsonObject>();
ChannelDetail->SetStringField(TEXT("topic"), TEXT("Plants and Animals"));
ChannelDetail->SetStringField(TEXT("rating"), TEXT("pg"));
Props.ExtraData.SetJsonValue(TEXT("source_detail"), MakeShared<FJsonValueObject>(ChannelDetail));
Client->CreateChannel(
Props,
[](UChatChannel* Channel)
{
// let's change the source of this channel
const TSharedRef<FJsonObject> NewSource = MakeShared<FJsonObject>();
NewSource->SetStringField(TEXT("source"), TEXT("system"));
Channel->PartialUpdate(NewSource);
// since it's system generated we no longer need source_detail
Channel->PartialUpdate({}, {TEXT("source_detail")});
// and finally update one of the nested fields in the channel_detail
const TSharedRef<FJsonObject> NewTopic = MakeShared<FJsonObject>();
NewSource->SetStringField(TEXT("channel_detail.topic"), TEXT("Nature"));
Channel->PartialUpdate(NewSource);
// and maybe we decide we no longer need a rating
Channel->PartialUpdate({}, {TEXT("channel_detail.rating")});
});channel := client.Chat().Channel("messaging", "general")
channel.GetOrCreate(ctx, &getstream.GetOrCreateChannelRequest{
Data: &getstream.ChannelInput{
CreatedByID: getstream.PtrTo("thierry"),
Custom: map[string]any{
"source": "user",
"source_detail": map[string]any{"user_id": "123"},
"channel_detail": map[string]any{"topic": "Plants and Animals", "rating": "pg"},
},
},
})
// let's change the source of this channel
channel.UpdateChannelPartial(ctx, &getstream.UpdateChannelPartialRequest{
Set: map[string]any{
"source": "system",
},
})
// since it's system generated we no longer need source_detail
channel.UpdateChannelPartial(ctx, &getstream.UpdateChannelPartialRequest{
Unset: []string{"source_detail"},
})
// and finally update one of the nested fields in the channel_detail
channel.UpdateChannelPartial(ctx, &getstream.UpdateChannelPartialRequest{
Set: map[string]any{
"channel_detail.topic": "Nature",
},
})
// and maybe we decide we no longer need a rating
channel.UpdateChannelPartial(ctx, &getstream.UpdateChannelPartialRequest{
Unset: []string{"channel_detail.rating"},
})require 'getstream_ruby'
Models = GetStream::Generated::Models
# Here's a channel with some custom field data that might be useful
client.chat.get_or_create_channel(type, id,
Models::ChannelGetOrCreateRequest.new(
data: Models::ChannelInput.new(
created_by_id: 'myuserid',
custom: {
'source' => 'user',
'source_detail' => { 'user_id' => 123 },
'channel_detail' => { 'topic' => 'Plants and Animals', 'rating' => 'pg' }
}
)
)
)
# let's change the source of this channel
client.chat.update_channel_partial(type, id,
Models::UpdateChannelPartialRequest.new(set: { 'source' => 'system' })
)
# since it's system generated we no longer need source_detail
client.chat.update_channel_partial(type, id,
Models::UpdateChannelPartialRequest.new(unset: ['source_detail'])
)
# and finally update one of the nested fields in the channel_detail
client.chat.update_channel_partial(type, id,
Models::UpdateChannelPartialRequest.new(set: { 'channel_detail.topic' => 'Nature' })
)
# and maybe we decide we no longer need a rating
client.chat.update_channel_partial(type, id,
Models::UpdateChannelPartialRequest.new(unset: ['channel_detail.rating'])
)public async Task PartialUpdate()
{
var channel = await Client.GetOrCreateChannelWithIdAsync(ChannelType.Messaging, channelId: "my-channel-id");
var setClanInfo = new ClanData
{
MaxMembers = 50,
Name = "Wild Boards",
Tags = new List<string>
{
"Competitive",
"Legendary",
}
};
var setFields = new Dictionary<string, object>();
// Set custom values
setFields.Add("frags", 5);
// Set custom arrays
setFields.Add("items", new[] { "sword", "shield" });
// Set custom class objects
setFields.Add("clan_info", setClanInfo);
// Send data
await channel.UpdatePartialAsync(setFields);
// Data is now available via CustomData property
var frags = channel.CustomData.Get<int>("frags");
var items = channel.CustomData.Get<List<string>>("items");
var clanInfo = channel.CustomData.Get<ClanData>("clan_info");
}
// Example class with data that you can assign as Channel custom data
private class ClanData
{
public int MaxMembers;
public string Name;
public List<string> Tags;
}// Android SDK
// Here's a channel with some custom field data that might be useful
ChannelClient channelClient = client.channel("messaging", "general");
List<String> members = Arrays.asList("thierry", "tommaso");
Map<String, String> channelDetail = new HashMap<>();
channelDetail.put("topic", "Plants and Animals");
channelDetail.put("rating", "pg");
Map<String, Integer> userId = new HashMap<>();
userId.put("user_id", 123);
Map<String, Object> extraData = new HashMap<>();
extraData.put("source", "user");
extraData.put("source_detail", userId);
extraData.put("channel_detail", channelDetail);
channelClient.create(members, extraData).execute();
// let's change the source of this channel
Map<String, Object> setField = Collections.singletonMap("source", "system");
channelClient.updatePartial(setField, emptyList()).execute();
// since it's system generated we no longer need source_detail
List<String> unsetField = Collections.singletonList("source_detail");
channelClient.updatePartial(emptyMap(), unsetField).execute();
// and finally update one of the nested fields in the channel_detail
Map<String, Object> setNestedField = Collections.singletonMap("channel_detail.topic", "Nature");
channelClient.updatePartial(setNestedField, emptyList()).execute();
// and maybe we decide we no longer need a rating
List<String> unsetNestedField = Collections.singletonList("channel_detail.rating");
channelClient.updatePartial(emptyMap(), unsetNestedField).execute();
// Backend SDK
chat.updateChannelPartial("messaging", "general", UpdateChannelPartialRequest.builder()
.set(Map.of("source", "system", "channel_detail.topic", "Nature"))
.unset(List.of("source_detail"))
.build()).execute();channelController.partialChannelUpdate(
extraData: [
"source": .string("user"),
"source_detail": .dictionary(["user_id": .number(123)]),
"channel_detail": .dictionary([
"topic": .string("Plants and Animals"),
"rating": .string("pg")
])
]
) { error in
if let error {
// handle error
}
}
// let's change the source of this channel
channelController.partialChannelUpdate(unsetProperties: ["source_detail"])
// let's change the source of this channel
channelController.partialChannelUpdate(extraData:["source": "system"])
// since it's system generated we no longer need source_detail
channelController.partialChannelUpdate(unsetProperties: ["source_detail"])
// and finally update one of the nested fields in the channel_detail
channelController.partialChannelUpdate(extraData:["channel_detail.topic": "Nature"])Full Update
The update function updates all of the channel data. Any data that is present on the channel and not included in a full update will be deleted.
val channelClient = client.channel("messaging", "general")
channelClient.update(
message = Message(
text = "Thierry changed the channel color to green"
),
extraData = mapOf(
"name" to "myspecialchannel",
"color" to "green",
),
).enqueue { result ->
if (result is Result.Success) {
val channel = result.value
} else {
// Handle Result.Failure
}
}const update = await channel.update({
name: "myspecialchannel",
color: "green",
});await channel.update({
"name": "myspecialchannel",
"color": "green",
}, Message(text: "Thierry changed the channel color to green"));use GetStream\ChatClient;
use GetStream\GeneratedModels as Models;
$client->updateChannel("messaging", "general", new Models\UpdateChannelRequest(
data: new Models\ChannelInputRequest(
custom: (object)["name" => "myspecialchannel", "color" => "green"],
),
message: new Models\MessageRequest(
text: "Thierry changed the channel color to green",
userID: "thierry",
),
));let channelController = chatClient.channelController(for: .init(type: .messaging, id: "general"))
channelController.updateChannel(
name: "My special channel",
imageURL: nil,
team: nil,
extraData: [
"name": .string("myspecialchannel"),
"color": .string("green"),
]
) { error in
if let error {
// handle error
}
}from getstream.models import ChannelInputRequest
channel.update(
data=ChannelInputRequest(
custom={
"name": "myspecialchannel",
"color": "green",
},
),
)FAdditionalFields Data;
Data.SetString(TEXT("name"), TEXT("myspecialchannel"));
Data.SetString(TEXT("color"), TEXT("green"));
Channel->Update(Data, Message);var resp = await chat.UpdateChannelAsync("messaging", channelId,
new UpdateChannelRequest
{
Data = new ChannelInputRequest
{
Custom = new Dictionary<string, object>
{
["name"] = "myspecialchannel",
["color"] = "green"
}
}
});channel.Update(ctx, &getstream.UpdateChannelRequest{
Data: &getstream.ChannelInputRequest{
Custom: map[string]any{
"name": "myspecialchannel",
"color": "green",
},
},
})require 'getstream_ruby'
Models = GetStream::Generated::Models
client.chat.update_channel('messaging', 'general',
Models::UpdateChannelRequest.new(
data: Models::ChannelInputRequest.new(
custom: { 'name' => 'myspecialchannel', 'color' => 'green' }
)
)
)var updateRequest = new StreamUpdateOverwriteChannelRequest
{
Name = "New name",
CustomData = new StreamCustomDataRequest
{
{"my-custom-int", 12},
{"my-custom-array", new string[]{"one", "two"}}
}
};
// This request will have all channel data removed except what is being passed in the request
await channel.UpdateOverwriteAsync(updateRequest);
// You can also pass an instance of channel to the request constructor to have all of the date copied over
// This way you alter only the fields you wish to change
var updateRequest2 = new StreamUpdateOverwriteChannelRequest(channel)
{
Name = "Brand new name"
};
// This will update only the name because all other data was copied over
await channel.UpdateOverwriteAsync(updateRequest2);// Android SDK
ChannelClient channelClient = client.channel("messaging", "general");
Map<String, Object> channelData = new HashMap<>();
channelData.put("name", "myspecialchannel");
channelData.put("color", "green");
Message updateMessage = new Message();
updateMessage.setText("Thierry changed the channel color to green");
channelClient.update(updateMessage, channelData).enqueue(result -> {
if (result.isSuccess()) {
Channel channel = result.data();
} else {
// Handle result.error()
}
});
// Backend SDK
chat.updateChannel("messaging", "general", UpdateChannelRequest.builder()
.message(MessageRequest.builder()
.text("Thierry changed the channel color to green")
.build())
.data(ChannelInputRequest.builder()
.custom(Map.of("name", "myspecialchannel", "color", "green"))
.build())
.build()).execute();Request Params
| Name | Type | Description | Optional |
|---|---|---|---|
| channel data | object | Object with the new channel information. One special field is "frozen". Setting this field to true will freeze the channel. Read more about freezing channels in "Freezing Channels" | |
| text | object | Message object allowing you to show a system message in the Channel that something changed. | Yes |
Updating a channel using these methods cannot be used to add or remove members. For this, you must use specific methods for adding/removing members, more information can be found here.