diff --git a/package.json b/package.json index 9c74c24..d46e1a6 100644 --- a/package.json +++ b/package.json @@ -73,6 +73,7 @@ "@types/jsonwebtoken": "^9.0.3", "@types/node": "^20.11.24", "jsonwebtoken": "^9.0.2", + "undici": "^5.29.0", "uuid": "^9.0.1" }, "peerDependencies": { diff --git a/src/BaseApi.ts b/src/BaseApi.ts index 0c0c857..691c3dd 100644 --- a/src/BaseApi.ts +++ b/src/BaseApi.ts @@ -2,9 +2,14 @@ import { v4 as uuidv4 } from 'uuid'; import { ApiConfig, RequestMetadata, StreamError } from './types'; import { APIError } from './gen/models'; import { getRateLimitFromResponseHeader } from './utils/rate-limit'; +import { Agent } from 'undici'; export class BaseApi { - constructor(protected readonly apiConfig: ApiConfig) {} + private readonly dispatcher: Agent; + + constructor(protected readonly apiConfig: ApiConfig) { + this.dispatcher = this.apiConfig.agent; + } protected sendRequest = async ( method: string, @@ -21,6 +26,7 @@ export class BaseApi { url = url.replace(`{${paramName}}`, pathParams[paramName]); }); } + url += `?${encodedParams}`; const clientRequestId = uuidv4(); const headers = { @@ -40,6 +46,8 @@ export class BaseApi { method, body: JSON.stringify(body), headers, + /** @ts-expect-error we get types from DOM here, but we should use node types */ + dispatcher: this.dispatcher, }); const responseHeaders = response.headers; diff --git a/src/StreamClient.ts b/src/StreamClient.ts index 6c39004..6313e22 100644 --- a/src/StreamClient.ts +++ b/src/StreamClient.ts @@ -6,10 +6,15 @@ import { StreamChatClient } from './StreamChatClient'; import { CallTokenPayload, UserTokenPayload } from './types'; import { QueryBannedUsersPayload, UserRequest } from './gen/models'; import { StreamModerationClient } from './StreamModerationClient'; +import { Agent } from 'undici'; export interface StreamClientOptions { timeout?: number; basePath?: string; + /** The max number of clients to create. `null` if no limit. Default is 100. Has no effect if `agent` is provided. */ + maxConnections?: number | null; + /** The [HTTP Agent](https://undici.nodejs.org/#/docs/api/Agent.md) to use. */ + agent?: Agent; } export class StreamClient extends CommonApi { @@ -19,6 +24,7 @@ export class StreamClient extends CommonApi { public readonly options: StreamClientOptions = {}; private static readonly DEFAULT_TIMEOUT = 3000; + private static readonly MAX_CONNECTIONS = 100; /** * @@ -33,9 +39,17 @@ export class StreamClient extends CommonApi { ) { const token = JWTServerToken(secret); const timeout = config?.timeout ?? StreamClient.DEFAULT_TIMEOUT; + const agent = + config?.agent ?? + new Agent({ + connections: + config?.maxConnections === undefined + ? StreamClient.MAX_CONNECTIONS + : config.maxConnections, + }); const chatBaseUrl = config?.basePath ?? 'https://chat.stream-io-api.com'; const videoBaseUrl = config?.basePath ?? 'https://video.stream-io-api.com'; - super({ apiKey, token, timeout, baseUrl: chatBaseUrl }); + super({ apiKey, token, timeout, baseUrl: chatBaseUrl, agent }); this.video = new StreamVideoClient({ streamClient: this, @@ -43,18 +57,21 @@ export class StreamClient extends CommonApi { token, timeout, baseUrl: videoBaseUrl, + agent, }); this.chat = new StreamChatClient({ apiKey, token, timeout, baseUrl: chatBaseUrl, + agent, }); this.moderation = new StreamModerationClient({ apiKey, token, timeout, baseUrl: chatBaseUrl, + agent, }); } diff --git a/src/gen/chat/ChannelApi.ts b/src/gen/chat/ChannelApi.ts index 4a655a9..c6e8e3a 100644 --- a/src/gen/chat/ChannelApi.ts +++ b/src/gen/chat/ChannelApi.ts @@ -7,6 +7,7 @@ import { EventResponse, FileUploadRequest, FileUploadResponse, + GetDraftResponse, GetManyMessagesResponse, HideChannelRequest, HideChannelResponse, @@ -83,6 +84,34 @@ export class ChannelApi { }); }; + deleteDraft = (request?: { + parent_id?: string; + user_id?: string; + }): Promise> => { + if (!this.id) { + throw new Error( + `Channel isn't yet created, call getOrCreateDistinctChannel() before this operation`, + ); + } + return this.chatApi.deleteDraft({ + id: this.id, + type: this.type, + ...request, + }); + }; + + getDraft = (request?: { + parent_id?: string; + user_id?: string; + }): Promise> => { + if (!this.id) { + throw new Error( + `Channel isn't yet created, call getOrCreateDistinctChannel() before this operation`, + ); + } + return this.chatApi.getDraft({ id: this.id, type: this.type, ...request }); + }; + sendEvent = ( request: SendEventRequest, ): Promise> => { diff --git a/src/gen/chat/ChatApi.ts b/src/gen/chat/ChatApi.ts index f86f544..ea6cab8 100644 --- a/src/gen/chat/ChatApi.ts +++ b/src/gen/chat/ChatApi.ts @@ -27,6 +27,7 @@ import { GetCampaignResponse, GetChannelTypeResponse, GetCommandResponse, + GetDraftResponse, GetManyMessagesResponse, GetMessageResponse, GetReactionsResponse, @@ -58,6 +59,8 @@ import { QueryCampaignsResponse, QueryChannelsRequest, QueryChannelsResponse, + QueryDraftsRequest, + QueryDraftsResponse, QueryMembersPayload, QueryMessageFlagsPayload, QueryMessageFlagsResponse, @@ -129,6 +132,7 @@ export class ChatApi extends BaseApi { limit: request?.limit, next: request?.next, prev: request?.prev, + user_limit: request?.user_limit, sort: request?.sort, filter: request?.filter, }; @@ -144,14 +148,22 @@ export class ChatApi extends BaseApi { getCampaign = async (request: { id: string; + prev?: string; + next?: string; + limit?: number; }): Promise> => { + const queryParams = { + prev: request?.prev, + next: request?.next, + limit: request?.limit, + }; const pathParams = { id: request?.id, }; const response = await this.sendRequest< StreamResponse - >('GET', '/api/v2/chat/campaigns/{id}', pathParams, undefined); + >('GET', '/api/v2/chat/campaigns/{id}', pathParams, queryParams); decoders.GetCampaignResponse?.(response.body); @@ -378,6 +390,60 @@ export class ChatApi extends BaseApi { return { ...response.body, metadata: response.metadata }; }; + deleteDraft = async (request: { + type: string; + id: string; + parent_id?: string; + user_id?: string; + }): Promise> => { + const queryParams = { + parent_id: request?.parent_id, + user_id: request?.user_id, + }; + const pathParams = { + type: request?.type, + id: request?.id, + }; + + const response = await this.sendRequest>( + 'DELETE', + '/api/v2/chat/channels/{type}/{id}/draft', + pathParams, + queryParams, + ); + + decoders.Response?.(response.body); + + return { ...response.body, metadata: response.metadata }; + }; + + getDraft = async (request: { + type: string; + id: string; + parent_id?: string; + user_id?: string; + }): Promise> => { + const queryParams = { + parent_id: request?.parent_id, + user_id: request?.user_id, + }; + const pathParams = { + type: request?.type, + id: request?.id, + }; + + const response = await this.sendRequest>( + 'GET', + '/api/v2/chat/channels/{type}/{id}/draft', + pathParams, + queryParams, + ); + + decoders.GetDraftResponse?.(response.body); + + return { ...response.body, metadata: response.metadata }; + }; + sendEvent = async ( request: SendEventRequest & { type: string; id: string }, ): Promise> => { @@ -991,6 +1057,28 @@ export class ChatApi extends BaseApi { return { ...response.body, metadata: response.metadata }; }; + queryDrafts = async ( + request?: QueryDraftsRequest, + ): Promise> => { + const body = { + limit: request?.limit, + next: request?.next, + prev: request?.prev, + user_id: request?.user_id, + sort: request?.sort, + filter: request?.filter, + user: request?.user, + }; + + const response = await this.sendRequest< + StreamResponse + >('POST', '/api/v2/chat/drafts/query', undefined, undefined, body); + + decoders.QueryDraftsResponse?.(response.body); + + return { ...response.body, metadata: response.metadata }; + }; + exportChannels = async ( request: ExportChannelsRequest, ): Promise> => { diff --git a/src/gen/model-decoders/index.ts b/src/gen/model-decoders/index.ts index 29c6b70..d2d654d 100644 --- a/src/gen/model-decoders/index.ts +++ b/src/gen/model-decoders/index.ts @@ -435,6 +435,8 @@ decoders.ChannelStateResponse = (input?: Record) => { channel: { type: 'ChannelResponse', isSingle: true }, + draft: { type: 'DraftResponse', isSingle: true }, + membership: { type: 'ChannelMember', isSingle: true }, push_preferences: { type: 'ChannelPushPreferences', isSingle: true }, @@ -462,6 +464,8 @@ decoders.ChannelStateResponseFields = (input?: Record) => { channel: { type: 'ChannelResponse', isSingle: true }, + draft: { type: 'DraftResponse', isSingle: true }, + membership: { type: 'ChannelMember', isSingle: true }, push_preferences: { type: 'ChannelPushPreferences', isSingle: true }, @@ -616,6 +620,28 @@ decoders.DeviceResponse = (input?: Record) => { return decode(typeMappings, input); }; +decoders.DraftPayloadResponse = (input?: Record) => { + const typeMappings: TypeMapping = { + mentioned_users: { type: 'UserResponse', isSingle: false }, + }; + return decode(typeMappings, input); +}; + +decoders.DraftResponse = (input?: Record) => { + const typeMappings: TypeMapping = { + created_at: { type: 'DatetimeType', isSingle: true }, + + message: { type: 'DraftPayloadResponse', isSingle: true }, + + channel: { type: 'ChannelResponse', isSingle: true }, + + parent_message: { type: 'MessageResponse', isSingle: true }, + + quoted_message: { type: 'MessageResponse', isSingle: true }, + }; + return decode(typeMappings, input); +}; + decoders.EgressRTMPResponse = (input?: Record) => { const typeMappings: TypeMapping = { started_at: { type: 'DatetimeType', isSingle: true }, @@ -688,7 +714,7 @@ decoders.ExportUserResponse = (input?: Record) => { return decode(typeMappings, input); }; -decoders.Flag2 = (input?: Record) => { +decoders.Flag = (input?: Record) => { const typeMappings: TypeMapping = { created_at: { type: 'DatetimeType', isSingle: true }, @@ -699,17 +725,6 @@ decoders.Flag2 = (input?: Record) => { return decode(typeMappings, input); }; -decoders.Flag2Response = (input?: Record) => { - const typeMappings: TypeMapping = { - created_at: { type: 'DatetimeType', isSingle: true }, - - updated_at: { type: 'DatetimeType', isSingle: true }, - - user: { type: 'UserResponse', isSingle: true }, - }; - return decode(typeMappings, input); -}; - decoders.FlagDetails = (input?: Record) => { const typeMappings: TypeMapping = { automod: { type: 'AutomodDetails', isSingle: true }, @@ -788,13 +803,6 @@ decoders.GetCallTypeResponse = (input?: Record) => { return decode(typeMappings, input); }; -decoders.GetCampaignResponse = (input?: Record) => { - const typeMappings: TypeMapping = { - campaign: { type: 'CampaignResponse', isSingle: true }, - }; - return decode(typeMappings, input); -}; - decoders.GetChannelTypeResponse = (input?: Record) => { const typeMappings: TypeMapping = { created_at: { type: 'DatetimeType', isSingle: true }, @@ -822,6 +830,13 @@ decoders.GetConfigResponse = (input?: Record) => { return decode(typeMappings, input); }; +decoders.GetDraftResponse = (input?: Record) => { + const typeMappings: TypeMapping = { + draft: { type: 'DraftResponse', isSingle: true }, + }; + return decode(typeMappings, input); +}; + decoders.GetImportResponse = (input?: Record) => { const typeMappings: TypeMapping = { import_task: { type: 'ImportTask', isSingle: true }, @@ -898,17 +913,6 @@ decoders.GetThreadResponse = (input?: Record) => { return decode(typeMappings, input); }; -decoders.GetUserModerationReportResponse = (input?: Record) => { - const typeMappings: TypeMapping = { - user_blocks: { type: 'UserBlock', isSingle: false }, - - user_mutes: { type: 'UserMute', isSingle: false }, - - user: { type: 'UserResponse', isSingle: true }, - }; - return decode(typeMappings, input); -}; - decoders.GoLiveResponse = (input?: Record) => { const typeMappings: TypeMapping = { call: { type: 'CallResponse', isSingle: true }, @@ -1146,6 +1150,8 @@ decoders.MessageResponse = (input?: Record) => { thread_participants: { type: 'UserResponse', isSingle: false }, + draft: { type: 'DraftResponse', isSingle: true }, + pinned_by: { type: 'UserResponse', isSingle: true }, poll: { type: 'PollResponseData', isSingle: true }, @@ -1183,6 +1189,8 @@ decoders.MessageWithChannelResponse = (input?: Record) => { thread_participants: { type: 'UserResponse', isSingle: false }, + draft: { type: 'DraftResponse', isSingle: true }, + pinned_by: { type: 'UserResponse', isSingle: true }, poll: { type: 'PollResponseData', isSingle: true }, @@ -1194,15 +1202,6 @@ decoders.MessageWithChannelResponse = (input?: Record) => { return decode(typeMappings, input); }; -decoders.ModerationUsageStats = (input?: Record) => { - const typeMappings: TypeMapping = { - reference_date: { type: 'DatetimeType', isSingle: true }, - - updated_at: { type: 'DatetimeType', isSingle: true }, - }; - return decode(typeMappings, input); -}; - decoders.MuteChannelResponse = (input?: Record) => { const typeMappings: TypeMapping = { channel_mutes: { type: 'ChannelMute', isSingle: false }, @@ -1442,6 +1441,13 @@ decoders.QueryChannelsResponse = (input?: Record) => { return decode(typeMappings, input); }; +decoders.QueryDraftsResponse = (input?: Record) => { + const typeMappings: TypeMapping = { + drafts: { type: 'DraftResponse', isSingle: false }, + }; + return decode(typeMappings, input); +}; + decoders.QueryFeedModerationTemplate = (input?: Record) => { const typeMappings: TypeMapping = { created_at: { type: 'DatetimeType', isSingle: true }, @@ -1530,13 +1536,6 @@ decoders.QueryThreadsResponse = (input?: Record) => { return decode(typeMappings, input); }; -decoders.QueryUsageStatsResponse = (input?: Record) => { - const typeMappings: TypeMapping = { - items: { type: 'ModerationUsageStats', isSingle: false }, - }; - return decode(typeMappings, input); -}; - decoders.QueryUsersResponse = (input?: Record) => { const typeMappings: TypeMapping = { users: { type: 'FullUserResponse', isSingle: false }, @@ -1601,7 +1600,7 @@ decoders.ReviewQueueItem = (input?: Record) => { bans: { type: 'Ban', isSingle: false }, - flags: { type: 'Flag2', isSingle: false }, + flags: { type: 'Flag', isSingle: false }, assigned_to: { type: 'User', isSingle: true }, @@ -1626,8 +1625,6 @@ decoders.ReviewQueueItemResponse = (input?: Record) => { bans: { type: 'Ban', isSingle: false }, - flags: { type: 'Flag2Response', isSingle: false }, - completed_at: { type: 'DatetimeType', isSingle: true }, reviewed_at: { type: 'DatetimeType', isSingle: true }, @@ -1687,6 +1684,8 @@ decoders.SearchResultMessage = (input?: Record) => { channel: { type: 'ChannelResponse', isSingle: true }, + draft: { type: 'DraftResponse', isSingle: true }, + pinned_by: { type: 'UserResponse', isSingle: true }, poll: { type: 'PollResponseData', isSingle: true }, @@ -1743,13 +1742,6 @@ decoders.SendReactionResponse = (input?: Record) => { return decode(typeMappings, input); }; -decoders.StartCampaignResponse = (input?: Record) => { - const typeMappings: TypeMapping = { - campaign: { type: 'CampaignResponse', isSingle: true }, - }; - return decode(typeMappings, input); -}; - decoders.StopLiveResponse = (input?: Record) => { const typeMappings: TypeMapping = { call: { type: 'CallResponse', isSingle: true }, @@ -1820,6 +1812,8 @@ decoders.ThreadStateResponse = (input?: Record) => { created_by: { type: 'UserResponse', isSingle: true }, + draft: { type: 'DraftResponse', isSingle: true }, + parent_message: { type: 'MessageResponse', isSingle: true }, }; return decode(typeMappings, input); @@ -2018,13 +2012,6 @@ decoders.User = (input?: Record) => { return decode(typeMappings, input); }; -decoders.UserBlock = (input?: Record) => { - const typeMappings: TypeMapping = { - created_at: { type: 'DatetimeType', isSingle: true }, - }; - return decode(typeMappings, input); -}; - decoders.UserMute = (input?: Record) => { const typeMappings: TypeMapping = { created_at: { type: 'DatetimeType', isSingle: true }, diff --git a/src/gen/models/index.ts b/src/gen/models/index.ts index 566136a..bd82397 100644 --- a/src/gen/models/index.ts +++ b/src/gen/models/index.ts @@ -300,6 +300,24 @@ export interface AsyncExportErrorEvent { received_at?: Date; } +export interface AsyncExportModerationLogsEvent { + created_at: Date; + + finished_at: Date; + + started_at: Date; + + task_id: string; + + url: string; + + custom: Record; + + type: string; + + received_at?: Date; +} + export interface AsyncExportUsersEvent { created_at: Date; @@ -672,10 +690,6 @@ export interface BlockedUserResponse { user: UserResponse; } -export interface BodyguardImageAnalysisConfig { - rules?: BodyguardRule[]; -} - export interface BodyguardRule { action: | 'flag' @@ -1536,6 +1550,28 @@ export interface CallUpdatedEvent { type: string; } +export interface CallUserFeedbackSubmittedEvent { + call_cid: string; + + created_at: Date; + + rating: number; + + session_id: string; + + user: UserResponse; + + type: string; + + reason?: string; + + sdk?: string; + + sdk_version?: string; + + custom?: Record; +} + export interface CallUserMutedEvent { call_cid: string; @@ -1656,6 +1692,10 @@ export interface CampaignStatsResponse { stats_messages_sent: number; stats_started_at: Date; + + stats_users_read: number; + + stats_users_sent: number; } export interface CastPollVoteRequest { @@ -1691,6 +1731,8 @@ export interface Channel { deleted_at?: Date; + last_campaigns?: string; + last_message_at?: Date; member_count?: number; @@ -2177,6 +2219,8 @@ export interface ChannelStateResponse { channel?: ChannelResponse; + draft?: DraftResponse; + membership?: ChannelMember; push_preferences?: ChannelPushPreferences; @@ -2205,6 +2249,8 @@ export interface ChannelStateResponseFields { channel?: ChannelResponse; + draft?: DraftResponse; + membership?: ChannelMember; push_preferences?: ChannelPushPreferences; @@ -3186,6 +3232,50 @@ export interface DeviceResponse { voip?: boolean; } +export interface DraftPayloadResponse { + id: string; + + text: string; + + custom: Record; + + html?: string; + + mml?: string; + + parent_id?: string; + + poll_id?: string; + + quoted_message_id?: string; + + show_in_channel?: boolean; + + silent?: boolean; + + type?: string; + + attachments?: Attachment[]; + + mentioned_users?: UserResponse[]; +} + +export interface DraftResponse { + channel_cid: string; + + created_at: Date; + + message: DraftPayloadResponse; + + parent_id?: string; + + channel?: ChannelResponse; + + parent_message?: MessageResponse; + + quoted_message?: MessageResponse; +} + export interface EdgeResponse { continent_code: string; @@ -3309,6 +3399,8 @@ export interface EntityCreator { custom: Record; + teams_role: Record; + ban_expires?: Date; created_at?: Date; @@ -3384,6 +3476,8 @@ export interface EntityCreatorResponse { privacy_settings?: PrivacySettingsResponse; push_notifications?: PushNotificationSettingsResponse; + + teams_role?: Record; } export interface ErrorResult { @@ -3545,36 +3639,6 @@ export interface FirebaseConfigFields { export interface Flag { created_at: Date; - created_by_automod: boolean; - - updated_at: Date; - - approved_at?: Date; - - reason?: string; - - rejected_at?: Date; - - reviewed_at?: Date; - - reviewed_by?: string; - - target_message_id?: string; - - custom?: Record; - - details?: FlagDetails; - - target_message?: Message; - - target_user?: User; - - user?: User; -} - -export interface Flag2 { - created_at: Date; - entity_id: string; entity_type: string; @@ -3602,36 +3666,6 @@ export interface Flag2 { user?: User; } -export interface Flag2Response { - created_at: Date; - - entity_id: string; - - entity_type: string; - - updated_at: Date; - - user_id: string; - - result: Array>; - - entity_creator_id?: string; - - reason?: string; - - review_queue_item_id?: string; - - type?: string; - - labels?: string[]; - - custom?: Record; - - moderation_payload?: ModerationPayload; - - user?: UserResponse; -} - export interface FlagDetails { original_text: string; @@ -3782,6 +3816,8 @@ export interface FullUserResponse { latest_hidden_channels?: string[]; privacy_settings?: PrivacySettingsResponse; + + teams_role?: Record; } export interface GeofenceResponse { @@ -3922,6 +3958,8 @@ export interface GetCampaignResponse { duration: string; campaign?: CampaignResponse; + + users?: PagerResponse; } export interface GetChannelTypeResponse { @@ -4020,6 +4058,12 @@ export interface GetCustomPermissionResponse { permission: Permission; } +export interface GetDraftResponse { + duration: string; + + draft: DraftResponse; +} + export interface GetEdgesResponse { duration: string; @@ -4046,18 +4090,6 @@ export interface GetMessageResponse { pending_message_metadata?: Record; } -export interface GetModerationAnalyticsRequest { - end_date?: string; - - start_date?: string; -} - -export interface GetModerationAnalyticsResponse { - duration: string; - - analytics?: ModerationAnalytics; -} - export interface GetOGResponse { duration: string; @@ -4196,16 +4228,6 @@ export interface GetThreadResponse { thread: ThreadStateResponse; } -export interface GetUserModerationReportResponse { - duration: string; - - user_blocks: UserBlock[]; - - user_mutes: UserMute[]; - - user: UserResponse; -} - export interface GoLiveRequest { recording_storage_name?: string; @@ -4898,6 +4920,10 @@ export interface MessageNewEvent { user?: User; } +export interface MessageOptions { + include_thread_participants?: boolean; +} + export interface MessagePaginationParams {} export interface MessageReadEvent { @@ -5027,6 +5053,8 @@ export interface MessageResponse { thread_participants?: UserResponse[]; + draft?: DraftResponse; + i18n?: Record; image_labels?: Record; @@ -5169,6 +5197,8 @@ export interface MessageWithChannelResponse { thread_participants?: UserResponse[]; + draft?: DraftResponse; + i18n?: Record; image_labels?: Record; @@ -5198,34 +5228,6 @@ export interface ModerationActionConfig { custom: Record; } -export interface ModerationAnalytics { - total_items_moderated: number; - - ai_image_harms: Array>; - - ai_text_harms: Array>; - - ai_video_harms: Array>; - - blocklist_by_list: Array>; - - blocklist_matches: Array>; - - model_accuracy: Array>; - - moderator_actions: Array>; - - moderator_productivity: Array>; - - semantic_filter_top_matches: Array>; - - sla_metrics: Array>; - - action_distribution_over_time: Record>; - - detection_by_engine_over_time: Record>; -} - export interface ModerationCustomActionEvent { created_at: Date; @@ -5238,22 +5240,6 @@ export interface ModerationCustomActionEvent { user?: User; } -export interface ModerationEvent { - created_at: Date; - - custom: Record; - - type: string; - - received_at?: Date; - - flags?: Flag2Response[]; - - action?: ActionLogResponse; - - review_queue_item?: ReviewQueueItemResponse; -} - export interface ModerationFlaggedEvent { created_at: Date; @@ -5298,22 +5284,6 @@ export interface ModerationResponse { toxic: number; } -export interface ModerationUsageStats { - app_pk: number; - - id: number; - - organization_id: number; - - reference_date: Date; - - updated_at: Date; - - usage_amount: number; - - usage_type: string; -} - export interface ModerationV2Response { action: string; @@ -5330,20 +5300,6 @@ export interface ModerationV2Response { text_harms?: string[]; } -export interface ModeratorStats { - id: string; - - items_reviewed: number; - - action_counts: Record; -} - -export interface ModeratorStatsResponse { - duration: string; - - moderator_stats: ModeratorStats[]; -} - export interface MuteChannelRequest { expiration?: number; @@ -5564,6 +5520,8 @@ export interface OwnUser { privacy_settings?: PrivacySettings; push_preferences?: PushPreferences; + + teams_role?: Record; } export interface OwnUserResponse { @@ -5620,6 +5578,14 @@ export interface OwnUserResponse { privacy_settings?: PrivacySettingsResponse; push_preferences?: PushPreferences; + + teams_role?: Record; +} + +export interface PagerResponse { + next?: string; + + prev?: string; } export interface PaginationParams { @@ -6239,6 +6205,8 @@ export interface QueryCampaignsRequest { prev?: string; + user_limit?: number; + sort?: SortParamRequest[]; filter?: Record; @@ -6280,6 +6248,32 @@ export interface QueryChannelsResponse { channels: ChannelStateResponseFields[]; } +export interface QueryDraftsRequest { + limit?: number; + + next?: string; + + prev?: string; + + user_id?: string; + + sort?: SortParamRequest[]; + + filter?: Record; + + user?: UserRequest; +} + +export interface QueryDraftsResponse { + duration: string; + + drafts: DraftResponse[]; + + next?: string; + + prev?: string; +} + export interface QueryFeedModerationTemplate { created_at: Date; @@ -6582,32 +6576,6 @@ export interface QueryThreadsResponse { prev?: string; } -export interface QueryUsageStatsRequest { - limit?: number; - - next?: string; - - prev?: string; - - user_id?: string; - - sort?: SortParamRequest[]; - - filter?: Record; - - user?: UserRequest; -} - -export interface QueryUsageStatsResponse { - duration: string; - - items: ModerationUsageStats[]; - - next?: string; - - prev?: string; -} - export interface QueryUserFeedbackRequest { limit?: number; @@ -6654,14 +6622,6 @@ export interface QueryUsersResponse { users: FullUserResponse[]; } -export interface QueueStatsResponse { - avg_time_to_action: number; - - duration: string; - - time_to_action_buckets: Record; -} - export interface RTMPBroadcastRequest { name: string; @@ -6989,6 +6949,8 @@ export interface ReviewQueueItem { entity_type: string; + flags_count: number; + has_image: boolean; has_text: boolean; @@ -7013,7 +6975,7 @@ export interface ReviewQueueItem { bans: Ban[]; - flags: Flag2[]; + flags: Flag[]; languages: string[]; @@ -7038,6 +7000,22 @@ export interface ReviewQueueItem { reaction?: Reaction; } +export interface ReviewQueueItemNewEvent { + created_at: Date; + + custom: Record; + + type: string; + + received_at?: Date; + + flags?: FlagResponse[]; + + action?: ActionLogResponse; + + review_queue_item?: ReviewQueueItemResponse; +} + export interface ReviewQueueItemResponse { ai_text_severity: string; @@ -7047,6 +7025,8 @@ export interface ReviewQueueItemResponse { entity_type: string; + flags_count: number; + id: string; recommended_action: string; @@ -7063,7 +7043,7 @@ export interface ReviewQueueItemResponse { bans: Ban[]; - flags: Flag2Response[]; + flags: FlagResponse[]; languages: string[]; @@ -7092,6 +7072,22 @@ export interface ReviewQueueItemResponse { reaction?: Reaction; } +export interface ReviewQueueItemUpdatedEvent { + created_at: Date; + + custom: Record; + + type: string; + + received_at?: Date; + + flags?: FlagResponse[]; + + action?: ActionLogResponse; + + review_queue_item?: ReviewQueueItemResponse; +} + export interface RingSettings { auto_cancel_timeout_ms: number; @@ -7192,6 +7188,8 @@ export interface SearchPayload { sort?: SortParamRequest[]; message_filter_conditions?: Record; + + message_options?: MessageOptions; } export interface SearchResponse { @@ -7277,6 +7275,8 @@ export interface SearchResultMessage { channel?: ChannelResponse; + draft?: DraftResponse; + i18n?: Record; image_labels?: Record; @@ -7462,6 +7462,8 @@ export interface StartCampaignResponse { duration: string; campaign?: CampaignResponse; + + users?: PagerResponse; } export interface StartClosedCaptionsRequest { @@ -7744,6 +7746,8 @@ export interface ThreadStateResponse { created_by?: UserResponse; + draft?: DraftResponse; + parent_message?: MessageResponse; } @@ -8692,8 +8696,6 @@ export interface UpsertConfigRequest { ai_image_config?: AIImageConfig; - ai_image_lite_config?: BodyguardImageAnalysisConfig; - ai_text_config?: AITextConfig; ai_video_config?: AIVideoConfig; @@ -8777,6 +8779,8 @@ export interface User { custom: Record; + teams_role: Record; + ban_expires?: Date; created_at?: Date; @@ -8826,14 +8830,6 @@ export interface UserBannedEvent { user?: User; } -export interface UserBlock { - blocked_by_user_id: string; - - blocked_user_id: string; - - created_at: Date; -} - export interface UserCustomEventRequest { type: string; @@ -8986,6 +8982,8 @@ export interface UserRequest { custom?: Record; privacy_settings?: PrivacySettingsResponse; + + teams_role?: Record; } export interface UserResponse { @@ -9032,6 +9030,8 @@ export interface UserResponse { privacy_settings?: PrivacySettingsResponse; push_notifications?: PushNotificationSettingsResponse; + + teams_role?: Record; } export interface UserResponseCommonFields { @@ -9066,6 +9066,8 @@ export interface UserResponseCommonFields { name?: string; revoke_tokens_issued_before?: Date; + + teams_role?: Record; } export interface UserResponsePrivacyFields { @@ -9104,6 +9106,8 @@ export interface UserResponsePrivacyFields { revoke_tokens_issued_before?: Date; privacy_settings?: PrivacySettingsResponse; + + teams_role?: Record; } export interface UserSessionStats { @@ -9311,12 +9315,16 @@ export interface VelocityFilterConfigRule { ip_ban: boolean; + probation_period: number; + shadow_ban: boolean; slow_spam_threshold: number; slow_spam_ttl: number; + url_only: boolean; + slow_spam_ban_duration?: number; } diff --git a/src/gen/moderation/ModerationApi.ts b/src/gen/moderation/ModerationApi.ts index 7552679..1a03b81 100644 --- a/src/gen/moderation/ModerationApi.ts +++ b/src/gen/moderation/ModerationApi.ts @@ -12,11 +12,7 @@ import { FlagRequest, FlagResponse, GetConfigResponse, - GetModerationAnalyticsRequest, - GetModerationAnalyticsResponse, GetReviewQueueItemResponse, - GetUserModerationReportResponse, - ModeratorStatsResponse, MuteRequest, MuteResponse, QueryFeedModerationTemplatesResponse, @@ -26,9 +22,6 @@ import { QueryModerationLogsResponse, QueryReviewQueueRequest, QueryReviewQueueResponse, - QueryUsageStatsRequest, - QueryUsageStatsResponse, - QueueStatsResponse, SubmitActionRequest, SubmitActionResponse, UnbanRequest, @@ -43,23 +36,6 @@ import { import { decoders } from '../model-decoders'; export class ModerationApi extends BaseApi { - getModerationAnalytics = async ( - request?: GetModerationAnalyticsRequest, - ): Promise> => { - const body = { - end_date: request?.end_date, - start_date: request?.start_date, - }; - - const response = await this.sendRequest< - StreamResponse - >('POST', '/api/v2/moderation/analytics', undefined, undefined, body); - - decoders.GetModerationAnalyticsResponse?.(response.body); - - return { ...response.body, metadata: response.metadata }; - }; - ban = async (request: BanRequest): Promise> => { const body = { target_user_id: request?.target_user_id, @@ -123,7 +99,6 @@ export class ModerationApi extends BaseApi { team: request?.team, user_id: request?.user_id, ai_image_config: request?.ai_image_config, - ai_image_lite_config: request?.ai_image_lite_config, ai_text_config: request?.ai_text_config, ai_video_config: request?.ai_video_config, automod_platform_circumvention_config: @@ -340,18 +315,6 @@ export class ModerationApi extends BaseApi { return { ...response.body, metadata: response.metadata }; }; - getModeratorStats = async (): Promise< - StreamResponse - > => { - const response = await this.sendRequest< - StreamResponse - >('GET', '/api/v2/moderation/moderator_stats', undefined, undefined); - - decoders.ModeratorStatsResponse?.(response.body); - - return { ...response.body, metadata: response.metadata }; - }; - mute = async ( request: MuteRequest, ): Promise> => { @@ -375,19 +338,6 @@ export class ModerationApi extends BaseApi { return { ...response.body, metadata: response.metadata }; }; - getQueueStats = async (): Promise> => { - const response = await this.sendRequest>( - 'GET', - '/api/v2/moderation/queue_stats', - undefined, - undefined, - ); - - decoders.QueueStatsResponse?.(response.body); - - return { ...response.body, metadata: response.metadata }; - }; - queryReviewQueue = async ( request?: QueryReviewQueueRequest, ): Promise> => { @@ -508,48 +458,4 @@ export class ModerationApi extends BaseApi { return { ...response.body, metadata: response.metadata }; }; - - queryUsageStats = async ( - request?: QueryUsageStatsRequest, - ): Promise> => { - const body = { - limit: request?.limit, - next: request?.next, - prev: request?.prev, - user_id: request?.user_id, - sort: request?.sort, - filter: request?.filter, - user: request?.user, - }; - - const response = await this.sendRequest< - StreamResponse - >('POST', '/api/v2/moderation/usage_stats', undefined, undefined, body); - - decoders.QueryUsageStatsResponse?.(response.body); - - return { ...response.body, metadata: response.metadata }; - }; - - getUserReport = async (request: { - user_id: string; - create_user_if_not_exists?: boolean; - include_user_mutes?: boolean; - include_user_blocks?: boolean; - }): Promise> => { - const queryParams = { - user_id: request?.user_id, - create_user_if_not_exists: request?.create_user_if_not_exists, - include_user_mutes: request?.include_user_mutes, - include_user_blocks: request?.include_user_blocks, - }; - - const response = await this.sendRequest< - StreamResponse - >('GET', '/api/v2/moderation/user_report', undefined, queryParams); - - decoders.GetUserModerationReportResponse?.(response.body); - - return { ...response.body, metadata: response.metadata }; - }; } diff --git a/src/types.ts b/src/types.ts index 67a4945..701a79e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,10 +1,14 @@ +import { Agent } from 'undici'; + export type OmitTypeId = Omit; export interface ApiConfig { apiKey: string; token: string; baseUrl: string; + /** The timeout for requests in milliseconds. The default is 3000. */ timeout: number; + agent: Agent; } export interface RequestMetadata { diff --git a/yarn.lock b/yarn.lock index 019f145..c32a03e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -271,6 +271,11 @@ resolved "https://registry.npmjs.org/@eslint/js/-/js-8.54.0.tgz" integrity sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ== +"@fastify/busboy@^2.0.0": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.1.tgz#b9da6a878a371829a0502c9b6c1c143ef6663f4d" + integrity sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA== + "@humanwhocodes/config-array@^0.11.13": version "0.11.13" resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz" @@ -365,7 +370,7 @@ consola "^2.15.0" node-fetch "^2.6.1" -"@openai/realtime-api-beta@github:openai/openai-realtime-api-beta#a5cb94824f625423858ebacb9f769226ca98945f": +"@openai/realtime-api-beta@openai/openai-realtime-api-beta#a5cb94824f625423858ebacb9f769226ca98945f": version "0.0.0" resolved "https://codeload.github.com/openai/openai-realtime-api-beta/tar.gz/a5cb94824f625423858ebacb9f769226ca98945f" dependencies: @@ -524,11 +529,11 @@ integrity sha512-LT+OIXpp2kj4E2S/p91BMe+VgGX2+lfO+XTpfXhh+bCk2LkQtHZSub8ewFBMGP5ClysPjTDFa4sMI8Q3n4T0wg== "@types/node@^20.11.24": - version "20.11.24" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.24.tgz#cc207511104694e84e9fb17f9a0c4c42d4517792" - integrity sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long== + version "20.17.30" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.17.30.tgz#1d93f656d3b869dbef7b796568ac457606ba58d0" + integrity sha512-7zf4YyHA+jvBNfVrk2Gtvs6x7E8V+YDW05bNfG2XkWDJfYRXrTiP/DsB2zSYTaHX0bGIujTBQdMVAhb+j7mwpg== dependencies: - undici-types "~5.26.4" + undici-types "~6.19.2" "@types/semver@^7.5.0": version "7.5.6" @@ -3311,10 +3316,17 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" -undici-types@~5.26.4: - version "5.26.5" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" - integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== +undici-types@~6.19.2: + version "6.19.8" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" + integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== + +undici@^5.29.0: + version "5.29.0" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.29.0.tgz#419595449ae3f2cdcba3580a2e8903399bd1f5a3" + integrity sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg== + dependencies: + "@fastify/busboy" "^2.0.0" universalify@^2.0.0: version "2.0.0"