feat: Add scripts for sending admin and test notes via Nostr

- Introduce `send_admin_note.js` for sending community announcements to Nostr relays.
- Implement `send_test_note.js` for testing note sending with specified private key and relay URL.
- Enhance `NostrFeed.vue` to filter notes based on admin pubkeys and display appropriate titles and descriptions for different feed types.
- Update `Home.vue` to use the announcements feed type for the Nostr feed component.
This commit is contained in:
padreug 2025-07-02 18:12:02 +02:00
parent ee7eb461c4
commit 97db2a2fec
5 changed files with 314 additions and 54 deletions

View file

@ -61,7 +61,7 @@ export class NostrClient {
} = {}): Promise<NostrNote[]> {
const {
limit = 20,
since = Math.floor((Date.now() - 24 * 60 * 60 * 1000) / 1000),
since = Math.floor((Date.now() - 7 * 24 * 60 * 60 * 1000) / 1000), // Last 7 days
authors,
includeReplies = false
} = options
@ -69,45 +69,25 @@ export class NostrClient {
const filters: Filter[] = [
{
kinds: [EventKinds.TEXT_NOTE],
since,
limit,
...(authors && { authors })
}
]
// Also fetch reactions and replies for engagement data
const engagementFilters: Filter[] = [
{
kinds: [EventKinds.REACTION, EventKinds.TEXT_NOTE],
since,
limit: limit * 5 // Get more for engagement calculation
}
]
try {
// Get events from all relays
const [noteEvents, engagementEvents] = await Promise.all([
Promise.all(
this.relays.map(async (relay) => {
try {
return await this.pool.querySync([relay], filters)
} catch (error) {
console.warn(`Failed to fetch notes from relay ${relay}:`, error)
return []
}
})
),
Promise.all(
this.relays.map(async (relay) => {
try {
return await this.pool.querySync([relay], engagementFilters)
} catch (error) {
console.warn(`Failed to fetch engagement from relay ${relay}:`, error)
return []
}
})
)
])
// Get events from all relays using the working get() method
const noteEvents = await Promise.all(
this.relays.map(async (relay) => {
try {
const filter = filters[0]
const singleEvent = await this.pool.get([relay], filter)
return singleEvent ? [singleEvent] : []
} catch (error) {
console.warn(`Failed to fetch notes from relay ${relay}:`, error)
return []
}
})
)
// Flatten and deduplicate events by ID
const uniqueNotes = Array.from(
@ -116,24 +96,16 @@ export class NostrClient {
).values()
)
const allEngagementEvents = engagementEvents.flat()
// Extract engagement data
const reactions = extractReactions(allEngagementEvents)
const replyCounts = extractReplyCounts(allEngagementEvents)
// Process notes with engagement data
// Process notes with basic info (engagement data disabled for now)
let processedNotes = uniqueNotes
.map((event: Event): NostrNote => {
const replyInfo = getReplyInfo(event)
const eventReactions = reactions.get(event.id) || {}
const reactionCount = Object.values(eventReactions).reduce((sum, count) => sum + count, 0)
return {
...event,
replyCount: replyCounts.get(event.id) || 0,
reactionCount,
reactions: eventReactions,
replyCount: 0,
reactionCount: 0,
reactions: {},
isReply: replyInfo.isReply,
replyTo: replyInfo.replyTo,
mentions: replyInfo.mentions