Skip to content

Commit

Permalink
add getFeedSuggestions (bluesky-social#1542)
Browse files Browse the repository at this point in the history
* add getFeedSuggestions lex

* move to feed namespace

* codegen

* add table and migration

* add endpoints

* remove comment

* add test

* fix order

* rename

* just remove proxy check
  • Loading branch information
estrattonbailey authored Aug 31, 2023
1 parent 9a0fd91 commit f84027f
Show file tree
Hide file tree
Showing 20 changed files with 575 additions and 1 deletion.
31 changes: 31 additions & 0 deletions lexicons/app/bsky/feed/getSuggestedFeeds.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"lexicon": 1,
"id": "app.bsky.feed.getSuggestedFeeds",
"defs": {
"main": {
"type": "query",
"description": "Get a list of suggested feeds for the viewer.",
"parameters": {
"type": "params",
"properties": {
"limit": {"type": "integer", "minimum": 1, "maximum": 100, "default": 50},
"cursor": {"type": "string"}
}
},
"output": {
"encoding": "application/json",
"schema": {
"type": "object",
"required": ["feeds"],
"properties": {
"cursor": {"type": "string"},
"feeds": {
"type": "array",
"items": {"type": "ref", "ref": "app.bsky.feed.defs#generatorView"}
}
}
}
}
}
}
}
13 changes: 13 additions & 0 deletions packages/api/src/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ import * as AppBskyFeedGetLikes from './types/app/bsky/feed/getLikes'
import * as AppBskyFeedGetPostThread from './types/app/bsky/feed/getPostThread'
import * as AppBskyFeedGetPosts from './types/app/bsky/feed/getPosts'
import * as AppBskyFeedGetRepostedBy from './types/app/bsky/feed/getRepostedBy'
import * as AppBskyFeedGetSuggestedFeeds from './types/app/bsky/feed/getSuggestedFeeds'
import * as AppBskyFeedGetTimeline from './types/app/bsky/feed/getTimeline'
import * as AppBskyFeedLike from './types/app/bsky/feed/like'
import * as AppBskyFeedPost from './types/app/bsky/feed/post'
Expand Down Expand Up @@ -219,6 +220,7 @@ export * as AppBskyFeedGetLikes from './types/app/bsky/feed/getLikes'
export * as AppBskyFeedGetPostThread from './types/app/bsky/feed/getPostThread'
export * as AppBskyFeedGetPosts from './types/app/bsky/feed/getPosts'
export * as AppBskyFeedGetRepostedBy from './types/app/bsky/feed/getRepostedBy'
export * as AppBskyFeedGetSuggestedFeeds from './types/app/bsky/feed/getSuggestedFeeds'
export * as AppBskyFeedGetTimeline from './types/app/bsky/feed/getTimeline'
export * as AppBskyFeedLike from './types/app/bsky/feed/like'
export * as AppBskyFeedPost from './types/app/bsky/feed/post'
Expand Down Expand Up @@ -1357,6 +1359,17 @@ export class FeedNS {
})
}

getSuggestedFeeds(
params?: AppBskyFeedGetSuggestedFeeds.QueryParams,
opts?: AppBskyFeedGetSuggestedFeeds.CallOptions,
): Promise<AppBskyFeedGetSuggestedFeeds.Response> {
return this._service.xrpc
.call('app.bsky.feed.getSuggestedFeeds', params, undefined, opts)
.catch((e) => {
throw AppBskyFeedGetSuggestedFeeds.toKnownErr(e)
})
}

