Add setPostInteractionSettings and related prefs ()

* Add setPostInteractionSettings and related prefs

* Fix test

* Align types and implementation

* Tighten up, clarifying descriptions

* Fix test

* Format
This commit is contained in:
Eric Bailey 2025-02-05 17:43:27 -06:00 committed by GitHub
parent 61dc0d60e1
commit 87ed907a6b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 588 additions and 1 deletions
.changeset
lexicons/app/bsky
packages
api
bsky/src/lexicon
ozone/src/lexicon
pds/src/lexicon

@ -0,0 +1,5 @@
---
"@atproto/api": patch
---
Add `setPostInteractionSettings` for configuring default interaction settings for creation of posts

@ -174,7 +174,8 @@
"#mutedWordsPref",
"#hiddenPostsPref",
"#bskyAppStatePref",
"#labelersPref"
"#labelersPref",
"#postInteractionSettingsPref"
]
}
},
@ -468,6 +469,35 @@
"description": "The date and time at which the NUX will expire and should be considered completed."
}
}
},
"postInteractionSettingsPref": {
"type": "object",
"description": "Default post interaction settings for the account. These values should be applied as default values when creating new posts. These refs should mirror the threadgate and postgate records exactly.",
"required": [],
"properties": {
"threadgateAllowRules": {
"description": "Matches threadgate record. List of rules defining who can reply to this users posts. If value is an empty array, no one can reply. If value is undefined, anyone can reply.",
"type": "array",
"maxLength": 5,
"items": {
"type": "union",
"refs": [
"app.bsky.feed.threadgate#mentionRule",
"app.bsky.feed.threadgate#followingRule",
"app.bsky.feed.threadgate#listRule"
]
}
},
"postgateEmbeddingRules": {
"description": "Matches postgate record. List of rules defining who can embed this users posts. If value is an empty array or is undefined, no particular rules apply and anyone can embed.",
"type": "array",
"maxLength": 5,
"items": {
"type": "union",
"refs": ["app.bsky.feed.postgate#disableRule"]
}
}
}
}
}
}

@ -26,6 +26,7 @@
"description": "List of AT-URIs embedding this post that the author has detached from."
},
"embeddingRules": {
"description": "List of rules defining who can embed this post. If value is an empty array or is undefined, no particular rules apply and anyone can embed.",
"type": "array",
"maxLength": 5,
"items": {

@ -16,6 +16,7 @@
"description": "Reference (AT-URI) to the post record."
},
"allow": {
"description": "List of rules defining who can reply to this post. If value is an empty array, no one can reply. If value is undefined, anyone can reply.",
"type": "array",
"maxLength": 5,
"items": {

@ -583,6 +583,10 @@ export class Agent extends XrpcClient {
activeProgressGuide: undefined,
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
}
const res = await this.app.bsky.actor.getPreferences({})
const labelPrefs: AppBskyActorDefs.ContentLabelPref[] = []
@ -687,6 +691,14 @@ export class Agent extends XrpcClient {
prefs.bskyAppState.queuedNudges = v.queuedNudges || []
prefs.bskyAppState.activeProgressGuide = v.activeProgressGuide
prefs.bskyAppState.nuxs = v.nuxs || []
} else if (
AppBskyActorDefs.isPostInteractionSettingsPref(pref) &&
AppBskyActorDefs.validatePostInteractionSettingsPref(pref).success
) {
prefs.postInteractionSettings.threadgateAllowRules =
pref.threadgateAllowRules
prefs.postInteractionSettings.postgateEmbeddingRules =
pref.postgateEmbeddingRules
}
}
@ -1463,6 +1475,49 @@ export class Agent extends XrpcClient {
})
}
async setPostInteractionSettings(
settings: AppBskyActorDefs.PostInteractionSettingsPref,
) {
if (
!AppBskyActorDefs.validatePostInteractionSettingsPref(settings).success
) {
throw new Error('Invalid post interaction settings')
}
await this.updatePreferences((prefs: AppBskyActorDefs.Preferences) => {
let prev = prefs.findLast(
(pref) =>
AppBskyActorDefs.isPostInteractionSettingsPref(pref) &&
AppBskyActorDefs.validatePostInteractionSettingsPref(pref).success,
) as AppBskyActorDefs.PostInteractionSettingsPref
if (!prev) {
prev = {
/**
* Matches handling of `threadgate.allow` where `undefined` means "everyone"
*/
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
}
}
/**
* Matches handling of `threadgate.allow` where `undefined` means "everyone"
*/
prev.threadgateAllowRules = settings.threadgateAllowRules
prev.postgateEmbeddingRules = settings.postgateEmbeddingRules
return prefs
.filter((p) => !AppBskyActorDefs.isPostInteractionSettingsPref(p))
.concat([
{
...prev,
$type: 'app.bsky.actor.defs#postInteractionSettingsPref',
},
])
})
}
//- Private methods
#prefsLock = new AwaitLock()

