@nexafon/node needs Node 20.19 or later and has no dependencies. Types are included.
npm install @nexafon/nodeToken endpoint
Section titled “Token endpoint”// The SDK calls getUserToken whenever it needs a session; answer with a fresh token for the signed-in user.if (req.method === 'POST' && req.url === '/nexafon-token') { const user = signedInUser(req) if (!user) { res.writeHead(401).end() return } if (!mayUseNexafon(user)) { res.writeHead(403).end() return } // Signed with NEXAFON_SECRET_KEY (sk_test_… or sk_live_…), which never leaves this server. const token = createUserToken({ userId: user.id, name: user.name, role: 'agent', email: user.email, // Nexafon links a first sign-in to the member with this email only when it is verified: never send true for // an address your app has not confirmed, or whoever sets a member's email on your app acts as that member. emailVerified: user.emailVerified, }) res.writeHead(200, { 'content-type': 'text/plain', 'cache-control': 'no-store' }).end(token) return}Options: secretKey (defaults to NEXAFON_SECRET_KEY), expiresIn in seconds (default 300, at most 600). An invalid
input throws a NexafonTokenError naming the problem.
Webhook receiver
Section titled “Webhook receiver”if (req.method === 'POST' && req.url === '/hooks/nexafon') { try { // The raw body, exactly as received: parsing it first changes the bytes the signature covers. const event = verifyWebhook( req.headers, await rawBody(req), process.env.NEXAFON_WEBHOOK_SECRET ?? '', ) // Deliveries can repeat: skip an event.id you have already handled. console.log(event.type, event.id) res.writeHead(204).end() } catch (err) { if (!(err instanceof WebhookVerificationError)) throw err res.writeHead(400).end() } return}verifyWebhook(headers, rawBody, secret) accepts Node’s req.headers, a Fetch Headers object or a plain record;
secret can be a list while you rotate. With Express, read the body with express.raw({ type: 'application/json' })
so it stays raw.
The whole file runs as is (node server.ts); it is the quickstart server. For partners, see the
Partner API.