getTimeline(
params?: AppBskyFeedGetTimeline.QueryParams,
opts?: AppBskyFeedGetTimeline.CallOptions,
Expand Down
44 changes: 44 additions & 0 deletions packages/api/src/client/lexicons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5302,6 +5302,49 @@ export const schemaDict = {
},
},
},
AppBskyFeedGetSuggestedFeeds: {
lexicon: 1,
id: 'app.bsky.feed.getSuggestedFeeds',
defs: {
main: {
type: 'query',
description: 'Get a list of suggested feeds for the viewer.',
parameters: {
type: 'params',
properties: {
limit: {
type: 'integer',
minimum: 1,
maximum: 100,
default: 50,
},
cursor: {
type: 'string',
},
},
},
output: {
encoding: 'application/json',
schema: {
type: 'object',
required: ['feeds'],
properties: {
cursor: {
type: 'string',
},
feeds: {
type: 'array',
items: {
type: 'ref',
ref: 'lex:app.bsky.feed.defs#generatorView',
},
},
},
},
},
},
},
},
AppBskyFeedGetTimeline: {
lexicon: 1,
id: 'app.bsky.feed.getTimeline',
Expand Down Expand Up @@ -6705,6 +6748,7 @@ export const ids = {
AppBskyFeedGetPostThread: 'app.bsky.feed.getPostThread',
AppBskyFeedGetPosts: 'app.bsky.feed.getPosts',
AppBskyFeedGetRepostedBy: 'app.bsky.feed.getRepostedBy',
AppBskyFeedGetSuggestedFeeds: 'app.bsky.feed.getSuggestedFeeds',
AppBskyFeedGetTimeline: 'app.bsky.feed.getTimeline',
AppBskyFeedLike: 'app.bsky.feed.like',
AppBskyFeedPost: 'app.bsky.feed.post',
Expand Down
38 changes: 38 additions & 0 deletions packages/api/src/client/types/app/bsky/feed/getSuggestedFeeds.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* GENERATED CODE - DO NOT MODIFY
*/
import { Headers, XRPCError } from '@atproto/xrpc'
import { ValidationResult, BlobRef } from '@atproto/lexicon'
import { isObj, hasProp } from '../../../../util'
import { lexicons } from '../../../../lexicons'
import { CID } from 'multiformats/cid'
import * as AppBskyFeedDefs from './defs'

export interface QueryParams {
limit?: number
cursor?: string
}

export type InputSchema = undefined

export interface OutputSchema {
cursor?: string
feeds: AppBskyFeedDefs.GeneratorView[]
[k: string]: unknown
}

export interface CallOptions {
headers?: Headers
}

export interface Response {
success: boolean
headers: Headers
data: OutputSchema
}

export function toKnownErr(e: any) {
if (e instanceof XRPCError) {
}
return e
}
39 changes: 39 additions & 0 deletions packages/bsky/src/api/app/bsky/feed/getSuggestedFeeds.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Server } from '../../../../lexicon'
import AppContext from '../../../../context'

export default function (server: Server, ctx: AppContext) {
server.app.bsky.feed.getSuggestedFeeds({
auth: ctx.authOptionalVerifier,
handler: async ({ auth }) => {
const viewer = auth.credentials.did

const db = ctx.db.getReplica()
const feedService = ctx.services.feed(db)
const feedsRes = await db.db
.selectFrom('suggested_feed')
.orderBy('suggested_feed.order', 'asc')
.selectAll()
.execute()

const genInfos = await feedService.getFeedGeneratorInfos(
feedsRes.map((r) => r.uri),
viewer,
)
const genList = Object.values(genInfos)

const creators = genList.map((gen) => gen.creator)
const profiles = await feedService.getActorInfos(creators, viewer)

const feedViews = genList.map((gen) =>
feedService.views.formatFeedGeneratorView(gen, profiles),
)

return {
encoding: 'application/json',
body: {
feeds: feedViews,
},
}
},
})
}
2 changes: 2 additions & 0 deletions packages/bsky/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import AppContext from '../context'
import describeFeedGenerator from './app/bsky/feed/describeFeedGenerator'
import getTimeline from './app/bsky/feed/getTimeline'
import getActorFeeds from './app/bsky/feed/getActorFeeds'
import getSuggestedFeeds from './app/bsky/feed/getSuggestedFeeds'
import getAuthorFeed from './app/bsky/feed/getAuthorFeed'
import getFeed from './app/bsky/feed/getFeed'
import getFeedGenerator from './app/bsky/feed/getFeedGenerator'
Expand Down Expand Up @@ -60,6 +61,7 @@ export default function (server: Server, ctx: AppContext) {
describeFeedGenerator(server, ctx)
getTimeline(server, ctx)
getActorFeeds(server, ctx)
getSuggestedFeeds(server, ctx)
getAuthorFeed(server, ctx)
getFeed(server, ctx)
getFeedGenerator(server, ctx)
Expand Down
4 changes: 3 additions & 1 deletion packages/bsky/src/db/database-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import * as label from './tables/label'
import * as algo from './tables/algo'
import * as viewParam from './tables/view-param'
import * as suggestedFollow from './tables/suggested-follow'
import * as suggestedFeed from './tables/suggested-feed'

export type DatabaseSchemaType = duplicateRecord.PartialDB &
profile.PartialDB &
Expand Down Expand Up @@ -57,7 +58,8 @@ export type DatabaseSchemaType = duplicateRecord.PartialDB &
label.PartialDB &
algo.PartialDB &
viewParam.PartialDB &
suggestedFollow.PartialDB
suggestedFollow.PartialDB &
suggestedFeed.PartialDB

export type DatabaseSchema = Kysely<DatabaseSchemaType>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Kysely } from 'kysely'

export async function up(db: Kysely<unknown>): Promise<void> {
await db.schema
.createTable('suggested_feed')
.addColumn('uri', 'varchar', (col) => col.primaryKey())
.addColumn('order', 'integer', (col) => col.notNull())
.execute()
}

export async function down(db: Kysely<unknown>): Promise<void> {
await db.schema.dropTable('suggested_feed').execute()
}
1 change: 1 addition & 0 deletions packages/bsky/src/db/migrations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ export * as _20230807T035309811Z from './20230807T035309811Z-feed-item-delete-in
export * as _20230808T172902639Z from './20230808T172902639Z-repo-rev'
export * as _20230810T203349843Z from './20230810T203349843Z-action-duration'
export * as _20230817T195936007Z from './20230817T195936007Z-native-notifications'
export * as _20230830T205507322Z from './20230830T205507322Z-suggested-feeds'
10 changes: 10 additions & 0 deletions packages/bsky/src/db/tables/suggested-feed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export const tableName = 'suggested_feed'

export interface SuggestedFeed {
uri: string
order: number
}

export type PartialDB = {
[tableName]: SuggestedFeed
}
12 changes: 12 additions & 0 deletions packages/bsky/src/lexicon/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ import * as AppBskyFeedGetLikes from './types/app/bsky/feed/getLikes'
import * as AppBskyFeedGetPostThread from './types/app/bsky/feed/getPostThread'
import * as AppBskyFeedGetPosts from './types/app/bsky/feed/getPosts'
import * as AppBskyFeedGetRepostedBy from './types/app/bsky/feed/getRepostedBy'
import * as AppBskyFeedGetSuggestedFeeds from './types/app/bsky/feed/getSuggestedFeeds'
import * as AppBskyFeedGetTimeline from './types/app/bsky/feed/getTimeline'
import * as AppBskyGraphGetBlocks from './types/app/bsky/graph/getBlocks'
import * as AppBskyGraphGetFollowers from './types/app/bsky/graph/getFollowers'
Expand Down Expand Up @@ -1153,6 +1154,17 @@ export class FeedNS {
return this._server.xrpc.method(nsid, cfg)
}

getSuggestedFeeds<AV extends AuthVerifier>(
cfg: ConfigOf<
AV,
AppBskyFeedGetSuggestedFeeds.Handler<ExtractAuth<AV>>,
AppBskyFeedGetSuggestedFeeds.HandlerReqCtx<ExtractAuth<AV>>
>,
) {
const nsid = 'app.bsky.feed.getSuggestedFeeds' // @ts-ignore
return this._server.xrpc.method(nsid, cfg)
}

getTimeline<AV extends AuthVerifier>(
cfg: ConfigOf<
AV,
Expand Down
44 changes: 44 additions & 0 deletions packages/bsky/src/lexicon/lexicons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5302,6 +5302,49 @@ export const schemaDict = {
},
},
},
AppBskyFeedGetSuggestedFeeds: {
lexicon: 1,
id: 'app.bsky.feed.getSuggestedFeeds',
defs: {
main: {
type: 'query',
description: 'Get a list of suggested feeds for the viewer.',
parameters: {
type: 'params',
properties: {
limit: {
type: 'integer',
minimum: 1,
maximum: 100,
default: 50,
},
cursor: {
type: 'string',
},
},
},
output: {
encoding: 'application/json',
schema: {
type: 'object',
required: ['feeds'],
properties: {
cursor: {
type: 'string',
},
feeds: {
type: 'array',
items: {
type: 'ref',
ref: 'lex:app.bsky.feed.defs#generatorView',
},
},
},
},
},
},
},
},
AppBskyFeedGetTimeline: {
lexicon: 1,
id: 'app.bsky.feed.getTimeline',
Expand Down Expand Up @@ -6705,6 +6748,7 @@ export const ids = {
AppBskyFeedGetPostThread: 'app.bsky.feed.getPostThread',
AppBskyFeedGetPosts: 'app.bsky.feed.getPosts',
AppBskyFeedGetRepostedBy: 'app.bsky.feed.getRepostedBy',
AppBskyFeedGetSuggestedFeeds: 'app.bsky.feed.getSuggestedFeeds',
AppBskyFeedGetTimeline: 'app.bsky.feed.getTimeline',
AppBskyFeedLike: 'app.bsky.feed.like',
AppBskyFeedPost: 'app.bsky.feed.post',
Expand Down
48 changes: 48 additions & 0 deletions packages/bsky/src/lexicon/types/app/bsky/feed/getSuggestedFeeds.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* GENERATED CODE - DO NOT MODIFY
*/
import express from 'express'
import { ValidationResult, BlobRef } from '@atproto/lexicon'
import { lexicons } from '../../../../lexicons'
import { isObj, hasProp } from '../../../../util'
import { CID } from 'multiformats/cid'
import { HandlerAuth } from '@atproto/xrpc-server'
import * as AppBskyFeedDefs from './defs'

export interface QueryParams {
limit: number
cursor?: string
}

export type InputSchema = undefined

export interface OutputSchema {
cursor?: string
feeds: AppBskyFeedDefs.GeneratorView[]
[k: string]: unknown
}

export type HandlerInput = undefined

export interface HandlerSuccess {
encoding: 'application/json'
body: OutputSchema
headers?: { [key: string]: string }
}

export interface HandlerError {
status: number
message?: string
}

export type HandlerOutput = HandlerError | HandlerSuccess
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
auth: HA
params: QueryParams
input: HandlerInput
req: express.Request
res: express.Response
}
export type Handler<HA extends HandlerAuth = never> = (
ctx: HandlerReqCtx<HA>,
) => Promise<HandlerOutput> | HandlerOutput
Loading

0 comments on commit f84027f

Please sign in to comment.