A tool for parsing traffic on the jetstream and applying a moderation workstream based on regexp based rules
1import type * as AppBskyRichtextFacet from "@atproto/ozone/dist/lexicon/types/app/bsky/richtext/facet.js";
2
3export interface Checks {
4 language?: string[];
5 label: string;
6 unlabel?: boolean;
7 comment: string;
8 description?: boolean;
9 displayName?: boolean;
10 reportAcct: boolean;
11 commentAcct: boolean;
12 reportPost?: boolean;
13 toLabel: boolean;
14 trackOnly?: boolean;
15 duration?: number;
16 check: RegExp;
17 whitelist?: RegExp;
18 ignoredDIDs?: string[];
19 starterPacks?: string[];
20 knownVectors?: string[];
21}
22
23export interface Post {
24 did: string;
25 time: number;
26 rkey: string;
27 atURI: string;
28 text: string;
29 cid: string;
30}
31
32export interface Handle {
33 did: string;
34 time: number;
35 handle: string;
36}
37
38export interface Profile {
39 did: string;
40 time: number;
41 displayName?: string;
42 description?: string;
43}
44
45export interface List {
46 label: string;
47 rkey: string;
48}
49
50// Re-export facet types from @atproto/ozone for convenience
51export type Facet = AppBskyRichtextFacet.Main;
52export type FacetIndex = AppBskyRichtextFacet.ByteSlice;
53export type FacetMention = AppBskyRichtextFacet.Mention;
54export type LinkFeature = AppBskyRichtextFacet.Link;
55export type FacetTag = AppBskyRichtextFacet.Tag;
56
57export interface AccountAgeCheck {
58 monitoredDIDs?: string[]; // DIDs to monitor for replies (optional if monitoredPostURIs is provided)
59 monitoredPostURIs?: string[]; // Specific post URIs to monitor for replies (optional if monitoredDIDs is provided)
60 anchorDate: string; // ISO 8601 date string (e.g., "2025-01-15")
61 maxAgeDays: number; // Maximum account age in days
62 label: string; // Label to apply if account is too new
63 comment: string; // Comment for the label
64 expires?: string; // Optional expiration date (ISO 8601) - check will be skipped after this date
65}
66
67export type WindowUnit = "minutes" | "hours" | "days";
68
69export interface AccountThresholdConfig {
70 labels: string | string[]; // Single label or array for OR matching
71 threshold: number; // Number of labeled posts required to trigger account action
72 accountLabel: string; // Label to apply to the account
73 accountComment: string; // Comment for the account action
74 window: number; // Rolling window duration
75 windowUnit: WindowUnit; // Unit for the rolling window
76 reportAcct: boolean; // Whether to report the account
77 commentAcct: boolean; // Whether to comment on the account
78 toLabel?: boolean; // Whether to apply label (defaults to true)
79}
80
81export interface StarterPackThresholdConfig {
82 threshold: number;
83 window: number;
84 windowUnit: WindowUnit;
85 accountLabel: string;
86 accountComment: string;
87 toLabel?: boolean;
88 reportAcct?: boolean;
89 commentAcct?: boolean;
90 allowlist?: string[];
91}
92
93export interface ModerationError {
94 action: "label" | "report" | "comment" | "unlabel";
95 error: unknown;
96}
97
98export interface ModerationResult {
99 success: boolean;
100 errors: ModerationError[];
101}