Skip to content

Commit 726fc79

Browse files
fix: fix the response types for moderation
1 parent c67f68d commit 726fc79

2 files changed

Lines changed: 163 additions & 21 deletions

File tree

src/moderation.ts

Lines changed: 97 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import type {
22
APIResponse,
3+
BlockListResponse,
4+
CheckResponse,
35
CustomCheckFlag,
6+
CustomCheckResponse,
47
GetConfigResponse,
58
GetUserModerationReportOptions,
69
GetUserModerationReportResponse,
@@ -24,6 +27,8 @@ import type {
2427
ReviewQueueResponse,
2528
ReviewQueueSort,
2629
SubmitActionOptions,
30+
SubmitActionResponse,
31+
UnmuteUserResponse,
2732
UpsertConfigResponse,
2833
UpsertModerationRuleResponse,
2934
} from './types';
@@ -135,7 +140,7 @@ export class Moderation {
135140
user_id?: string;
136141
},
137142
) {
138-
return await this.client.post<{ item_id: string } & APIResponse>(
143+
return await this.client.post<UnmuteUserResponse>(
139144
this.client.baseURL + '/api/v2/moderation/unmute',
140145
{
141146
target_ids: [targetID],
@@ -209,7 +214,7 @@ export class Moderation {
209214
}
210215

211216
async deleteConfig(key: string, data?: { team?: string }) {
212-
return await this.client.delete(
217+
return await this.client.delete<APIResponse>(
213218
this.client.baseURL + '/api/v2/moderation/config/' + key,
214219
data,
215220
);
@@ -241,7 +246,7 @@ export class Moderation {
241246
itemID: string,
242247
options: SubmitActionOptions = {},
243248
) {
244-
return await this.client.post<{ item_id: string } & APIResponse>(
249+
return await this.client.post<SubmitActionResponse>(
245250
this.client.baseURL + '/api/v2/moderation/submit_action',
246251
{
247252
action_type: actionType,
@@ -281,14 +286,17 @@ export class Moderation {
281286
test_mode?: boolean;
282287
},
283288
) {
284-
return await this.client.post(this.client.baseURL + `/api/v2/moderation/check`, {
285-
entity_type: entityType,
286-
entity_id: entityID,
287-
entity_creator_id: entityCreatorID,
288-
moderation_payload: moderationPayload,
289-
config_key: configKey,
290-
options,
291-
});
289+
return await this.client.post<CheckResponse>(
290+
this.client.baseURL + `/api/v2/moderation/check`,
291+
{
292+
entity_type: entityType,
293+
entity_id: entityID,
294+
entity_creator_id: entityCreatorID,
295+
moderation_payload: moderationPayload,
296+
config_key: configKey,
297+
options,
298+
},
299+
);
292300
}
293301

294302
/**
@@ -368,15 +376,16 @@ export class Moderation {
368376
},
369377
flags: CustomCheckFlag[],
370378
) {
371-
return await this.client.post<
372-
{ id: string; item: ReviewQueueItem; status: string } & APIResponse
373-
>(this.client.baseURL + `/api/v2/moderation/custom_check`, {
374-
entity_type: entityType,
375-
entity_id: entityID,
376-
entity_creator_id: entityCreatorID,
377-
moderation_payload: moderationPayload,
378-
flags,
379-
});
379+
return await this.client.post<CustomCheckResponse>(
380+
this.client.baseURL + `/api/v2/moderation/custom_check`,
381+
{
382+
entity_type: entityType,
383+
entity_id: entityID,
384+
entity_creator_id: entityCreatorID,
385+
moderation_payload: moderationPayload,
386+
flags,
387+
},
388+
);
380389
}
381390

382391
/**
@@ -446,8 +455,75 @@ export class Moderation {
446455
* @returns
447456
*/
448457
async deleteModerationRule(id: string) {
449-
return await this.client.delete(
458+
return await this.client.delete<APIResponse>(
450459
this.client.baseURL + '/api/v2/moderation/moderation_rule/' + id,
451460
);
452461
}
462+
463+
/**
464+
* Bulk upload a domain blocklist from a URL, S3 path, or file upload
465+
* @param {Object} options Bulk upload options
466+
* @param {string} options.name Name of the blocklist
467+
* @param {string} options.type Type of blocklist ('domains' or 'domain_allowlist')
468+
* @param {string} [options.team] Team ID the blocklist belongs to
469+
* @param {boolean} [options.is_leet_check_enabled] Enable leet check
470+
* @param {boolean} [options.is_plural_check_enabled] Enable plural check
471+
* @param {string} [options.url] Publicly accessible URL to download the domain list from
472+
* @param {string} [options.s3_path] S3 path to the file (e.g., "12345/blocklists/my-list.txt")
473+
* @param {File} [options.file] File to upload (for multipart form data)
474+
* @returns {Promise<APIResponse & {blocklist: BlockListResponse, domain_count: number}>}
475+
*/
476+
async bulkUploadBlockList(options: {
477+
name: string;
478+
type: 'domains' | 'domain_allowlist';
479+
team?: string;
480+
is_leet_check_enabled?: boolean;
481+
is_plural_check_enabled?: boolean;
482+
url?: string;
483+
s3_path?: string;
484+
file?: File;
485+
}): Promise<APIResponse & { blocklist: BlockListResponse; domain_count: number }> {
486+
// If file is provided, use FormData; otherwise use JSON
487+
if (options.file) {
488+
const FormData = require('form-data');
489+
const formData = new FormData();
490+
formData.append('name', options.name);
491+
formData.append('type', options.type);
492+
if (options.team) {
493+
formData.append('team', options.team);
494+
}
495+
if (options.is_leet_check_enabled !== undefined) {
496+
formData.append('is_leet_check_enabled', String(options.is_leet_check_enabled));
497+
}
498+
if (options.is_plural_check_enabled !== undefined) {
499+
formData.append(
500+
'is_plural_check_enabled',
501+
String(options.is_plural_check_enabled),
502+
);
503+
}
504+
formData.append('file', options.file);
505+
506+
return (await (this.client as any).doAxiosRequest(
507+
'postForm',
508+
this.client.baseURL + '/api/v2/blocklists/bulk-upload',
509+
formData,
510+
{
511+
headers: formData.getHeaders ? formData.getHeaders() : {},
512+
},
513+
)) as Promise<APIResponse & { blocklist: any; domain_count: number }>;
514+
} else {
515+
// Use JSON for URL or S3 path
516+
return await this.client.post<
517+
APIResponse & { blocklist: any; domain_count: number }
518+
>(this.client.baseURL + '/api/v2/blocklists/bulk-upload', {
519+
name: options.name,
520+
type: options.type,
521+
team: options.team,
522+
is_leet_check_enabled: options.is_leet_check_enabled,
523+
is_plural_check_enabled: options.is_plural_check_enabled,
524+
url: options.url,
525+
s3_path: options.s3_path,
526+
});
527+
}
528+
}
453529
}

src/types.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -801,6 +801,11 @@ export type MuteUserResponse = APIResponse & {
801801
mute?: MuteResponse;
802802
mutes?: Array<Mute>;
803803
own_user?: OwnUserResponse;
804+
non_existing_users?: string[];
805+
};
806+
807+
export type UnmuteUserResponse = APIResponse & {
808+
non_existing_users?: string[];
804809
};
805810

806811
export type BlockUserAPIResponse = APIResponse & {
@@ -3685,6 +3690,7 @@ export type ReviewQueueItem = {
36853690
reviewed_at: string;
36863691
status: string;
36873692
updated_at: string;
3693+
latest_moderator_action?: string;
36883694
};
36893695

36903696
export type CustomCheckFlag = {
@@ -3726,6 +3732,10 @@ export type SubmitActionOptions = {
37263732
user_id?: string;
37273733
};
37283734

3735+
export type SubmitActionResponse = APIResponse & {
3736+
item?: ReviewQueueItem;
3737+
};
3738+
37293739
export type GetUserModerationReportResponse = {
37303740
user: UserResponse;
37313741
user_blocks?: Array<{
@@ -3736,6 +3746,19 @@ export type GetUserModerationReportResponse = {
37363746
user_mutes?: Mute[];
37373747
};
37383748

3749+
export type CheckResponse = APIResponse & {
3750+
status: string;
3751+
task_id?: string;
3752+
recommended_action: string;
3753+
item?: ReviewQueueItem;
3754+
};
3755+
3756+
export type CustomCheckResponse = APIResponse & {
3757+
id: string;
3758+
item: ReviewQueueItem;
3759+
status: string;
3760+
};
3761+
37393762
export type QueryModerationConfigsFilters = QueryFilters<
37403763
{
37413764
key?: string;
@@ -3787,6 +3810,12 @@ export type ReviewQueueFilters = QueryFilters<
37873810
entity_id?:
37883811
| RequireOnlyOne<Pick<QueryFilter<ReviewQueueItem['entity_id']>, '$eq' | '$in'>>
37893812
| PrimitiveFilter<ReviewQueueItem['entity_id']>;
3813+
} & {
3814+
entity_creator_id?:
3815+
| RequireOnlyOne<
3816+
Pick<QueryFilter<ReviewQueueItem['entity_creator_id']>, '$eq' | '$in'>
3817+
>
3818+
| PrimitiveFilter<ReviewQueueItem['entity_creator_id']>;
37903819
} & {
37913820
reviewed?: boolean;
37923821
} & {
@@ -3840,6 +3869,7 @@ export type ReviewQueueFilters = QueryFilters<
38403869
} & {
38413870
recommended_action?: RequireOnlyOne<{
38423871
$eq?: string;
3872+
$in?: string[];
38433873
}>;
38443874
} & {
38453875
flagged_user_id?: RequireOnlyOne<{
@@ -3852,6 +3882,7 @@ export type ReviewQueueFilters = QueryFilters<
38523882
} & {
38533883
label?: RequireOnlyOne<{
38543884
$eq?: string;
3885+
$in?: string[];
38553886
}>;
38563887
} & {
38573888
reporter_type?: RequireOnlyOne<{
@@ -3866,6 +3897,24 @@ export type ReviewQueueFilters = QueryFilters<
38663897
date_range?: RequireOnlyOne<{
38673898
$eq?: string; // Format: "date1_date2"
38683899
}>;
3900+
} & {
3901+
latest_moderator_action?:
3902+
| RequireOnlyOne<
3903+
Pick<QueryFilter<ReviewQueueItem['latest_moderator_action']>, '$eq' | '$in'>
3904+
>
3905+
| PrimitiveFilter<ReviewQueueItem['latest_moderator_action']>;
3906+
} & {
3907+
flags_count?: RequireOnlyOne<{
3908+
$eq?: number;
3909+
}>;
3910+
} & {
3911+
ai_text_severity?: RequireOnlyOne<{
3912+
$eq?: string;
3913+
}>;
3914+
} & {
3915+
channel_cid?: RequireOnlyOne<{
3916+
$eq?: string;
3917+
}>;
38693918
}
38703919
>;
38713920

@@ -3877,8 +3926,25 @@ export type QueryModerationConfigsSort = Array<Sort<'key' | 'created_at' | 'upda
38773926

38783927
export type ReviewQueuePaginationOptions = Pager;
38793928

3929+
export type FilterConfigResponse = {
3930+
llm_labels: string[];
3931+
ai_text_labels?: string[];
3932+
};
3933+
3934+
export type ModerationActionConfig = {
3935+
entity_type: string;
3936+
order: number;
3937+
action: string;
3938+
icon: string;
3939+
description: string;
3940+
custom?: Record<string, unknown>;
3941+
};
3942+
38803943
export type ReviewQueueResponse = {
38813944
items: ReviewQueueItem[];
3945+
action_config?: Record<string, ModerationActionConfig[]>;
3946+
filter_config?: FilterConfigResponse;
3947+
stats?: Record<string, unknown>;
38823948
next?: string;
38833949
prev?: string;
38843950
};

0 commit comments

Comments
 (0)