UNPKG

@atproto/ozone

Version:

Backend service for moderating the Bluesky network.

71 lines (64 loc) 2.17 kB
import { langLogger as log } from '../logger' import { ModerationService } from '../mod-service' import { ModSubject } from '../mod-service/subject' import { ModerationSubjectStatusRow } from '../mod-service/types' import { ContentTagger } from './content-tagger' import { EmbedTagger } from './embed-tagger' import { LanguageTagger } from './language-tagger' export class TagService { private taggers: ContentTagger[] constructor( private subject: ModSubject, protected subjectStatus: ModerationSubjectStatusRow | null, private taggerDid: string, private moderationService: ModerationService, ) { this.taggers = [ new LanguageTagger(subject, subjectStatus, moderationService), new EmbedTagger(subject, subjectStatus, moderationService), // Add more taggers as needed ] } // Allow the caller to seed the initial tags async evaluateForSubject(initialTags?: Iterable<string>) { try { const tags = new Set(initialTags) await Promise.all( this.taggers.map(async (tagger) => { try { const newTags = await tagger.getTags() for (const newTag of newTags) { tags.add(newTag) } } catch (e) { // Don't let one tagger error stop the rest from running log.error( { subject: this.subject, err: e }, 'Error applying tagger', ) } }), ) // Ensure that before inserting new tags, we discard any tag that may // have been evaluated to be added but is already present in the subject if (this.subjectStatus?.tags?.length) { for (const tag of this.subjectStatus.tags) { tags.delete(tag) } } if (tags.size) { await this.moderationService.logEvent({ event: { $type: 'tools.ozone.moderation.defs#modEventTag', add: [...tags], remove: [], }, subject: this.subject, createdBy: this.taggerDid, }) } } catch (err) { log.error({ subject: this.subject, err }, 'Error tagging subject') } } }