Skip to content

Commit 189b822

Browse files
javierdfmRafael Marinho
andauthored
feat: batch channel updates (#1656)
## CLA - [ ] I have signed the [Stream CLA](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform) (required). - [ ] Code changes are tested ## Description of the changes, What, Why and How? https://linear.app/stream/issue/CHA-1608/js ## Changelog - --------- Co-authored-by: Rafael Marinho <[email protected]>
1 parent 3cd767d commit 189b822

File tree

4 files changed

+322
-0
lines changed

4 files changed

+322
-0
lines changed

src/channel_batch_updater.ts

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
import type { StreamChat } from './client';
2+
import type {
3+
APIResponse,
4+
BatchChannelDataUpdate,
5+
NewMemberPayload,
6+
UpdateChannelsBatchFilters,
7+
UpdateChannelsBatchResponse,
8+
} from './types';
9+
10+
/**
11+
* ChannelBatchUpdater - A class that provides convenience methods for batch channel operations
12+
*/
13+
export class ChannelBatchUpdater {
14+
client: StreamChat;
15+
16+
constructor(client: StreamChat) {
17+
this.client = client;
18+
}
19+
20+
// Member operations
21+
22+
/**
23+
* addMembers - Add members to channels matching the filter
24+
*
25+
* @param {UpdateChannelsBatchFilters} filter Filter to select channels
26+
* @param {string[] | NewMemberPayload[]} members Members to add
27+
* @return {Promise<APIResponse & UpdateChannelsBatchResponse>} The server response
28+
*/
29+
async addMembers(
30+
filter: UpdateChannelsBatchFilters,
31+
members: string[] | NewMemberPayload[],
32+
): Promise<APIResponse & UpdateChannelsBatchResponse> {
33+
return await this.client.updateChannelsBatch({
34+
operation: 'addMembers',
35+
filter,
36+
members,
37+
});
38+
}
39+
40+
/**
41+
* removeMembers - Remove members from channels matching the filter
42+
*
43+
* @param {UpdateChannelsBatchFilters} filter Filter to select channels
44+
* @param {string[]} members Member IDs to remove
45+
* @return {Promise<APIResponse & UpdateChannelsBatchResponse>} The server response
46+
*/
47+
async removeMembers(
48+
filter: UpdateChannelsBatchFilters,
49+
members: string[],
50+
): Promise<APIResponse & UpdateChannelsBatchResponse> {
51+
return await this.client.updateChannelsBatch({
52+
operation: 'removeMembers',
53+
filter,
54+
members,
55+
});
56+
}
57+
58+
/**
59+
* inviteMembers - Invite members to channels matching the filter
60+
*
61+
* @param {UpdateChannelsBatchFilters} filter Filter to select channels
62+
* @param {string[] | NewMemberPayload[]} members Members to invite
63+
* @return {Promise<APIResponse & UpdateChannelsBatchResponse>} The server response
64+
*/
65+
async inviteMembers(
66+
filter: UpdateChannelsBatchFilters,
67+
members: string[] | NewMemberPayload[],
68+
): Promise<APIResponse & UpdateChannelsBatchResponse> {
69+
return await this.client.updateChannelsBatch({
70+
operation: 'inviteMembers',
71+
filter,
72+
members,
73+
});
74+
}
75+
76+
/**
77+
* addModerators - Add moderators to channels matching the filter
78+
*
79+
* @param {UpdateChannelsBatchFilters} filter Filter to select channels
80+
* @param {string[]} members Member IDs to promote to moderator
81+
* @return {Promise<APIResponse & UpdateChannelsBatchResponse>} The server response
82+
*/
83+
async addModerators(
84+
filter: UpdateChannelsBatchFilters,
85+
members: string[],
86+
): Promise<APIResponse & UpdateChannelsBatchResponse> {
87+
return await this.client.updateChannelsBatch({
88+
operation: 'addModerators',
89+
filter,
90+
members,
91+
});
92+
}
93+
94+
/**
95+
* demoteModerators - Remove moderator role from members in channels matching the filter
96+
*
97+
* @param {UpdateChannelsBatchFilters} filter Filter to select channels
98+
* @param {string[]} members Member IDs to demote
99+
* @return {Promise<APIResponse & UpdateChannelsBatchResponse>} The server response
100+
*/
101+
async demoteModerators(
102+
filter: UpdateChannelsBatchFilters,
103+
members: string[],
104+
): Promise<APIResponse & UpdateChannelsBatchResponse> {
105+
return await this.client.updateChannelsBatch({
106+
operation: 'demoteModerators',
107+
filter,
108+
members,
109+
});
110+
}
111+
112+
/**
113+
* assignRoles - Assign roles to members in channels matching the filter
114+
*
115+
* @param {UpdateChannelsBatchFilters} filter Filter to select channels
116+
* @param {NewMemberPayload[]} members Members with role assignments
117+
* @return {Promise<APIResponse & UpdateChannelsBatchResponse>} The server response
118+
*/
119+
async assignRoles(
120+
filter: UpdateChannelsBatchFilters,
121+
members: NewMemberPayload[],
122+
): Promise<APIResponse & UpdateChannelsBatchResponse> {
123+
return await this.client.updateChannelsBatch({
124+
operation: 'assignRoles',
125+
filter,
126+
members,
127+
});
128+
}
129+
130+
// Visibility operations
131+
132+
/**
133+
* hide - Hide channels matching the filter
134+
*
135+
* @param {UpdateChannelsBatchFilters} filter Filter to select channels
136+
* @return {Promise<APIResponse & UpdateChannelsBatchResponse>} The server response
137+
*/
138+
async hide(
139+
filter: UpdateChannelsBatchFilters,
140+
): Promise<APIResponse & UpdateChannelsBatchResponse> {
141+
return await this.client.updateChannelsBatch({
142+
operation: 'hide',
143+
filter,
144+
});
145+
}
146+
147+
/**
148+
* show - Show channels matching the filter
149+
*
150+
* @param {UpdateChannelsBatchFilters} filter Filter to select channels
151+
* @return {Promise<APIResponse & UpdateChannelsBatchResponse>} The server response
152+
*/
153+
async show(
154+
filter: UpdateChannelsBatchFilters,
155+
): Promise<APIResponse & UpdateChannelsBatchResponse> {
156+
return await this.client.updateChannelsBatch({
157+
operation: 'show',
158+
filter,
159+
});
160+
}
161+
162+
/**
163+
* archive - Archive channels matching the filter
164+
*
165+
* @param {UpdateChannelsBatchFilters} filter Filter to select channels
166+
* @return {Promise<APIResponse & UpdateChannelsBatchResponse>} The server response
167+
*/
168+
async archive(
169+
filter: UpdateChannelsBatchFilters,
170+
): Promise<APIResponse & UpdateChannelsBatchResponse> {
171+
return await this.client.updateChannelsBatch({
172+
operation: 'archive',
173+
filter,
174+
});
175+
}
176+
177+
/**
178+
* unarchive - Unarchive channels matching the filter
179+
*
180+
* @param {UpdateChannelsBatchFilters} filter Filter to select channels
181+
* @return {Promise<APIResponse & UpdateChannelsBatchResponse>} The server response
182+
*/
183+
async unarchive(
184+
filter: UpdateChannelsBatchFilters,
185+
): Promise<APIResponse & UpdateChannelsBatchResponse> {
186+
return await this.client.updateChannelsBatch({
187+
operation: 'unarchive',
188+
filter,
189+
});
190+
}
191+
192+
// Data operations
193+
194+
/**
195+
* updateData - Update data on channels matching the filter
196+
*
197+
* @param {UpdateChannelsBatchFilters} filter Filter to select channels
198+
* @param {BatchChannelDataUpdate} data Data to update
199+
* @return {Promise<APIResponse & UpdateChannelsBatchResponse>} The server response
200+
*/
201+
async updateData(
202+
filter: UpdateChannelsBatchFilters,
203+
data: BatchChannelDataUpdate,
204+
): Promise<APIResponse & UpdateChannelsBatchResponse> {
205+
return await this.client.updateChannelsBatch({
206+
operation: 'updateData',
207+
filter,
208+
data,
209+
});
210+
}
211+
212+
/**
213+
* addFilterTags - Add filter tags to channels matching the filter
214+
*
215+
* @param {UpdateChannelsBatchFilters} filter Filter to select channels
216+
* @param {string[]} tags Tags to add
217+
* @return {Promise<APIResponse & UpdateChannelsBatchResponse>} The server response
218+
*/
219+
async addFilterTags(
220+
filter: UpdateChannelsBatchFilters,
221+
tags: string[],
222+
): Promise<APIResponse & UpdateChannelsBatchResponse> {
223+
return await this.client.updateChannelsBatch({
224+
operation: 'addFilterTags',
225+
filter,
226+
filter_tags_update: tags,
227+
});
228+
}
229+
230+
/**
231+
* removeFilterTags - Remove filter tags from channels matching the filter
232+
*
233+
* @param {UpdateChannelsBatchFilters} filter Filter to select channels
234+
* @param {string[]} tags Tags to remove
235+
* @return {Promise<APIResponse & UpdateChannelsBatchResponse>} The server response
236+
*/
237+
async removeFilterTags(
238+
filter: UpdateChannelsBatchFilters,
239+
tags: string[],
240+
): Promise<APIResponse & UpdateChannelsBatchResponse> {
241+
return await this.client.updateChannelsBatch({
242+
operation: 'removeFilterTags',
243+
filter,
244+
filter_tags_update: tags,
245+
});
246+
}
247+
}

src/client.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { CheckSignature, DevToken, JWTUserToken } from './signing';
1313
import { TokenManager } from './token_manager';
1414
import { WSConnectionFallback } from './connection_fallback';
1515
import { Campaign } from './campaign';
16+
import { ChannelBatchUpdater } from './channel_batch_updater';
1617
import { Segment } from './segment';
1718
import { isErrorResponse, isWSFailure } from './errors';
1819
import {
@@ -209,6 +210,8 @@ import type {
209210
TokenOrProvider,
210211
TranslateResponse,
211212
UnBanUserOptions,
213+
UpdateChannelsBatchOptions,
214+
UpdateChannelsBatchResponse,
212215
UpdateChannelTypeRequest,
213216
UpdateChannelTypeResponse,
214217
UpdateCommandOptions,
@@ -3746,6 +3749,15 @@ export class StreamChat {
37463749
return new Campaign(this, idOrData, data);
37473750
}
37483751

3752+
/**
3753+
* channelBatchUpdater - Returns a ChannelBatchUpdater instance for batch channel operations
3754+
*
3755+
* @return {ChannelBatchUpdater} A ChannelBatchUpdater instance
3756+
*/
3757+
channelBatchUpdater() {
3758+
return new ChannelBatchUpdater(this);
3759+
}
3760+
37493761
segment(type: SegmentType, idOrData: string | SegmentData, data?: SegmentData) {
37503762
if (typeof idOrData === 'string') {
37513763
return new Segment(this, type, idOrData, data);
@@ -4792,4 +4804,17 @@ export class StreamChat {
47924804
syncDeliveredCandidates(collections: Channel[]) {
47934805
this.messageDeliveryReporter.syncDeliveredCandidates(collections);
47944806
}
4807+
4808+
/**
4809+
* Update Channels Batch
4810+
*
4811+
* @param {UpdateChannelsBatchOptions} payload for updating channels in batch
4812+
* @return {Promise<APIResponse & UpdateChannelsBatchResponse>} The server response
4813+
*/
4814+
async updateChannelsBatch(payload: UpdateChannelsBatchOptions) {
4815+
return await this.put<APIResponse & UpdateChannelsBatchResponse>(
4816+
this.baseURL + `/channels/batch`,
4817+
payload,
4818+
);
4819+
}
47954820
}

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export * from './base64';
22
export * from './campaign';
3+
export * from './channel_batch_updater';
34
export * from './client';
45
export * from './client_state';
56
export * from './channel';

src/types.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4495,3 +4495,52 @@ export type EventHook = {
44954495
created_at?: string;
44964496
updated_at?: string;
44974497
};
4498+
4499+
export type BatchUpdateOperation =
4500+
| 'addMembers'
4501+
| 'removeMembers'
4502+
| 'inviteMembers'
4503+
| 'assignRoles'
4504+
| 'addModerators'
4505+
| 'demoteModerators'
4506+
| 'hide'
4507+
| 'show'
4508+
| 'archive'
4509+
| 'unarchive'
4510+
| 'updateData'
4511+
| 'addFilterTags'
4512+
| 'removeFilterTags';
4513+
4514+
export type BatchChannelDataUpdate = {
4515+
frozen?: boolean;
4516+
disabled?: boolean;
4517+
custom?: Record<string, unknown>;
4518+
team?: string;
4519+
config_overrides?: Record<string, unknown>;
4520+
auto_translation_enabled?: boolean;
4521+
auto_translation_language?: string;
4522+
};
4523+
4524+
export type UpdateChannelsBatchOptions = {
4525+
operation: BatchUpdateOperation;
4526+
filter: UpdateChannelsBatchFilters;
4527+
members?: string[] | Array<NewMemberPayload>;
4528+
data?: BatchChannelDataUpdate;
4529+
filter_tags_update?: string[];
4530+
};
4531+
4532+
export type UpdateChannelsBatchFilters = QueryFilters<{
4533+
cids?:
4534+
| RequireOnlyOne<Pick<QueryFilter<string>, '$in' | '$eq'>>
4535+
| PrimitiveFilter<string[]>;
4536+
types?:
4537+
| RequireOnlyOne<Pick<QueryFilter<string>, '$in' | '$eq'>>
4538+
| PrimitiveFilter<string[]>;
4539+
filter_tags?:
4540+
| RequireOnlyOne<Pick<QueryFilter<string>, '$in' | '$eq'>>
4541+
| PrimitiveFilter<Record<string, string>>;
4542+
}>;
4543+
4544+
export type UpdateChannelsBatchResponse = {
4545+
result: Record<string, string>;
4546+
} & Partial<TaskResponse>;

0 commit comments

Comments
 (0)