Add avatar-bubbles endpoint to bskyogcard (#10327)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: rafaeleyng <rafaeleyng@gmail.com>
This commit is contained in:
Samuel Newman
2026-05-12 17:54:00 +01:00
committed by GitHub
parent a03cbd8b1a
commit f527b35244
14 changed files with 259 additions and 55 deletions
+6 -34
View File
@@ -1,6 +1,5 @@
import assert from 'node:assert'
import React from 'react'
import {type AppBskyGraphDefs, AtUri} from '@atproto/api'
import resvg from '@resvg/resvg-js'
import {type Express} from 'express'
@@ -14,7 +13,12 @@ import {
import {type AppContext} from '../context.js'
import {httpLogger} from '../logger.js'
import {loadEmojiAsSvg} from '../util.js'
import {handler, originVerifyMiddleware} from './util.js'
import {
getImage,
handler,
hideAvatarLabels,
originVerifyMiddleware,
} from './util.js'
export default function (ctx: AppContext, app: Express) {
return app.get(
@@ -87,35 +91,3 @@ export default function (ctx: AppContext, app: Express) {
}),
)
}
async function getImage(url: string) {
const response = await fetch(ensureJpeg(url))
const arrayBuf = await response.arrayBuffer() // must drain body even if it will be discarded
if (response.status !== 200) return null
return Buffer.from(arrayBuf)
}
// CDN URLs end with @jpeg, @webp, or no extension (which may default to webp).
// We want to ensure the image URLs we use are for jpegs, required for compat with satori.
function ensureJpeg(url: string) {
return url.replace(/(@[a-z]{3,5})?$/, '@jpeg')
}
const hideAvatarLabels = new Set([
'!hide',
'!warn',
'porn',
'sexual',
'nudity',
'sexual-figurative',
'graphic-media',
'gore',
'self-harm',
'sensitive',
'security',
'impersonation',
'scam',
'spam',
'misleading',
'inauthentic',
])