Skip to content

Commit

Permalink
Feed context & sendInteractions impl (bluesky-social#2402)
Browse files Browse the repository at this point in the history
* forward feedContext on getFeed

* add sendInteractions to PDS

* fix typeof

* add feedContext to snapshots

---------

Co-authored-by: Devin Ivy <[email protected]>
  • Loading branch information
dholms and devinivy authored Apr 26, 2024
1 parent 65a9fd7 commit e306304
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 18 deletions.
33 changes: 16 additions & 17 deletions packages/bsky/src/api/app/bsky/feed/getFeed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ const skeleton = async (

return {
cursor,
items: algoItems.map(toFeedItem),
items: algoItems,
timerSkele: timerSkele.stop(),
timerHydr: new ServerTimer('hydr').start(),
resHeaders,
Expand Down Expand Up @@ -126,7 +126,12 @@ const presentation = (
) => {
const { ctx, params, skeleton, hydration } = inputs
const feed = mapDefined(skeleton.items, (item) => {
return ctx.views.feedViewPost(item, hydration)
const post = ctx.views.feedViewPost(item, hydration)
if (!post) return
return {
...post,
feedContext: item.feedContext,
}
}).slice(0, params.limit)
return {
feed,
Expand All @@ -146,7 +151,7 @@ type Params = GetFeedParams & {
}

type Skeleton = {
items: FeedItem[]
items: AlgoResponseItem[]
passthrough: Record<string, unknown> // pass through additional items in feedgen response
resHeaders?: Record<string, string>
cursor?: string
Expand Down Expand Up @@ -228,9 +233,12 @@ const skeletonFromFeedGen = async (

const { feed: feedSkele, ...skele } = skeleton
const feedItems = feedSkele.map((item) => ({
itemUri:
typeof item.reason?.repost === 'string' ? item.reason.repost : item.post,
postUri: item.post,
post: { uri: item.post },
repost:
typeof item.reason?.repost === 'string'
? { uri: item.reason.repost }
: undefined,
feedContext: item.feedContext,
}))

return { ...skele, resHeaders, feedItems }
Expand All @@ -242,15 +250,6 @@ export type AlgoResponse = {
cursor?: string
}

export type AlgoResponseItem = {
itemUri: string
postUri: string
export type AlgoResponseItem = FeedItem & {
feedContext?: string
}

export const toFeedItem = (feedItem: AlgoResponseItem): FeedItem => ({
post: { uri: feedItem.postUri },
repost:
feedItem.itemUri === feedItem.postUri
? undefined
: { uri: feedItem.itemUri },
})
11 changes: 11 additions & 0 deletions packages/bsky/tests/__snapshots__/feed-generation.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ Array [
exports[`feed generation getFeed paginates, handling replies and reposts. 1`] = `
Array [
Object {
"feedContext": "item-0",
"post": Object {
"author": Object {
"avatar": "https://bsky.public.url/img/avatar/plain/user(1)/cids(1)@jpeg",
Expand Down Expand Up @@ -401,6 +402,7 @@ Array [
},
},
Object {
"feedContext": "item-1",
"post": Object {
"author": Object {
"avatar": "https://bsky.public.url/img/avatar/plain/user(3)/cids(1)@jpeg",
Expand Down Expand Up @@ -435,6 +437,7 @@ Array [
},
},
Object {
"feedContext": "item-2",
"post": Object {
"author": Object {
"did": "user(4)",
Expand Down Expand Up @@ -554,6 +557,7 @@ Array [
},
},
Object {
"feedContext": "item-4",
"post": Object {
"author": Object {
"did": "user(4)",
Expand Down Expand Up @@ -678,6 +682,7 @@ Array [
},
},
Object {
"feedContext": "item-5",
"post": Object {
"author": Object {
"did": "user(6)",
Expand Down Expand Up @@ -865,6 +870,7 @@ Array [
exports[`feed generation getFeed resolves basic feed contents without auth. 1`] = `
Array [
Object {
"feedContext": "item-0",
"post": Object {
"author": Object {
"avatar": "https://bsky.public.url/img/avatar/plain/user(1)/cids(1)@jpeg",
Expand Down Expand Up @@ -919,6 +925,7 @@ Array [
},
},
Object {
"feedContext": "item-2",
"post": Object {
"author": Object {
"did": "user(2)",
Expand Down Expand Up @@ -1023,6 +1030,7 @@ Array [
},
},
Object {
"feedContext": "item-4",
"post": Object {
"author": Object {
"did": "user(2)",
Expand Down Expand Up @@ -1135,6 +1143,7 @@ Array [
exports[`feed generation getFeed resolves basic feed contents. 1`] = `
Array [
Object {
"feedContext": "item-0",
"post": Object {
"author": Object {
"avatar": "https://bsky.public.url/img/avatar/plain/user(1)/cids(1)@jpeg",
Expand Down Expand Up @@ -1194,6 +1203,7 @@ Array [
},
},
Object {
"feedContext": "item-2",
"post": Object {
"author": Object {
"did": "user(2)",
Expand Down Expand Up @@ -1313,6 +1323,7 @@ Array [
},
},
Object {
"feedContext": "item-4",
"post": Object {
"author": Object {
"did": "user(2)",
Expand Down
2 changes: 1 addition & 1 deletion packages/bsky/tests/feed-generation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ describe('feed generation', () => {
repost: sc.reposts[sc.dids.carol][0].uriStr,
},
},
]
].map((item, i) => ({ ...item, feedContext: `item-${i}` })) // add a deterministic context to test passthrough
const offset = cursor ? parseInt(cursor, 10) : 0
const fullFeed = candidates.filter((_, i) => {
if (feedName === 'even') {
Expand Down
2 changes: 2 additions & 0 deletions packages/pds/src/api/app/bsky/feed/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import getRepostedBy from './getRepostedBy'
import getSuggestedFeeds from './getSuggestedFeeds'
import getTimeline from './getTimeline'
import searchPosts from './searchPosts'
import sendInteractions from './sendInteractions'

export default function (server: Server, ctx: AppContext) {
getActorFeeds(server, ctx)
Expand All @@ -30,4 +31,5 @@ export default function (server: Server, ctx: AppContext) {
getSuggestedFeeds(server, ctx)
getTimeline(server, ctx)
searchPosts(server, ctx)
sendInteractions(server, ctx)
}
13 changes: 13 additions & 0 deletions packages/pds/src/api/app/bsky/feed/sendInteractions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Server } from '../../../../lexicon'
import AppContext from '../../../../context'
import { pipethroughProcedure } from '../../../../pipethrough'

export default function (server: Server, ctx: AppContext) {
server.app.bsky.feed.sendInteractions({
auth: ctx.authVerifier.access,
handler: async ({ input, auth, req }) => {
const requester = auth.credentials.did
return pipethroughProcedure(ctx, req, input.body, requester)
},
})
}

0 comments on commit e306304

Please sign in to comment.