diff --git a/src/channel_batch_updater.ts b/src/channel_batch_updater.ts new file mode 100644 index 000000000..3d37c9a6f --- /dev/null +++ b/src/channel_batch_updater.ts @@ -0,0 +1,247 @@ +import type { StreamChat } from './client'; +import type { + APIResponse, + BatchChannelDataUpdate, + NewMemberPayload, + UpdateChannelsBatchFilters, + UpdateChannelsBatchResponse, +} from './types'; + +/** + * ChannelBatchUpdater - A class that provides convenience methods for batch channel operations + */ +export class ChannelBatchUpdater { + client: StreamChat; + + constructor(client: StreamChat) { + this.client = client; + } + + // Member operations + + /** + * addMembers - Add members to channels matching the filter + * + * @param {UpdateChannelsBatchFilters} filter Filter to select channels + * @param {string[] | NewMemberPayload[]} members Members to add + * @return {Promise} The server response + */ + async addMembers( + filter: UpdateChannelsBatchFilters, + members: string[] | NewMemberPayload[], + ): Promise { + return await this.client.updateChannelsBatch({ + operation: 'addMembers', + filter, + members, + }); + } + + /** + * removeMembers - Remove members from channels matching the filter + * + * @param {UpdateChannelsBatchFilters} filter Filter to select channels + * @param {string[]} members Member IDs to remove + * @return {Promise} The server response + */ + async removeMembers( + filter: UpdateChannelsBatchFilters, + members: string[], + ): Promise { + return await this.client.updateChannelsBatch({ + operation: 'removeMembers', + filter, + members, + }); + } + + /** + * inviteMembers - Invite members to channels matching the filter + * + * @param {UpdateChannelsBatchFilters} filter Filter to select channels + * @param {string[] | NewMemberPayload[]} members Members to invite + * @return {Promise} The server response + */ + async inviteMembers( + filter: UpdateChannelsBatchFilters, + members: string[] | NewMemberPayload[], + ): Promise { + return await this.client.updateChannelsBatch({ + operation: 'invites', + filter, + members, + }); + } + + /** + * addModerators - Add moderators to channels matching the filter + * + * @param {UpdateChannelsBatchFilters} filter Filter to select channels + * @param {string[]} members Member IDs to promote to moderator + * @return {Promise} The server response + */ + async addModerators( + filter: UpdateChannelsBatchFilters, + members: string[], + ): Promise { + return await this.client.updateChannelsBatch({ + operation: 'addModerators', + filter, + members, + }); + } + + /** + * demoteModerators - Remove moderator role from members in channels matching the filter + * + * @param {UpdateChannelsBatchFilters} filter Filter to select channels + * @param {string[]} members Member IDs to demote + * @return {Promise} The server response + */ + async demoteModerators( + filter: UpdateChannelsBatchFilters, + members: string[], + ): Promise { + return await this.client.updateChannelsBatch({ + operation: 'demoteModerators', + filter, + members, + }); + } + + /** + * assignRoles - Assign roles to members in channels matching the filter + * + * @param {UpdateChannelsBatchFilters} filter Filter to select channels + * @param {NewMemberPayload[]} members Members with role assignments + * @return {Promise} The server response + */ + async assignRoles( + filter: UpdateChannelsBatchFilters, + members: NewMemberPayload[], + ): Promise { + return await this.client.updateChannelsBatch({ + operation: 'assignRoles', + filter, + members, + }); + } + + // Visibility operations + + /** + * hide - Hide channels matching the filter + * + * @param {UpdateChannelsBatchFilters} filter Filter to select channels + * @return {Promise} The server response + */ + async hide( + filter: UpdateChannelsBatchFilters, + ): Promise { + return await this.client.updateChannelsBatch({ + operation: 'hide', + filter, + }); + } + + /** + * show - Show channels matching the filter + * + * @param {UpdateChannelsBatchFilters} filter Filter to select channels + * @return {Promise} The server response + */ + async show( + filter: UpdateChannelsBatchFilters, + ): Promise { + return await this.client.updateChannelsBatch({ + operation: 'show', + filter, + }); + } + + /** + * archive - Archive channels matching the filter + * + * @param {UpdateChannelsBatchFilters} filter Filter to select channels + * @return {Promise} The server response + */ + async archive( + filter: UpdateChannelsBatchFilters, + ): Promise { + return await this.client.updateChannelsBatch({ + operation: 'archive', + filter, + }); + } + + /** + * unarchive - Unarchive channels matching the filter + * + * @param {UpdateChannelsBatchFilters} filter Filter to select channels + * @return {Promise} The server response + */ + async unarchive( + filter: UpdateChannelsBatchFilters, + ): Promise { + return await this.client.updateChannelsBatch({ + operation: 'unarchive', + filter, + }); + } + + // Data operations + + /** + * updateData - Update data on channels matching the filter + * + * @param {UpdateChannelsBatchFilters} filter Filter to select channels + * @param {BatchChannelDataUpdate} data Data to update + * @return {Promise} The server response + */ + async updateData( + filter: UpdateChannelsBatchFilters, + data: BatchChannelDataUpdate, + ): Promise { + return await this.client.updateChannelsBatch({ + operation: 'updateData', + filter, + data, + }); + } + + /** + * addFilterTags - Add filter tags to channels matching the filter + * + * @param {UpdateChannelsBatchFilters} filter Filter to select channels + * @param {string[]} tags Tags to add + * @return {Promise} The server response + */ + async addFilterTags( + filter: UpdateChannelsBatchFilters, + tags: string[], + ): Promise { + return await this.client.updateChannelsBatch({ + operation: 'addFilterTags', + filter, + filter_tags_update: tags, + }); + } + + /** + * removeFilterTags - Remove filter tags from channels matching the filter + * + * @param {UpdateChannelsBatchFilters} filter Filter to select channels + * @param {string[]} tags Tags to remove + * @return {Promise} The server response + */ + async removeFilterTags( + filter: UpdateChannelsBatchFilters, + tags: string[], + ): Promise { + return await this.client.updateChannelsBatch({ + operation: 'removeFilterTags', + filter, + filter_tags_update: tags, + }); + } +} diff --git a/src/client.ts b/src/client.ts index d44a8d8dd..959c338c3 100644 --- a/src/client.ts +++ b/src/client.ts @@ -13,6 +13,7 @@ import { CheckSignature, DevToken, JWTUserToken } from './signing'; import { TokenManager } from './token_manager'; import { WSConnectionFallback } from './connection_fallback'; import { Campaign } from './campaign'; +import { ChannelBatchUpdater } from './channel_batch_updater'; import { Segment } from './segment'; import { isErrorResponse, isWSFailure } from './errors'; import { @@ -209,6 +210,8 @@ import type { TokenOrProvider, TranslateResponse, UnBanUserOptions, + UpdateChannelsBatchOptions, + UpdateChannelsBatchResponse, UpdateChannelTypeRequest, UpdateChannelTypeResponse, UpdateCommandOptions, @@ -3746,6 +3749,15 @@ export class StreamChat { return new Campaign(this, idOrData, data); } + /** + * channelBatchUpdater - Returns a ChannelBatchUpdater instance for batch channel operations + * + * @return {ChannelBatchUpdater} A ChannelBatchUpdater instance + */ + channelBatchUpdater() { + return new ChannelBatchUpdater(this); + } + segment(type: SegmentType, idOrData: string | SegmentData, data?: SegmentData) { if (typeof idOrData === 'string') { return new Segment(this, type, idOrData, data); @@ -4792,4 +4804,17 @@ export class StreamChat { syncDeliveredCandidates(collections: Channel[]) { this.messageDeliveryReporter.syncDeliveredCandidates(collections); } + + /** + * Update Channels Batch + * + * @param {UpdateChannelsBatchOptions} payload for updating channels in batch + * @return {Promise} The server response + */ + async updateChannelsBatch(payload: UpdateChannelsBatchOptions) { + return await this.put( + this.baseURL + `/channels/batch`, + payload, + ); + } } diff --git a/src/index.ts b/src/index.ts index 5f5daf375..805a12979 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,6 @@ export * from './base64'; export * from './campaign'; +export * from './channel_batch_updater'; export * from './client'; export * from './client_state'; export * from './channel'; diff --git a/src/types.ts b/src/types.ts index 0a621d0ed..f823bca68 100644 --- a/src/types.ts +++ b/src/types.ts @@ -4495,3 +4495,52 @@ export type EventHook = { created_at?: string; updated_at?: string; }; + +export type BatchUpdateOperation = + | 'addMembers' + | 'removeMembers' + | 'invites' + | 'assignRoles' + | 'addModerators' + | 'demoteModerators' + | 'hide' + | 'show' + | 'archive' + | 'unarchive' + | 'updateData' + | 'addFilterTags' + | 'removeFilterTags'; + +export type BatchChannelDataUpdate = { + frozen?: boolean; + disabled?: boolean; + custom?: Record; + team?: string; + config_overrides?: Record; + auto_translation_enabled?: boolean; + auto_translation_language?: string; +}; + +export type UpdateChannelsBatchOptions = { + operation: BatchUpdateOperation; + filter: UpdateChannelsBatchFilters; + members?: string[] | Array; + data?: BatchChannelDataUpdate; + filter_tags_update?: string[]; +}; + +export type UpdateChannelsBatchFilters = QueryFilters<{ + cids?: + | RequireOnlyOne, '$in' | '$eq'>> + | PrimitiveFilter; + types?: + | RequireOnlyOne, '$in' | '$eq'>> + | PrimitiveFilter; + filter_tags?: + | RequireOnlyOne, '$in' | '$eq'>> + | PrimitiveFilter>; +}>; + +export type UpdateChannelsBatchResponse = { + result: Record; +} & Partial;