@ -4381,6 +4381,7 @@ export const schemaDict = {
'lex:app.bsky.actor.defs#hiddenPostsPref',
'lex:app.bsky.actor.defs#bskyAppStatePref',
'lex:app.bsky.actor.defs#labelersPref',
'lex:app.bsky.actor.defs#postInteractionSettingsPref',
],
},
},
@ -4714,6 +4715,38 @@ export const schemaDict = {
},
},
},
postInteractionSettingsPref: {
type: 'object',
description:
'Default post interaction settings for the account. These values should be applied as default values when creating new posts. These refs should mirror the threadgate and postgate records exactly.',
required: [],
properties: {
threadgateAllowRules: {
description:
'Matches threadgate record. List of rules defining who can reply to this users posts. If value is an empty array, no one can reply. If value is undefined, anyone can reply.',
type: 'array',
maxLength: 5,
items: {
type: 'union',
refs: [
'lex:app.bsky.feed.threadgate#mentionRule',
'lex:app.bsky.feed.threadgate#followingRule',
'lex:app.bsky.feed.threadgate#listRule',
],
},
},
postgateEmbeddingRules: {
description:
'Matches postgate record. List of rules defining who can embed this users posts. If value is an empty array or is undefined, no particular rules apply and anyone can embed.',
type: 'array',
maxLength: 5,
items: {
type: 'union',
refs: ['lex:app.bsky.feed.postgate#disableRule'],
},
},
},
},
},
},
AppBskyActorGetPreferences: {
@ -7120,6 +7153,8 @@ export const schemaDict = {
'List of AT-URIs embedding this post that the author has detached from.',
},
embeddingRules: {
description:
'List of rules defining who can embed this post. If value is an empty array or is undefined, no particular rules apply and anyone can embed.',
type: 'array',
maxLength: 5,
items: {
@ -7333,6 +7368,8 @@ export const schemaDict = {
description: 'Reference (AT-URI) to the post record.',
},
allow: {
description:
'List of rules defining who can reply to this post. If value is an empty array, no one can reply. If value is undefined, anyone can reply.',
type: 'array',
maxLength: 5,
items: {

@ -8,6 +8,8 @@ import { CID } from 'multiformats/cid'
import * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs'
import * as AppBskyGraphDefs from '../graph/defs'
import * as ComAtprotoRepoStrongRef from '../../../com/atproto/repo/strongRef'
import * as AppBskyFeedThreadgate from '../feed/threadgate'
import * as AppBskyFeedPostgate from '../feed/postgate'
export interface ProfileViewBasic {
did: string
@ -188,6 +190,7 @@ export type Preferences = (
| HiddenPostsPref
| BskyAppStatePref
| LabelersPref
| PostInteractionSettingsPref
| { $type: string; [k: string]: unknown }
)[]
@ -532,3 +535,36 @@ export function isNux(v: unknown): v is Nux {
export function validateNux(v: unknown): ValidationResult {
return lexicons.validate('app.bsky.actor.defs#nux', v)
}
/** Default post interaction settings for the account. These values should be applied as default values when creating new posts. These refs should mirror the threadgate and postgate records exactly. */
export interface PostInteractionSettingsPref {
/** Matches threadgate record. List of rules defining who can reply to this users posts. If value is an empty array, no one can reply. If value is undefined, anyone can reply. */
threadgateAllowRules?: (
| AppBskyFeedThreadgate.MentionRule
| AppBskyFeedThreadgate.FollowingRule
| AppBskyFeedThreadgate.ListRule
| { $type: string; [k: string]: unknown }
)[]
/** Matches postgate record. List of rules defining who can embed this users posts. If value is an empty array or is undefined, no particular rules apply and anyone can embed. */
postgateEmbeddingRules?: (
| AppBskyFeedPostgate.DisableRule
| { $type: string; [k: string]: unknown }
)[]
[k: string]: unknown
}
export function isPostInteractionSettingsPref(
v: unknown,
): v is PostInteractionSettingsPref {
return (
isObj(v) &&
hasProp(v, '$type') &&
v.$type === 'app.bsky.actor.defs#postInteractionSettingsPref'
)
}
export function validatePostInteractionSettingsPref(
v: unknown,
): ValidationResult {
return lexicons.validate('app.bsky.actor.defs#postInteractionSettingsPref', v)
}

@ -12,6 +12,7 @@ export interface Record {
post: string
/** List of AT-URIs embedding this post that the author has detached from. */
detachedEmbeddingUris?: string[]
/** List of rules defining who can embed this post. If value is an empty array or is undefined, no particular rules apply and anyone can embed. */
embeddingRules?: (DisableRule | { $type: string; [k: string]: unknown })[]
[k: string]: unknown
}

@ -9,6 +9,7 @@ import { CID } from 'multiformats/cid'
export interface Record {
/** Reference (AT-URI) to the post record. */
post: string
/** List of rules defining who can reply to this post. If value is an empty array, no one can reply. If value is undefined, anyone can reply. */
allow?: (
| MentionRule
| FollowingRule

@ -109,4 +109,5 @@ export interface BskyPreferences {
activeProgressGuide: AppBskyActorDefs.BskyAppProgressGuide | undefined
nuxs: AppBskyActorDefs.Nux[]
}
postInteractionSettings: AppBskyActorDefs.PostInteractionSettingsPref
}

@ -278,6 +278,10 @@ describe('agent', () => {
queuedNudges: [],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
await agent.setAdultContentEnabled(true)
@ -320,6 +324,10 @@ describe('agent', () => {
queuedNudges: [],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
await agent.setAdultContentEnabled(false)
@ -362,6 +370,10 @@ describe('agent', () => {
queuedNudges: [],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
await agent.setContentLabelPref('misinfo', 'hide')
@ -404,6 +416,10 @@ describe('agent', () => {
queuedNudges: [],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
await agent.setContentLabelPref('spam', 'ignore')
@ -450,6 +466,10 @@ describe('agent', () => {
queuedNudges: [],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
await agent.addSavedFeed('at://bob.com/app.bsky.feed.generator/fake')
@ -499,6 +519,10 @@ describe('agent', () => {
queuedNudges: [],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
await agent.addPinnedFeed('at://bob.com/app.bsky.feed.generator/fake')
@ -548,6 +572,10 @@ describe('agent', () => {
queuedNudges: [],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
await agent.removePinnedFeed('at://bob.com/app.bsky.feed.generator/fake')
@ -597,6 +625,10 @@ describe('agent', () => {
queuedNudges: [],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
await agent.removeSavedFeed('at://bob.com/app.bsky.feed.generator/fake')
@ -646,6 +678,10 @@ describe('agent', () => {
queuedNudges: [],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
await agent.addPinnedFeed('at://bob.com/app.bsky.feed.generator/fake')
@ -695,6 +731,10 @@ describe('agent', () => {
queuedNudges: [],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
await agent.addPinnedFeed('at://bob.com/app.bsky.feed.generator/fake2')
@ -750,6 +790,10 @@ describe('agent', () => {
queuedNudges: [],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
await agent.removeSavedFeed('at://bob.com/app.bsky.feed.generator/fake')
@ -799,6 +843,10 @@ describe('agent', () => {
queuedNudges: [],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
await agent.setPersonalDetails({ birthDate: '2023-09-11T18:05:42.556Z' })
@ -848,6 +896,10 @@ describe('agent', () => {
queuedNudges: [],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
await agent.setFeedViewPrefs('home', { hideReplies: true })
@ -897,6 +949,10 @@ describe('agent', () => {
queuedNudges: [],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
await agent.setFeedViewPrefs('home', { hideReplies: false })
@ -946,6 +1002,10 @@ describe('agent', () => {
queuedNudges: [],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
await agent.setFeedViewPrefs('other', { hideReplies: true })
@ -1002,6 +1062,10 @@ describe('agent', () => {
queuedNudges: [],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
await agent.setThreadViewPrefs({ sort: 'random' })
@ -1058,6 +1122,10 @@ describe('agent', () => {
queuedNudges: [],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
await agent.setThreadViewPrefs({ sort: 'oldest' })
@ -1114,6 +1182,10 @@ describe('agent', () => {
queuedNudges: [],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
await agent.setInterestsPref({ tags: ['foo', 'bar'] })
@ -1170,6 +1242,10 @@ describe('agent', () => {
queuedNudges: [],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
})
@ -1353,6 +1429,10 @@ describe('agent', () => {
queuedNudges: ['two'],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
await agent.setAdultContentEnabled(false)
@ -1411,6 +1491,10 @@ describe('agent', () => {
queuedNudges: ['two'],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
await agent.setContentLabelPref('porn', 'ignore')
@ -1470,6 +1554,10 @@ describe('agent', () => {
queuedNudges: ['two'],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
await agent.removeLabeler('did:plc:other')
@ -1525,6 +1613,10 @@ describe('agent', () => {
queuedNudges: ['two'],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
await agent.addPinnedFeed('at://bob.com/app.bsky.feed.generator/fake')
@ -1580,6 +1672,10 @@ describe('agent', () => {
queuedNudges: ['two'],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
await agent.setPersonalDetails({ birthDate: '2023-09-11T18:05:42.556Z' })
@ -1635,6 +1731,10 @@ describe('agent', () => {
queuedNudges: ['two'],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
await agent.setFeedViewPrefs('home', {
@ -1702,6 +1802,10 @@ describe('agent', () => {
queuedNudges: ['two', 'three'],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
const res = await agent.app.bsky.actor.getPreferences()
@ -3337,6 +3441,80 @@ describe('agent', () => {
})
})
describe('setPostInteractionSettings', () => {
let agent: AtpAgent
beforeAll(async () => {
agent = new AtpAgent({ service: network.pds.url })
await agent.createAccount({
handle: 'pints.test',
email: 'pints@test.com',
password: 'password',
})
})
it('works', async () => {
const next: AppBskyActorDefs.PostInteractionSettingsPref = {
threadgateAllowRules: [
{ $type: 'app.bsky.feed.threadgate#mentionRule' },
],
postgateEmbeddingRules: [],
}
await agent.setPostInteractionSettings(next)
const prefs = await agent.getPreferences()
expect(prefs.postInteractionSettings).toEqual(next)
})
it('clears', async () => {
const next: AppBskyActorDefs.PostInteractionSettingsPref = {
threadgateAllowRules: [],
postgateEmbeddingRules: [],
}
await agent.setPostInteractionSettings(next)
const prefs = await agent.getPreferences()
expect(prefs.postInteractionSettings).toEqual(next)
})
/**
* Logic matches threadgate `allow` logic, where `undefined` means "anyone
* can reply" and an empty array means "no one can reply".
*
* Postgate `embeddingRules` behaves differently, where `undefined` and
* an empty array both mean "no particular rules applied".
*
* Both props are optional though, so for easier sharing of types, we
* allow `undefined`.
*/
it('clears using undefined', async () => {
const next: AppBskyActorDefs.PostInteractionSettingsPref = {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
}
await agent.setPostInteractionSettings(next)
const prefs = await agent.getPreferences()
expect(prefs.postInteractionSettings).toEqual(next)
})
it('validates inputs', async () => {
expect(() =>
agent.setPostInteractionSettings({
threadgateAllowRules: [{ key: 'string' }],
postgateEmbeddingRules: [],
}),
).rejects.toThrow()
})
})
// end
})
})

@ -86,6 +86,10 @@ describe('agent', () => {
queuedNudges: [],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
})
@ -136,6 +140,10 @@ describe('agent', () => {
queuedNudges: [],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
expect(agent.labelers).toStrictEqual(['did:plc:other'])
@ -171,6 +179,10 @@ describe('agent', () => {
queuedNudges: [],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
expect(agent.labelers).toStrictEqual([])
})
@ -228,6 +240,10 @@ describe('agent', () => {
queuedNudges: [],
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: undefined,
},
})
})

@ -4381,6 +4381,7 @@ export const schemaDict = {
'lex:app.bsky.actor.defs#hiddenPostsPref',
'lex:app.bsky.actor.defs#bskyAppStatePref',
'lex:app.bsky.actor.defs#labelersPref',
'lex:app.bsky.actor.defs#postInteractionSettingsPref',
],
},
},
@ -4714,6 +4715,38 @@ export const schemaDict = {
},
},
},
postInteractionSettingsPref: {
type: 'object',
description:
'Default post interaction settings for the account. These values should be applied as default values when creating new posts. These refs should mirror the threadgate and postgate records exactly.',
required: [],
properties: {
threadgateAllowRules: {
description:
'Matches threadgate record. List of rules defining who can reply to this users posts. If value is an empty array, no one can reply. If value is undefined, anyone can reply.',
type: 'array',
maxLength: 5,
items: {
type: 'union',
refs: [
'lex:app.bsky.feed.threadgate#mentionRule',
'lex:app.bsky.feed.threadgate#followingRule',
'lex:app.bsky.feed.threadgate#listRule',
],
},
},
postgateEmbeddingRules: {
description:
'Matches postgate record. List of rules defining who can embed this users posts. If value is an empty array or is undefined, no particular rules apply and anyone can embed.',
type: 'array',
maxLength: 5,
items: {
type: 'union',
refs: ['lex:app.bsky.feed.postgate#disableRule'],
},
},
},
},
},
},
AppBskyActorGetPreferences: {
@ -7120,6 +7153,8 @@ export const schemaDict = {
'List of AT-URIs embedding this post that the author has detached from.',
},
embeddingRules: {
description:
'List of rules defining who can embed this post. If value is an empty array or is undefined, no particular rules apply and anyone can embed.',
type: 'array',
maxLength: 5,
items: {
@ -7333,6 +7368,8 @@ export const schemaDict = {
description: 'Reference (AT-URI) to the post record.',
},
allow: {
description:
'List of rules defining who can reply to this post. If value is an empty array, no one can reply. If value is undefined, anyone can reply.',
type: 'array',
maxLength: 5,
items: {

@ -8,6 +8,8 @@ import { CID } from 'multiformats/cid'
import * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs'
import * as AppBskyGraphDefs from '../graph/defs'
import * as ComAtprotoRepoStrongRef from '../../../com/atproto/repo/strongRef'
import * as AppBskyFeedThreadgate from '../feed/threadgate'
import * as AppBskyFeedPostgate from '../feed/postgate'
export interface ProfileViewBasic {
did: string
@ -188,6 +190,7 @@ export type Preferences = (
| HiddenPostsPref
| BskyAppStatePref
| LabelersPref
| PostInteractionSettingsPref
| { $type: string; [k: string]: unknown }
)[]
@ -532,3 +535,36 @@ export function isNux(v: unknown): v is Nux {
export function validateNux(v: unknown): ValidationResult {
return lexicons.validate('app.bsky.actor.defs#nux', v)
}
/** Default post interaction settings for the account. These values should be applied as default values when creating new posts. These refs should mirror the threadgate and postgate records exactly. */
export interface PostInteractionSettingsPref {
/** Matches threadgate record. List of rules defining who can reply to this users posts. If value is an empty array, no one can reply. If value is undefined, anyone can reply. */
threadgateAllowRules?: (
| AppBskyFeedThreadgate.MentionRule
| AppBskyFeedThreadgate.FollowingRule
| AppBskyFeedThreadgate.ListRule
| { $type: string; [k: string]: unknown }
)[]
/** Matches postgate record. List of rules defining who can embed this users posts. If value is an empty array or is undefined, no particular rules apply and anyone can embed. */
postgateEmbeddingRules?: (
| AppBskyFeedPostgate.DisableRule
| { $type: string; [k: string]: unknown }
)[]
[k: string]: unknown
}
export function isPostInteractionSettingsPref(
v: unknown,
): v is PostInteractionSettingsPref {
return (
isObj(v) &&
hasProp(v, '$type') &&
v.$type === 'app.bsky.actor.defs#postInteractionSettingsPref'
)
}
export function validatePostInteractionSettingsPref(
v: unknown,
): ValidationResult {
return lexicons.validate('app.bsky.actor.defs#postInteractionSettingsPref', v)
}

@ -12,6 +12,7 @@ export interface Record {
post: string
/** List of AT-URIs embedding this post that the author has detached from. */
detachedEmbeddingUris?: string[]
/** List of rules defining who can embed this post. If value is an empty array or is undefined, no particular rules apply and anyone can embed. */
embeddingRules?: (DisableRule | { $type: string; [k: string]: unknown })[]
[k: string]: unknown
}

@ -9,6 +9,7 @@ import { CID } from 'multiformats/cid'
export interface Record {
/** Reference (AT-URI) to the post record. */
post: string
/** List of rules defining who can reply to this post. If value is an empty array, no one can reply. If value is undefined, anyone can reply. */
allow?: (
| MentionRule
| FollowingRule

@ -4381,6 +4381,7 @@ export const schemaDict = {
'lex:app.bsky.actor.defs#hiddenPostsPref',
'lex:app.bsky.actor.defs#bskyAppStatePref',
'lex:app.bsky.actor.defs#labelersPref',
'lex:app.bsky.actor.defs#postInteractionSettingsPref',
],
},
},
@ -4714,6 +4715,38 @@ export const schemaDict = {
},
},
},
postInteractionSettingsPref: {
type: 'object',
description:
'Default post interaction settings for the account. These values should be applied as default values when creating new posts. These refs should mirror the threadgate and postgate records exactly.',
required: [],
properties: {
threadgateAllowRules: {
description:
'Matches threadgate record. List of rules defining who can reply to this users posts. If value is an empty array, no one can reply. If value is undefined, anyone can reply.',
type: 'array',
maxLength: 5,
items: {
type: 'union',
refs: [
'lex:app.bsky.feed.threadgate#mentionRule',
'lex:app.bsky.feed.threadgate#followingRule',
'lex:app.bsky.feed.threadgate#listRule',
],
},
},
postgateEmbeddingRules: {
description:
'Matches postgate record. List of rules defining who can embed this users posts. If value is an empty array or is undefined, no particular rules apply and anyone can embed.',
type: 'array',
maxLength: 5,
items: {
type: 'union',
refs: ['lex:app.bsky.feed.postgate#disableRule'],
},
},
},
},
},
},
AppBskyActorGetPreferences: {
@ -7120,6 +7153,8 @@ export const schemaDict = {
'List of AT-URIs embedding this post that the author has detached from.',
},
embeddingRules: {
description:
'List of rules defining who can embed this post. If value is an empty array or is undefined, no particular rules apply and anyone can embed.',
type: 'array',
maxLength: 5,
items: {
@ -7333,6 +7368,8 @@ export const schemaDict = {
description: 'Reference (AT-URI) to the post record.',
},
allow: {
description:
'List of rules defining who can reply to this post. If value is an empty array, no one can reply. If value is undefined, anyone can reply.',
type: 'array',
maxLength: 5,
items: {

@ -8,6 +8,8 @@ import { CID } from 'multiformats/cid'
import * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs'
import * as AppBskyGraphDefs from '../graph/defs'
import * as ComAtprotoRepoStrongRef from '../../../com/atproto/repo/strongRef'
import * as AppBskyFeedThreadgate from '../feed/threadgate'
import * as AppBskyFeedPostgate from '../feed/postgate'
export interface ProfileViewBasic {
did: string
@ -188,6 +190,7 @@ export type Preferences = (
| HiddenPostsPref
| BskyAppStatePref
| LabelersPref
| PostInteractionSettingsPref
| { $type: string; [k: string]: unknown }
)[]
@ -532,3 +535,36 @@ export function isNux(v: unknown): v is Nux {
export function validateNux(v: unknown): ValidationResult {
return lexicons.validate('app.bsky.actor.defs#nux', v)
}
/** Default post interaction settings for the account. These values should be applied as default values when creating new posts. These refs should mirror the threadgate and postgate records exactly. */
export interface PostInteractionSettingsPref {
/** Matches threadgate record. List of rules defining who can reply to this users posts. If value is an empty array, no one can reply. If value is undefined, anyone can reply. */
threadgateAllowRules?: (
| AppBskyFeedThreadgate.MentionRule
| AppBskyFeedThreadgate.FollowingRule
| AppBskyFeedThreadgate.ListRule
| { $type: string; [k: string]: unknown }
)[]
/** Matches postgate record. List of rules defining who can embed this users posts. If value is an empty array or is undefined, no particular rules apply and anyone can embed. */
postgateEmbeddingRules?: (
| AppBskyFeedPostgate.DisableRule
| { $type: string; [k: string]: unknown }
)[]
[k: string]: unknown
}
export function isPostInteractionSettingsPref(
v: unknown,
): v is PostInteractionSettingsPref {
return (
isObj(v) &&
hasProp(v, '$type') &&
v.$type === 'app.bsky.actor.defs#postInteractionSettingsPref'
)
}
export function validatePostInteractionSettingsPref(
v: unknown,
): ValidationResult {
return lexicons.validate('app.bsky.actor.defs#postInteractionSettingsPref', v)
}

@ -12,6 +12,7 @@ export interface Record {
post: string
/** List of AT-URIs embedding this post that the author has detached from. */
detachedEmbeddingUris?: string[]
/** List of rules defining who can embed this post. If value is an empty array or is undefined, no particular rules apply and anyone can embed. */
embeddingRules?: (DisableRule | { $type: string; [k: string]: unknown })[]
[k: string]: unknown
}

@ -9,6 +9,7 @@ import { CID } from 'multiformats/cid'
export interface Record {
/** Reference (AT-URI) to the post record. */
post: string
/** List of rules defining who can reply to this post. If value is an empty array, no one can reply. If value is undefined, anyone can reply. */
allow?: (
| MentionRule
| FollowingRule

@ -4381,6 +4381,7 @@ export const schemaDict = {
'lex:app.bsky.actor.defs#hiddenPostsPref',
'lex:app.bsky.actor.defs#bskyAppStatePref',
'lex:app.bsky.actor.defs#labelersPref',
'lex:app.bsky.actor.defs#postInteractionSettingsPref',
],
},
},
@ -4714,6 +4715,38 @@ export const schemaDict = {
},
},
},
postInteractionSettingsPref: {
type: 'object',
description:
'Default post interaction settings for the account. These values should be applied as default values when creating new posts. These refs should mirror the threadgate and postgate records exactly.',
required: [],
properties: {
threadgateAllowRules: {
description:
'Matches threadgate record. List of rules defining who can reply to this users posts. If value is an empty array, no one can reply. If value is undefined, anyone can reply.',
type: 'array',
maxLength: 5,
items: {
type: 'union',
refs: [
'lex:app.bsky.feed.threadgate#mentionRule',
'lex:app.bsky.feed.threadgate#followingRule',
'lex:app.bsky.feed.threadgate#listRule',
],
},
},
postgateEmbeddingRules: {
description:
'Matches postgate record. List of rules defining who can embed this users posts. If value is an empty array or is undefined, no particular rules apply and anyone can embed.',
type: 'array',
maxLength: 5,
items: {
type: 'union',
refs: ['lex:app.bsky.feed.postgate#disableRule'],
},
},
},
},
},
},
AppBskyActorGetPreferences: {
@ -7120,6 +7153,8 @@ export const schemaDict = {
'List of AT-URIs embedding this post that the author has detached from.',
},
embeddingRules: {
description:
'List of rules defining who can embed this post. If value is an empty array or is undefined, no particular rules apply and anyone can embed.',
type: 'array',
maxLength: 5,
items: {
@ -7333,6 +7368,8 @@ export const schemaDict = {
description: 'Reference (AT-URI) to the post record.',
},
allow: {
description:
'List of rules defining who can reply to this post. If value is an empty array, no one can reply. If value is undefined, anyone can reply.',
type: 'array',
maxLength: 5,
items: {

@ -8,6 +8,8 @@ import { CID } from 'multiformats/cid'
import * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs'
import * as AppBskyGraphDefs from '../graph/defs'
import * as ComAtprotoRepoStrongRef from '../../../com/atproto/repo/strongRef'
import * as AppBskyFeedThreadgate from '../feed/threadgate'
import * as AppBskyFeedPostgate from '../feed/postgate'
export interface ProfileViewBasic {
did: string
@ -188,6 +190,7 @@ export type Preferences = (
| HiddenPostsPref
| BskyAppStatePref
| LabelersPref
| PostInteractionSettingsPref
| { $type: string; [k: string]: unknown }
)[]
@ -532,3 +535,36 @@ export function isNux(v: unknown): v is Nux {
export function validateNux(v: unknown): ValidationResult {
return lexicons.validate('app.bsky.actor.defs#nux', v)
}
/** Default post interaction settings for the account. These values should be applied as default values when creating new posts. These refs should mirror the threadgate and postgate records exactly. */
export interface PostInteractionSettingsPref {
/** Matches threadgate record. List of rules defining who can reply to this users posts. If value is an empty array, no one can reply. If value is undefined, anyone can reply. */
threadgateAllowRules?: (
| AppBskyFeedThreadgate.MentionRule
| AppBskyFeedThreadgate.FollowingRule
| AppBskyFeedThreadgate.ListRule
| { $type: string; [k: string]: unknown }
)[]
/** Matches postgate record. List of rules defining who can embed this users posts. If value is an empty array or is undefined, no particular rules apply and anyone can embed. */
postgateEmbeddingRules?: (
| AppBskyFeedPostgate.DisableRule
| { $type: string; [k: string]: unknown }
)[]
[k: string]: unknown
}
export function isPostInteractionSettingsPref(
v: unknown,
): v is PostInteractionSettingsPref {
return (
isObj(v) &&
hasProp(v, '$type') &&
v.$type === 'app.bsky.actor.defs#postInteractionSettingsPref'
)
}
export function validatePostInteractionSettingsPref(
v: unknown,
): ValidationResult {
return lexicons.validate('app.bsky.actor.defs#postInteractionSettingsPref', v)
}

@ -12,6 +12,7 @@ export interface Record {
post: string
/** List of AT-URIs embedding this post that the author has detached from. */
detachedEmbeddingUris?: string[]
/** List of rules defining who can embed this post. If value is an empty array or is undefined, no particular rules apply and anyone can embed. */
embeddingRules?: (DisableRule | { $type: string; [k: string]: unknown })[]
[k: string]: unknown
}

@ -9,6 +9,7 @@ import { CID } from 'multiformats/cid'
export interface Record {
/** Reference (AT-URI) to the post record. */
post: string
/** List of rules defining who can reply to this post. If value is an empty array, no one can reply. If value is undefined, anyone can reply. */
allow?: (
| MentionRule
| FollowingRule