UNPKG

@atproto/api

Version:

Client library for atproto and Bluesky

352 lines 14.2 kB
import { AppBskyEmbedExternal, AppBskyEmbedGallery, AppBskyEmbedImages, AppBskyEmbedRecord, AppBskyEmbedRecordWithMedia, AppBskyFeedPost, } from '../../client/index.js'; import { ModerationDecision } from '../decision.js'; import { matchMuteWords } from '../mutewords.js'; import { decideAccount } from './account.js'; import { decideProfile } from './profile.js'; export function decidePost(subject, opts) { return ModerationDecision.merge(decideSubject(subject, opts), decideEmbed(subject.embed, opts)?.downgrade(), decideAccount(subject.author, opts), decideProfile(subject.author, opts)); } function decideSubject(subject, opts) { const acc = new ModerationDecision(); acc.setDid(subject.author.did); acc.setIsMe(subject.author.did === opts.userDid); if (subject.labels?.length) { for (const label of subject.labels) { acc.addLabel('content', label, opts); } } acc.addHidden(checkHiddenPost(subject, opts.prefs.hiddenPosts)); if (!acc.isMe) { acc.addMutedWord(matchAllMuteWords(subject, opts.prefs.mutedWords)); } return acc; } function decideEmbed(embed, opts) { if (embed) { if ((AppBskyEmbedRecord.isView(embed) || AppBskyEmbedRecordWithMedia.isView(embed)) && AppBskyEmbedRecord.isViewRecord(embed.record)) { // quote post return decideQuotedPost(embed.record, opts); } else if (AppBskyEmbedRecordWithMedia.isView(embed) && AppBskyEmbedRecord.isViewRecord(embed.record.record)) { // quoted post with media return decideQuotedPost(embed.record.record, opts); } else if ((AppBskyEmbedRecord.isView(embed) || AppBskyEmbedRecordWithMedia.isView(embed)) && AppBskyEmbedRecord.isViewBlocked(embed.record)) { // blocked quote post return decideBlockedQuotedPost(embed.record, opts); } else if (AppBskyEmbedRecordWithMedia.isView(embed) && AppBskyEmbedRecord.isViewBlocked(embed.record.record)) { // blocked quoted post with media return decideBlockedQuotedPost(embed.record.record, opts); } } return undefined; } function decideQuotedPost(subject, opts) { const acc = new ModerationDecision(); acc.setDid(subject.author.did); acc.setIsMe(subject.author.did === opts.userDid); if (subject.labels?.length) { for (const label of subject.labels) { acc.addLabel('content', label, opts); } } return ModerationDecision.merge(acc, decideAccount(subject.author, opts), decideProfile(subject.author, opts)); } function decideBlockedQuotedPost(subject, opts) { const acc = new ModerationDecision(); acc.setDid(subject.author.did); acc.setIsMe(subject.author.did === opts.userDid); if (subject.author.viewer?.muted) { if (subject.author.viewer?.mutedByList) { acc.addMutedByList(subject.author.viewer?.mutedByList); } else { acc.addMuted(subject.author.viewer?.muted); } } if (subject.author.viewer?.blocking) { if (subject.author.viewer?.blockingByList) { acc.addBlockingByList(subject.author.viewer?.blockingByList); } else { acc.addBlocking(subject.author.viewer?.blocking); } } acc.addBlockedBy(subject.author.viewer?.blockedBy); return acc; } function checkHiddenPost(subject, hiddenPosts) { if (!hiddenPosts?.length) { return false; } if (hiddenPosts.includes(subject.uri)) { return true; } if (subject.embed) { if (AppBskyEmbedRecord.isView(subject.embed) && AppBskyEmbedRecord.isViewRecord(subject.embed.record) && hiddenPosts.includes(subject.embed.record.uri)) { return true; } if (AppBskyEmbedRecordWithMedia.isView(subject.embed) && AppBskyEmbedRecord.isViewRecord(subject.embed.record.record) && hiddenPosts.includes(subject.embed.record.record.uri)) { return true; } } return false; } function matchAllMuteWords(subject, mutedWords) { if (!mutedWords?.length) { return; } const postAuthor = subject.author; if (AppBskyFeedPost.isRecord(subject.record)) { const post = subject.record; const matches = matchMuteWords({ mutedWords, text: post.text, facets: post.facets, outlineTags: post.tags, languages: post.langs, actor: postAuthor, }); // post text if (matches) { return matches; } if (post.embed && AppBskyEmbedImages.isMain(post.embed)) { // post images for (const image of post.embed.images) { const matches = matchMuteWords({ mutedWords, text: image.alt, languages: post.langs, actor: postAuthor, }); if (matches) { return matches; } } } if (post.embed && AppBskyEmbedGallery.isMain(post.embed)) { // post gallery items for (const item of post.embed.items) { if (AppBskyEmbedGallery.isImage(item)) { const matches = matchMuteWords({ mutedWords, text: item.alt, languages: post.langs, actor: postAuthor, }); if (matches) { return matches; } } } } } const { embed } = subject; if (embed) { // quote post if ((AppBskyEmbedRecord.isView(embed) || AppBskyEmbedRecordWithMedia.isView(embed)) && AppBskyEmbedRecord.isViewRecord(embed.record)) { if (AppBskyFeedPost.isRecord(embed.record.value)) { const embeddedPost = embed.record.value; const embedAuthor = embed.record.author; const matches = matchMuteWords({ mutedWords, text: embeddedPost.text, facets: embeddedPost.facets, outlineTags: embeddedPost.tags, languages: embeddedPost.langs, actor: embedAuthor, }); // quoted post text if (matches) { return matches; } // quoted post's images if (AppBskyEmbedImages.isMain(embeddedPost.embed)) { for (const image of embeddedPost.embed.images) { const matches = matchMuteWords({ mutedWords, text: image.alt, languages: embeddedPost.langs, actor: embedAuthor, }); if (matches) { return matches; } } } // quoted post's gallery if (AppBskyEmbedGallery.isMain(embeddedPost.embed)) { for (const item of embeddedPost.embed.items) { if (AppBskyEmbedGallery.isImage(item)) { const matches = matchMuteWords({ mutedWords, text: item.alt, languages: embeddedPost.langs, actor: embedAuthor, }); if (matches) { return matches; } } } } // quoted post's link card if (AppBskyEmbedExternal.isMain(embeddedPost.embed)) { const { external } = embeddedPost.embed; const matches = matchMuteWords({ mutedWords, text: external.title + ' ' + external.description, languages: [], actor: embedAuthor, }); if (matches) { return matches; } } if (AppBskyEmbedRecordWithMedia.isMain(embeddedPost.embed)) { // quoted post's link card when it did a quote + media if (AppBskyEmbedExternal.isMain(embeddedPost.embed.media)) { const { external } = embeddedPost.embed.media; const matches = matchMuteWords({ mutedWords, text: external.title + ' ' + external.description, languages: [], actor: embedAuthor, }); if (matches) { return matches; } } // quoted post's images when it did a quote + media if (AppBskyEmbedImages.isMain(embeddedPost.embed.media)) { for (const image of embeddedPost.embed.media.images) { const matches = matchMuteWords({ mutedWords, text: image.alt, languages: AppBskyFeedPost.isRecord(embeddedPost.record) ? embeddedPost.langs : [], actor: embedAuthor, }); if (matches) { return matches; } } } // quoted post's gallery when it did a quote + media if (AppBskyEmbedGallery.isMain(embeddedPost.embed.media)) { for (const item of embeddedPost.embed.media.items) { if (AppBskyEmbedGallery.isImage(item)) { const matches = matchMuteWords({ mutedWords, text: item.alt, languages: AppBskyFeedPost.isRecord(embeddedPost.record) ? embeddedPost.langs : [], actor: embedAuthor, }); if (matches) { return matches; } } } } } } } // link card else if (AppBskyEmbedExternal.isView(embed)) { const { external } = embed; const matches = matchMuteWords({ mutedWords, text: external.title + ' ' + external.description, languages: [], actor: postAuthor, }); if (matches) { return matches; } } // quote post with media else if (AppBskyEmbedRecordWithMedia.isView(embed) && AppBskyEmbedRecord.isViewRecord(embed.record.record)) { const embedAuthor = embed.record.record.author; // quoted post text if (AppBskyFeedPost.isRecord(embed.record.record.value)) { const post = embed.record.record.value; const matches = matchMuteWords({ mutedWords, text: post.text, facets: post.facets, outlineTags: post.tags, languages: post.langs, actor: embedAuthor, }); if (matches) { return matches; } } // quoted post images if (AppBskyEmbedImages.isView(embed.media)) { for (const image of embed.media.images) { const matches = matchMuteWords({ mutedWords, text: image.alt, languages: AppBskyFeedPost.isRecord(subject.record) ? subject.record.langs : [], actor: embedAuthor, }); if (matches) { return matches; } } } // quoted post gallery if (AppBskyEmbedGallery.isView(embed.media)) { for (const item of embed.media.items) { if (AppBskyEmbedGallery.isViewImage(item)) { const matches = matchMuteWords({ mutedWords, text: item.alt, languages: AppBskyFeedPost.isRecord(subject.record) ? subject.record.langs : [], actor: embedAuthor, }); if (matches) { return matches; } } } } if (AppBskyEmbedExternal.isView(embed.media)) { const { external } = embed.media; const matches = matchMuteWords({ mutedWords, text: external.title + ' ' + external.description, languages: [], actor: embedAuthor, }); if (matches) { return matches; } } } } } //# sourceMappingURL=post.js.map