use neynar notifs

This commit is contained in:
lucas-neynar
2025-03-14 17:02:56 -07:00
parent 710c8255bf
commit c9deb0512c
8 changed files with 187 additions and 212 deletions

View File

@@ -2,6 +2,9 @@ import { NeynarAPIClient } from '@neynar/nodejs-sdk';
let neynarClient: NeynarAPIClient | null = null;
// Example usage:
// const client = getNeynarClient();
// const user = await client.lookupUserByFid(fid);
export function getNeynarClient() {
if (!neynarClient) {
const apiKey = process.env.NEYNAR_API_KEY;
@@ -13,6 +16,46 @@ export function getNeynarClient() {
return neynarClient;
}
// Example usage:
// const client = getNeynarClient();
// const user = await client.lookupUserByFid(fid);
type SendFrameNotificationResult =
| {
state: "error";
error: unknown;
}
| { state: "no_token" }
| { state: "rate_limit" }
| { state: "success" };
export async function sendNeynarFrameNotification({
fid,
title,
body,
}: {
fid: number;
title: string;
body: string;
}): Promise<SendFrameNotificationResult> {
try {
const client = getNeynarClient();
const targetFids = [fid];
const notification = {
title,
body,
target_url: process.env.NEXT_PUBLIC_URL,
};
const result = await client.publishFrameNotifications({
targetFids,
notification
});
if (result.success) {
return { state: "success" };
} else if (result.status === 429) {
return { state: "rate_limit" };
} else {
return { state: "error", error: result.error || "Unknown error" };
}
} catch (error) {
return { state: "error", error };
}
}

View File

@@ -62,6 +62,13 @@ export async function generateFarcasterMetadata() {
};
}
// Determine webhook URL based on whether Neynar is enabled
const neynarApiKey = process.env.NEYNAR_API_KEY;
const neynarClientId = process.env.NEYNAR_CLIENT_ID;
const webhookUrl = neynarApiKey && neynarClientId
? `https://api.neynar.com/f/app/${neynarClientId}/event`
: `${appUrl}/api/webhook`;
return {
accountAssociation,
frame: {
@@ -73,7 +80,7 @@ export async function generateFarcasterMetadata() {
buttonTitle: process.env.NEXT_PUBLIC_FRAME_BUTTON_TEXT || "Launch Frame",
splashImageUrl: process.env.NEXT_PUBLIC_FRAME_SPLASH_IMAGE_URL || `${appUrl}/splash.png`,
splashBackgroundColor: "#f7f7f7",
webhookUrl: `${appUrl}/api/webhook`,
webhookUrl,
},
};
}