Docs and helpers (#38)
* improve docs & helpers around publisher dids * add docs to env
This commit is contained in:
parent
e849ac7f66
commit
cbdac3417e
@ -13,5 +13,10 @@ FEEDGEN_SUBSCRIPTION_ENDPOINT="wss://bsky.social"
|
|||||||
# Set this to the hostname that you intend to run the service at
|
# Set this to the hostname that you intend to run the service at
|
||||||
FEEDGEN_HOSTNAME="example.com"
|
FEEDGEN_HOSTNAME="example.com"
|
||||||
|
|
||||||
|
# Set this to the DID of the account you'll use to publish the feed
|
||||||
|
# You can find your accounts DID by going to
|
||||||
|
# https://bsky.social/xrpc/com.atproto.identity.resolveHandle?handle=${YOUR_HANDLE}
|
||||||
|
FEEDGEN_PUBLISHER_DID="did:plc:abcde...."
|
||||||
|
|
||||||
# Only use this if you want a service did different from did:web
|
# Only use this if you want a service did different from did:web
|
||||||
# FEEDGEN_SERVICE_DID="did:plc:abcde..."
|
# FEEDGEN_SERVICE_DID="did:plc:abcde..."
|
11
README.md
11
README.md
@ -1,10 +1,6 @@
|
|||||||
# ATProto Feed Generator
|
# ATProto Feed Generator
|
||||||
|
|
||||||
🚧 Work in Progress 🚧
|
This is a starter kit for creating ATProto Feed Generators. It's not feature complete, but should give you a good starting ground off of which to build and deploy a feed.
|
||||||
|
|
||||||
We are actively developing Feed Generator integration into the Bluesky Personal Data Server (PDS). Though we are reasonably confident about the general shape and interfaces laid out here, these interfaces and implementation details _are_ subject to change.
|
|
||||||
|
|
||||||
In the meantime, we've put together this starter kit for devs. It doesn't do everything, but it should be enough to get you familiar with the system and started building!
|
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
@ -44,6 +40,11 @@ Next, you will need to do two things:
|
|||||||
|
|
||||||
We've taken care of setting this server up with a did:web. However, you're free to switch this out for did:plc if you like - you may want to if you expect this Feed Generator to be long-standing and possibly migrating domains.
|
We've taken care of setting this server up with a did:web. However, you're free to switch this out for did:plc if you like - you may want to if you expect this Feed Generator to be long-standing and possibly migrating domains.
|
||||||
|
|
||||||
|
### Deploying your feed
|
||||||
|
Your feed will need to be accessible at the value supplied to the `FEEDGEN_HOSTNAME` environment variable.
|
||||||
|
|
||||||
|
The service must be set up to respond to HTTPS queries over port 443.
|
||||||
|
|
||||||
### Publishing your feed
|
### Publishing your feed
|
||||||
|
|
||||||
To publish your feed, go to the script at `scripts/publishFeedGen.ts` and fill in the variables at the top. Examples are included, and some are optional. To publish your feed generator, simply run `yarn publishFeed`.
|
To publish your feed, go to the script at `scripts/publishFeedGen.ts` and fill in the variables at the top. Examples are included, and some are optional. To publish your feed generator, simply run `yarn publishFeed`.
|
||||||
|
@ -8,7 +8,7 @@ import * as whatsAlf from './whats-alf'
|
|||||||
type AlgoHandler = (ctx: AppContext, params: QueryParams) => Promise<AlgoOutput>
|
type AlgoHandler = (ctx: AppContext, params: QueryParams) => Promise<AlgoOutput>
|
||||||
|
|
||||||
const algos: Record<string, AlgoHandler> = {
|
const algos: Record<string, AlgoHandler> = {
|
||||||
[whatsAlf.uri]: whatsAlf.handler,
|
[whatsAlf.shortname]: whatsAlf.handler,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default algos
|
export default algos
|
||||||
|
@ -2,7 +2,8 @@ import { InvalidRequestError } from '@atproto/xrpc-server'
|
|||||||
import { QueryParams } from '../lexicon/types/app/bsky/feed/getFeedSkeleton'
|
import { QueryParams } from '../lexicon/types/app/bsky/feed/getFeedSkeleton'
|
||||||
import { AppContext } from '../config'
|
import { AppContext } from '../config'
|
||||||
|
|
||||||
export const uri = 'at://did:example:alice/app.bsky.feed.generator/whats-alf'
|
// max 15 chars
|
||||||
|
export const shortname = 'whats-alf'
|
||||||
|
|
||||||
export const handler = async (ctx: AppContext, params: QueryParams) => {
|
export const handler = async (ctx: AppContext, params: QueryParams) => {
|
||||||
let builder = ctx.db
|
let builder = ctx.db
|
||||||
|
@ -14,4 +14,5 @@ export type Config = {
|
|||||||
sqliteLocation: string
|
sqliteLocation: string
|
||||||
subscriptionEndpoint: string
|
subscriptionEndpoint: string
|
||||||
serviceDid: string
|
serviceDid: string
|
||||||
|
publisherDid: string
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,8 @@ const run = async () => {
|
|||||||
subscriptionEndpoint:
|
subscriptionEndpoint:
|
||||||
maybeStr(process.env.FEEDGEN_SUBSCRIPTION_ENDPOINT) ??
|
maybeStr(process.env.FEEDGEN_SUBSCRIPTION_ENDPOINT) ??
|
||||||
'wss://bsky.social',
|
'wss://bsky.social',
|
||||||
|
publisherDid:
|
||||||
|
maybeStr(process.env.FEEDGEN_PUBLISHER_DID) ?? 'did:example:alice',
|
||||||
hostname,
|
hostname,
|
||||||
serviceDid,
|
serviceDid,
|
||||||
})
|
})
|
||||||
|
@ -1,10 +1,17 @@
|
|||||||
import { Server } from '../lexicon'
|
import { Server } from '../lexicon'
|
||||||
import { AppContext } from '../config'
|
import { AppContext } from '../config'
|
||||||
import algos from '../algos'
|
import algos from '../algos'
|
||||||
|
import { AtUri } from '@atproto/uri'
|
||||||
|
|
||||||
export default function (server: Server, ctx: AppContext) {
|
export default function (server: Server, ctx: AppContext) {
|
||||||
server.app.bsky.feed.describeFeedGenerator(async () => {
|
server.app.bsky.feed.describeFeedGenerator(async () => {
|
||||||
const feeds = Object.keys(algos).map((uri) => ({ uri }))
|
const feeds = Object.keys(algos).map((shortname) => ({
|
||||||
|
uri: AtUri.make(
|
||||||
|
ctx.cfg.publisherDid,
|
||||||
|
'app.bsky.feed.generator',
|
||||||
|
shortname,
|
||||||
|
).toString(),
|
||||||
|
}))
|
||||||
return {
|
return {
|
||||||
encoding: 'application/json',
|
encoding: 'application/json',
|
||||||
body: {
|
body: {
|
||||||
|
@ -3,11 +3,17 @@ import { Server } from '../lexicon'
|
|||||||
import { AppContext } from '../config'
|
import { AppContext } from '../config'
|
||||||
import algos from '../algos'
|
import algos from '../algos'
|
||||||
import { validateAuth } from '../auth'
|
import { validateAuth } from '../auth'
|
||||||
|
import { AtUri } from '@atproto/uri'
|
||||||
|
|
||||||
export default function (server: Server, ctx: AppContext) {
|
export default function (server: Server, ctx: AppContext) {
|
||||||
server.app.bsky.feed.getFeedSkeleton(async ({ params, req }) => {
|
server.app.bsky.feed.getFeedSkeleton(async ({ params, req }) => {
|
||||||
const algo = algos[params.feed]
|
const feedUri = new AtUri(params.feed)
|
||||||
if (!algo) {
|
const algo = algos[feedUri.rkey]
|
||||||
|
if (
|
||||||
|
feedUri.hostname !== ctx.cfg.publisherDid ||
|
||||||
|
feedUri.collection !== 'app.bsky.feed.generator' ||
|
||||||
|
!algo
|
||||||
|
) {
|
||||||
throw new InvalidRequestError(
|
throw new InvalidRequestError(
|
||||||
'Unsupported algorithm',
|
'Unsupported algorithm',
|
||||||
'UnsupportedAlgorithm',
|
'UnsupportedAlgorithm',
|
||||||
|
Loading…
Reference in New Issue
Block a user