diff --git a/services/nostr-band/nostr-band-followers.service.js b/services/nostr-band/nostr-band-followers.service.js new file mode 100644 index 0000000000000..f9133e928e909 --- /dev/null +++ b/services/nostr-band/nostr-band-followers.service.js @@ -0,0 +1,67 @@ +import Joi from 'joi' +import { metric } from '../text-formatters.js' +import { BaseJsonService, pathParams } from '../index.js' + +const npubSchema = Joi.object({ + followers_pubkey_count: Joi.number().required(), +}).required() + +const mainSchema = Joi.object({ + stats: Joi.object() + .pattern(Joi.string(), npubSchema) + .min(1) + .max(1) + .required(), +}).required() + +export default class NostrBandFollowers extends BaseJsonService { + static category = 'social' + + static route = { + base: 'nostr-band/followers', + pattern: ':npub', + } + + static openApi = { + '/nostr-band/followers/{npub}': { + get: { + summary: 'Nostr.band Followers', + description: + 'Returns the number of followers for a Nostr pubkey using the Nostr.band API.', + parameters: pathParams({ + name: 'npub', + description: 'Nostr pubkey in (npub1...) format or hex.', + example: + 'npub18c556t7n8xa3df2q82rwxejfglw5przds7sqvefylzjh8tjne28qld0we7', + }), + }, + }, + } + + static defaultBadgeData = { label: 'followers' } + + static render({ followers }) { + return { + message: metric(followers), + style: 'social', + } + } + + async fetch({ npub }) { + const data = await this._requestJson({ + url: `https://api.nostr.band/v0/stats/profile/${npub}`, + schema: mainSchema, + httpErrors: { + 400: 'invalid pubkey', + }, + }) + const stats = data.stats + const firstKey = Object.keys(stats)[0] + return stats[firstKey].followers_pubkey_count + } + + async handle({ npub }) { + const followers = await this.fetch({ npub }) + return this.constructor.render({ followers }) + } +} diff --git a/services/nostr-band/nostr-band-followers.tester.js b/services/nostr-band/nostr-band-followers.tester.js new file mode 100644 index 0000000000000..1a85f8c337337 --- /dev/null +++ b/services/nostr-band/nostr-band-followers.tester.js @@ -0,0 +1,15 @@ +import { isMetric } from '../test-validators.js' +import { createServiceTester } from '../tester.js' +export const t = await createServiceTester() + +t.create('fetch: valid npub') + .get('/npub18c556t7n8xa3df2q82rwxejfglw5przds7sqvefylzjh8tjne28qld0we7.json') + .expectBadge({ + label: 'followers', + message: isMetric, + }) + +t.create('fetch: invalid npub').get('/invalidnpub.json').expectBadge({ + label: 'followers', + message: 'invalid pubkey', +})