stream-chat 8.17.0 → 8.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/client.ts CHANGED
@@ -11,6 +11,8 @@ import { StableWSConnection } from './connection';
11
11
  import { CheckSignature, DevToken, JWTUserToken } from './signing';
12
12
  import { TokenManager } from './token_manager';
13
13
  import { WSConnectionFallback } from './connection_fallback';
14
+ import { Campaign } from './campaign';
15
+ import { Segment } from './segment';
14
16
  import { isErrorResponse, isWSFailure } from './errors';
15
17
  import {
16
18
  addFileToFormData,
@@ -38,7 +40,7 @@ import {
38
40
  BaseDeviceFields,
39
41
  BlockList,
40
42
  BlockListResponse,
41
- Campaign,
43
+ CampaignResponse,
42
44
  CampaignData,
43
45
  CampaignFilters,
44
46
  CampaignQueryOptions,
@@ -65,7 +67,6 @@ import {
65
67
  CustomPermissionOptions,
66
68
  DeactivateUsersOptions,
67
69
  DefaultGenerics,
68
- DeleteCampaignOptions,
69
70
  DeleteChannelsResponse,
70
71
  DeleteCommandResponse,
71
72
  DeleteUserOptions,
@@ -136,7 +137,7 @@ import {
136
137
  SearchMessageSortBase,
137
138
  SearchOptions,
138
139
  SearchPayload,
139
- Segment,
140
+ SegmentResponse,
140
141
  SegmentData,
141
142
  SegmentType,
142
143
  SendFileAPIResponse,
@@ -145,7 +146,6 @@ import {
145
146
  SyncResponse,
146
147
  TaskResponse,
147
148
  TaskStatus,
148
- TestCampaignResponse,
149
149
  TestPushDataInput,
150
150
  TestSNSDataInput,
151
151
  TestSQSDataInput,
@@ -168,6 +168,10 @@ import {
168
168
  PartialThreadUpdate,
169
169
  QueryThreadsOptions,
170
170
  GetThreadOptions,
171
+ CampaignSort,
172
+ SegmentTargetsResponse,
173
+ QuerySegmentTargetsFilter,
174
+ SortParam,
171
175
  } from './types';
172
176
  import { InsightMetrics, postInsights } from './insights';
173
177
  import { Thread } from './thread';
@@ -2943,6 +2947,30 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
2943
2947
  return this.get<APIResponse & ExportChannelStatusResponse>(`${this.baseURL}/export_channels/${id}`);
2944
2948
  }
2945
2949
 
2950
+ campaign(idOrData: string | CampaignData, data?: CampaignData) {
2951
+ if (typeof idOrData === 'string') {
2952
+ return new Campaign(this, idOrData, data);
2953
+ }
2954
+
2955
+ return new Campaign(this, null, idOrData);
2956
+ }
2957
+
2958
+ segment(type: SegmentType, idOrData: string | SegmentData, data?: SegmentData) {
2959
+ if (typeof idOrData === 'string') {
2960
+ return new Segment(this, type, idOrData, data);
2961
+ }
2962
+
2963
+ return new Segment(this, type, null, idOrData);
2964
+ }
2965
+
2966
+ validateServerSideAuth() {
2967
+ if (!this.secret) {
2968
+ throw new Error(
2969
+ 'Campaigns is a server-side only feature. Please initialize the client with a secret to use this feature.',
2970
+ );
2971
+ }
2972
+ }
2973
+
2946
2974
  /**
2947
2975
  * createSegment - Creates a segment
2948
2976
  *
@@ -2952,17 +2980,17 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
2952
2980
  * @param {string} name Segment name (valid UUID)
2953
2981
  * @param {SegmentData} params Segment data
2954
2982
  *
2955
- * @return {Segment} The created Segment
2983
+ * @return {{segment: SegmentResponse} & APIResponse} The created Segment
2956
2984
  */
2957
- private async createSegment(type: SegmentType, id: string, name: string, data?: SegmentData): Promise<Segment> {
2985
+ private async createSegment(type: SegmentType, id: string, name: string, data?: SegmentData) {
2986
+ this.validateServerSideAuth();
2958
2987
  const body = {
2959
2988
  id,
2960
2989
  type,
2961
2990
  name,
2962
2991
  data,
2963
2992
  };
2964
- const { segment } = await this.post<{ segment: Segment }>(this.baseURL + `/segments`, body);
2965
- return segment;
2993
+ return this.post<{ segment: SegmentResponse }>(this.baseURL + `/segments`, body);
2966
2994
  }
2967
2995
 
2968
2996
  /**
@@ -2974,8 +3002,9 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
2974
3002
  *
2975
3003
  * @return {Segment} The created Segment
2976
3004
  */
2977
- async createUserSegment(id: string, name: string, data?: SegmentData): Promise<Segment> {
2978
- return await this.createSegment('user', id, name, data);
3005
+ async createUserSegment(id: string, name: string, data?: SegmentData) {
3006
+ this.validateServerSideAuth();
3007
+ return this.createSegment('user', id, name, data);
2979
3008
  }
2980
3009
 
2981
3010
  /**
@@ -2987,8 +3016,14 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
2987
3016
  *
2988
3017
  * @return {Segment} The created Segment
2989
3018
  */
2990
- async createChannelSegment(id: string, name: string, data?: SegmentData): Promise<Segment> {
2991
- return await this.createSegment('channel', id, name, data);
3019
+ async createChannelSegment(id: string, name: string, data?: SegmentData) {
3020
+ this.validateServerSideAuth();
3021
+ return this.createSegment('channel', id, name, data);
3022
+ }
3023
+
3024
+ async getSegment(id: string) {
3025
+ this.validateServerSideAuth();
3026
+ return this.get<{ segment: SegmentResponse } & APIResponse>(this.baseURL + `/segments/${id}`);
2992
3027
  }
2993
3028
 
2994
3029
  /**
@@ -3000,8 +3035,8 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
3000
3035
  * @return {Segment} Updated Segment
3001
3036
  */
3002
3037
  async updateSegment(id: string, data: Partial<UpdateSegmentData>) {
3003
- const { segment } = await this.put<{ segment: Segment }>(this.baseURL + `/segments/${id}`, data);
3004
- return segment;
3038
+ this.validateServerSideAuth();
3039
+ return this.put<{ segment: SegmentResponse }>(this.baseURL + `/segments/${id}`, data);
3005
3040
  }
3006
3041
 
3007
3042
  /**
@@ -3013,21 +3048,39 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
3013
3048
  * @return {APIResponse} API response
3014
3049
  */
3015
3050
  async addSegmentTargets(id: string, targets: string[]) {
3016
- const body = { targets };
3017
- return await this.post<APIResponse>(this.baseURL + `/segments/${id}/addtargets`, body);
3051
+ this.validateServerSideAuth();
3052
+ const body = { target_ids: targets };
3053
+ return this.post<APIResponse>(this.baseURL + `/segments/${id}/addtargets`, body);
3018
3054
  }
3019
3055
 
3056
+ async querySegmentTargets(
3057
+ id: string,
3058
+ filter: QuerySegmentTargetsFilter | null = {},
3059
+ sort: SortParam[] | null | [] = [],
3060
+ options = {},
3061
+ ) {
3062
+ this.validateServerSideAuth();
3063
+ return this.post<{ targets: SegmentTargetsResponse[]; next?: string } & APIResponse>(
3064
+ this.baseURL + `/segments/${id}/targets/query`,
3065
+ {
3066
+ filter: filter || {},
3067
+ sort: sort || [],
3068
+ ...options,
3069
+ },
3070
+ );
3071
+ }
3020
3072
  /**
3021
- * deleteSegmentTargets - Delete targets from a segment
3073
+ * removeSegmentTargets - Remove targets from a segment
3022
3074
  *
3023
3075
  * @param {string} id Segment ID
3024
3076
  * @param {string[]} targets Targets to add to the segment
3025
3077
  *
3026
3078
  * @return {APIResponse} API response
3027
3079
  */
3028
- async deleteSegmentTargets(id: string, targets: string[]) {
3029
- const body = { targets };
3030
- return await this.post<APIResponse>(this.baseURL + `/segments/${id}/deletetargets`, body);
3080
+ async removeSegmentTargets(id: string, targets: string[]) {
3081
+ this.validateServerSideAuth();
3082
+ const body = { target_ids: targets };
3083
+ return this.post<APIResponse>(this.baseURL + `/segments/${id}/deletetargets`, body);
3031
3084
  }
3032
3085
 
3033
3086
  /**
@@ -3038,15 +3091,17 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
3038
3091
  *
3039
3092
  * @return {Segment[]} Segments
3040
3093
  */
3041
- async querySegments(filter: {}, options: QuerySegmentsOptions = {}) {
3042
- return await this.get<{
3043
- segments: Segment[];
3044
- next?: string;
3045
- }>(this.baseURL + `/segments`, {
3046
- payload: {
3047
- filter,
3048
- ...options,
3049
- },
3094
+ async querySegments(filter: {}, sort?: SortParam[], options: QuerySegmentsOptions = {}) {
3095
+ this.validateServerSideAuth();
3096
+ return this.post<
3097
+ {
3098
+ segments: SegmentResponse[];
3099
+ next?: string;
3100
+ } & APIResponse
3101
+ >(this.baseURL + `/segments/query`, {
3102
+ filter,
3103
+ sort,
3104
+ ...options,
3050
3105
  });
3051
3106
  }
3052
3107
 
@@ -3058,7 +3113,8 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
3058
3113
  * @return {Promise<APIResponse>} The Server Response
3059
3114
  */
3060
3115
  async deleteSegment(id: string) {
3061
- return await this.delete<APIResponse>(this.baseURL + `/segments/${id}`);
3116
+ this.validateServerSideAuth();
3117
+ return this.delete<APIResponse>(this.baseURL + `/segments/${id}`);
3062
3118
  }
3063
3119
 
3064
3120
  /**
@@ -3070,7 +3126,8 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
3070
3126
  * @return {Promise<APIResponse>} The Server Response
3071
3127
  */
3072
3128
  async segmentTargetExists(segmentId: string, targetId: string) {
3073
- return await this.get<APIResponse>(this.baseURL + `/segments/${segmentId}/target/${targetId}`);
3129
+ this.validateServerSideAuth();
3130
+ return this.get<APIResponse>(this.baseURL + `/segments/${segmentId}/target/${targetId}`);
3074
3131
  }
3075
3132
 
3076
3133
  /**
@@ -3081,27 +3138,38 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
3081
3138
  * @return {Campaign} The Created Campaign
3082
3139
  */
3083
3140
  async createCampaign(params: CampaignData) {
3084
- const { campaign } = await this.post<{ campaign: Campaign }>(this.baseURL + `/campaigns`, { campaign: params });
3085
- return campaign;
3141
+ this.validateServerSideAuth();
3142
+ return this.post<{ campaign: CampaignResponse } & APIResponse>(this.baseURL + `/campaigns`, { ...params });
3143
+ }
3144
+
3145
+ async getCampaign(id: string) {
3146
+ this.validateServerSideAuth();
3147
+ return this.get<{ campaign: CampaignResponse } & APIResponse>(this.baseURL + `/campaigns/${id}`);
3086
3148
  }
3087
3149
 
3150
+ async startCampaign(id: string, scheduledFor?: string) {
3151
+ this.validateServerSideAuth();
3152
+ return this.post<{ campaign: CampaignResponse } & APIResponse>(this.baseURL + `/campaigns/${id}/start`, {
3153
+ scheduled_for: scheduledFor,
3154
+ });
3155
+ }
3088
3156
  /**
3089
3157
  * queryCampaigns - Query Campaigns
3090
3158
  *
3091
3159
  *
3092
3160
  * @return {Campaign[]} Campaigns
3093
3161
  */
3094
- async queryCampaigns(filters: CampaignFilters, options: CampaignQueryOptions = {}) {
3095
- return await this.get<{
3096
- campaigns: Campaign[];
3162
+ async queryCampaigns(filter: CampaignFilters, sort?: CampaignSort, options?: CampaignQueryOptions) {
3163
+ this.validateServerSideAuth();
3164
+ return await this.post<{
3165
+ campaigns: CampaignResponse[];
3097
3166
  segments: Record<string, Segment>;
3098
3167
  channels?: Record<string, ChannelResponse<StreamChatGenerics>>;
3099
3168
  users?: Record<string, UserResponse<StreamChatGenerics>>;
3100
- }>(this.baseURL + `/campaigns`, {
3101
- payload: {
3102
- filter_conditions: filters,
3103
- ...options,
3104
- },
3169
+ }>(this.baseURL + `/campaigns/query`, {
3170
+ filter,
3171
+ sort,
3172
+ ...(options || {}),
3105
3173
  });
3106
3174
  }
3107
3175
 
@@ -3114,10 +3182,8 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
3114
3182
  * @return {Campaign} Updated Campaign
3115
3183
  */
3116
3184
  async updateCampaign(id: string, params: Partial<CampaignData>) {
3117
- const { campaign } = await this.put<{ campaign: Campaign }>(this.baseURL + `/campaigns/${id}`, {
3118
- campaign: params,
3119
- });
3120
- return campaign;
3185
+ this.validateServerSideAuth();
3186
+ return this.put<{ campaign: CampaignResponse }>(this.baseURL + `/campaigns/${id}`, params);
3121
3187
  }
3122
3188
 
3123
3189
  /**
@@ -3127,24 +3193,9 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
3127
3193
  *
3128
3194
  * @return {Promise<APIResponse>} The Server Response
3129
3195
  */
3130
- async deleteCampaign(id: string, params: DeleteCampaignOptions = {}) {
3131
- return this.delete<APIResponse>(this.baseURL + `/campaigns/${id}`, params);
3132
- }
3133
-
3134
- /**
3135
- * scheduleCampaign - Schedule a Campaign
3136
- *
3137
- * @param {string} id Campaign ID
3138
- * @param {{scheduledFor: number}} params Schedule params
3139
- *
3140
- * @return {Campaign} Scheduled Campaign
3141
- */
3142
- async scheduleCampaign(id: string, params: { scheduledFor: number }) {
3143
- const { scheduledFor } = params;
3144
- const { campaign } = await this.patch<{ campaign: Campaign }>(this.baseURL + `/campaigns/${id}/schedule`, {
3145
- scheduled_for: scheduledFor,
3146
- });
3147
- return campaign;
3196
+ async deleteCampaign(id: string) {
3197
+ this.validateServerSideAuth();
3198
+ return this.delete<APIResponse>(this.baseURL + `/campaigns/${id}`);
3148
3199
  }
3149
3200
 
3150
3201
  /**
@@ -3155,35 +3206,11 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
3155
3206
  * @return {Campaign} Stopped Campaign
3156
3207
  */
3157
3208
  async stopCampaign(id: string) {
3158
- const { campaign } = await this.patch<{ campaign: Campaign }>(this.baseURL + `/campaigns/${id}/stop`);
3159
- return campaign;
3160
- }
3161
-
3162
- /**
3163
- * resumeCampaign - Resume a Campaign
3164
- *
3165
- * @param {string} id Campaign ID
3166
- *
3167
- * @return {Campaign} Resumed Campaign
3168
- */
3169
- async resumeCampaign(id: string) {
3170
- const { campaign } = await this.patch<{ campaign: Campaign }>(this.baseURL + `/campaigns/${id}/resume`);
3209
+ this.validateServerSideAuth();
3210
+ const { campaign } = await this.patch<{ campaign: CampaignResponse }>(this.baseURL + `/campaigns/${id}/stop`);
3171
3211
  return campaign;
3172
3212
  }
3173
3213
 
3174
- /**
3175
- * testCampaign - Test a Campaign
3176
- *
3177
- * @param {string} id Campaign ID
3178
- * @param {{users: string[]}} params Test params
3179
- *
3180
- * @return {TestCampaignResponse} Test campaign response
3181
- */
3182
- async testCampaign(id: string, params: { users: string[] }) {
3183
- const { users } = params;
3184
- return await this.post<APIResponse & TestCampaignResponse>(this.baseURL + `/campaigns/${id}/test`, { users });
3185
- }
3186
-
3187
3214
  /**
3188
3215
  * enrichURL - Get OpenGraph data of the given link
3189
3216
  *
package/src/index.ts CHANGED
@@ -11,4 +11,6 @@ export * from './signing';
11
11
  export * from './token_manager';
12
12
  export * from './insights';
13
13
  export * from './types';
14
+ export * from './segment';
15
+ export * from './campaign';
14
16
  export { isOwnUser, chatCodes, logChatPromiseExecution, formatMessage } from './utils';
package/src/segment.ts ADDED
@@ -0,0 +1,89 @@
1
+ import { StreamChat } from './client';
2
+ import {
3
+ DefaultGenerics,
4
+ ExtendableGenerics,
5
+ QuerySegmentTargetsFilter,
6
+ SegmentData,
7
+ SegmentResponse,
8
+ SortParam,
9
+ } from './types';
10
+
11
+ type SegmentType = 'user' | 'channel';
12
+
13
+ type SegmentUpdatableFields = {
14
+ description?: string;
15
+ filter?: {};
16
+ name?: string;
17
+ };
18
+
19
+ export class Segment<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {
20
+ type: SegmentType;
21
+ id?: string | null;
22
+ client: StreamChat<StreamChatGenerics>;
23
+ data?: SegmentData | SegmentResponse;
24
+
25
+ constructor(client: StreamChat<StreamChatGenerics>, type: SegmentType, id: string | null, data?: SegmentData) {
26
+ this.client = client;
27
+ this.type = type;
28
+ this.id = id;
29
+ this.data = data;
30
+ }
31
+
32
+ async create() {
33
+ const body = {
34
+ id: this.id,
35
+ type: this.type,
36
+ name: this.data?.name,
37
+ filter: this.data?.filter,
38
+ description: this.data?.description,
39
+ all_users: this.data?.all_users,
40
+ };
41
+
42
+ return this.client.post<{ segment: SegmentResponse }>(this.client.baseURL + `/segments`, body);
43
+ }
44
+
45
+ verifySegmentId() {
46
+ if (!this.id) {
47
+ throw new Error(
48
+ 'Segment id is missing. Either create the segment using segment.create() or set the id during instantiation - const segment = client.segment(id)',
49
+ );
50
+ }
51
+ }
52
+
53
+ async get() {
54
+ this.verifySegmentId();
55
+ return this.client.getSegment(this.id as string);
56
+ }
57
+
58
+ async update(data: Partial<SegmentUpdatableFields>) {
59
+ this.verifySegmentId();
60
+
61
+ return this.client.updateSegment(this.id as string, data);
62
+ }
63
+
64
+ async addTargets(targets: string[]) {
65
+ this.verifySegmentId();
66
+ return this.client.addSegmentTargets(this.id as string, targets);
67
+ }
68
+
69
+ async removeTargets(targets: string[]) {
70
+ this.verifySegmentId();
71
+ return this.client.removeSegmentTargets(this.id as string, targets);
72
+ }
73
+
74
+ async delete() {
75
+ this.verifySegmentId();
76
+ return this.client.deleteSegment(this.id as string);
77
+ }
78
+
79
+ async targetExists(targetId: string) {
80
+ this.verifySegmentId();
81
+ return this.client.segmentTargetExists(this.id as string, targetId);
82
+ }
83
+
84
+ async queryTargets(filter: QuerySegmentTargetsFilter | null = {}, sort: SortParam[] | null | [] = [], options = {}) {
85
+ this.verifySegmentId();
86
+
87
+ return this.client.querySegmentTargets(this.id as string, filter, sort, options);
88
+ }
89
+ }
package/src/types.ts CHANGED
@@ -2487,17 +2487,19 @@ export type DeleteUserOptions = {
2487
2487
  export type SegmentType = 'channel' | 'user';
2488
2488
 
2489
2489
  export type SegmentData = {
2490
+ all_users?: boolean;
2490
2491
  description?: string;
2491
2492
  filter?: {};
2493
+ name?: string;
2492
2494
  };
2493
2495
 
2494
- export type Segment = {
2496
+ export type SegmentResponse = {
2495
2497
  created_at: string;
2496
2498
  deleted_at: string;
2497
2499
  id: string;
2498
2500
  locked: boolean;
2499
- name: string;
2500
2501
  size: number;
2502
+ task_id: string;
2501
2503
  type: SegmentType;
2502
2504
  updated_at: string;
2503
2505
  } & SegmentData;
@@ -2506,6 +2508,12 @@ export type UpdateSegmentData = {
2506
2508
  name: string;
2507
2509
  } & SegmentData;
2508
2510
 
2511
+ export type SegmentTargetsResponse = {
2512
+ created_at: string;
2513
+ segment_id: string;
2514
+ target_id: string;
2515
+ };
2516
+
2509
2517
  export type SortParam = {
2510
2518
  field: string;
2511
2519
  direction?: AscDesc;
@@ -2517,10 +2525,18 @@ export type Pager = {
2517
2525
  prev?: string;
2518
2526
  };
2519
2527
 
2520
- export type QuerySegmentsOptions = {
2521
- sort?: SortParam[];
2522
- } & Pager;
2528
+ export type QuerySegmentsOptions = Pager;
2523
2529
 
2530
+ export type QuerySegmentTargetsFilter = {
2531
+ target_id?: {
2532
+ $eq?: string;
2533
+ $gte?: string;
2534
+ $in?: string[];
2535
+ $lte?: string;
2536
+ };
2537
+ };
2538
+ export type QuerySegmentTargetsSort = {};
2539
+ export type QuerySegmentTargetsOptions = Pick<Pager, 'next' | 'limit'>;
2524
2540
  export type CampaignSortField = {
2525
2541
  field: string;
2526
2542
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -2534,6 +2550,8 @@ export type CampaignSort = {
2534
2550
 
2535
2551
  export type CampaignQueryOptions = {
2536
2552
  limit?: number;
2553
+ next?: string;
2554
+ prev?: string;
2537
2555
  sort?: CampaignSort;
2538
2556
  };
2539
2557
 
@@ -2543,14 +2561,25 @@ export type SegmentQueryOptions = CampaignQueryOptions;
2543
2561
  export type CampaignFilters = {};
2544
2562
 
2545
2563
  export type CampaignData = {
2546
- attachments: Attachment[];
2547
- channel_type: string;
2548
- defaults: Record<string, string>;
2549
- name: string;
2550
- segment_id: string;
2551
- text: string;
2564
+ channel_template?: {
2565
+ type: string;
2566
+ custom?: {};
2567
+ id?: string;
2568
+ members?: string[];
2569
+ };
2570
+ create_channels?: boolean;
2571
+ deleted_at?: string;
2552
2572
  description?: string;
2573
+ id?: string | null;
2574
+ message_template?: {
2575
+ text: string;
2576
+ attachments?: Attachment[];
2577
+ custom?: {};
2578
+ };
2579
+ name?: string;
2580
+ segment_ids?: string[];
2553
2581
  sender_id?: string;
2582
+ user_ids?: string[];
2554
2583
  };
2555
2584
 
2556
2585
  export type CampaignStatusName = 'draft' | 'stopped' | 'scheduled' | 'completed' | 'failed' | 'in_progress';
@@ -2568,7 +2597,7 @@ export type CampaignStatus = {
2568
2597
  task_id?: string;
2569
2598
  };
2570
2599
 
2571
- export type Campaign = {
2600
+ export type CampaignResponse = {
2572
2601
  created_at: string;
2573
2602
  id: string;
2574
2603
  updated_at: string;