NestJS
Set up Pingback in your NestJS app with the @usepingback/nestjs adapter.
Installation
npm install @usepingback/nestjsModule Setup
Import PingbackModule and call register() in your root module. The module auto-registers a POST endpoint and scans your providers for decorated handlers on startup:
import { PingbackModule } from '@usepingback/nestjs';
@Module({
imports: [
PingbackModule.register({
apiKey: process.env.PINGBACK_API_KEY,
cronSecret: process.env.PINGBACK_CRON_SECRET,
baseUrl: process.env.APP_URL,
}),
],
})
export class AppModule {}Defining Functions
Use the @Cron and @Task decorators on methods in any injectable service. They are automatically discovered at startup:
import { Injectable } from '@nestjs/common';
import { Cron, Task, PingbackContext } from '@usepingback/nestjs';
@Injectable()
export class EmailService {
@Cron('send-emails', '*/15 * * * *', { retries: 3, timeout: '60s' })
async sendEmails(ctx: PingbackContext) {
const pending = await getPendingEmails();
for (const email of pending) {
await ctx.task('send-email', { id: email.id });
}
ctx.log(`Dispatched ${pending.length} emails`);
}
@Task('send-email', { retries: 2, timeout: '15s' })
async sendEmail(ctx: PingbackContext, payload: { id: string }) {
const email = await getEmail(payload.id);
await deliver(email);
ctx.log('Sent email', { id: payload.id });
}
}Structured Logging
The ctx object provides structured logging at multiple levels. All log entries are captured and returned to the platform with the execution result:
ctx.log('message'); // info
ctx.log('message', { key: 'value' }); // info with metadata
ctx.log.warn('slow query', { ms: 2500 }); // warning
ctx.log.error('failed', { code: 'E001' }); // error
ctx.log.debug('cache stats', { hits: 847 }); // debugFan-Out
Dispatch background tasks from within a cron handler using ctx.task(). Each task runs independently with its own retries and timeout:
@Cron('process-orders', '0 * * * *', { retries: 3, timeout: '120s' })
async processOrders(ctx: PingbackContext) {
const orders = await getUnprocessedOrders();
for (const order of orders) {
await ctx.task('fulfill-order', { orderId: order.id });
}
ctx.log(`Dispatched ${orders.length} orders for fulfillment`);
}Configuration
The full set of options accepted by PingbackModule.register():
PingbackModule.register({
apiKey: string; // Required — your project API key
cronSecret: string; // Required — request signing secret
baseUrl?: string; // Your app's public URL
routePath?: string; // default: /api/pingback
platformUrl?: string; // default: https://api.pingback.lol
})Environment Variables
Add these to your .env file:
PINGBACK_API_KEY=pb_live_your_api_key_here
PINGBACK_CRON_SECRET=your_cron_secret_here| Variable | Description |
|---|---|
| PINGBACK_API_KEY | Your project API key. Found in the dashboard under API Keys. |
| PINGBACK_CRON_SECRET | Request signing secret. Found in the dashboard under project Settings. |
Local Development
Use npx pingback-nest dev [port] to test your cron jobs and tasks locally against the production Pingback platform. The CLI creates a secure tunnel to your local NestJS dev server so the platform can invoke your endpoint:
# Start your NestJS dev server, then in another terminal:
npx pingback-nest dev 3000Executions triggered from the dashboard or by schedule will be routed to your local machine, letting you debug with full access to local logs and breakpoints.
How It Works
1. On startup, the module scans all providers for @Cron and @Task decorators.
2. Discovered functions are registered with the Pingback platform via the API.
3. A POST endpoint is auto-registered at /api/pingback (configurable).
4. The platform sends signed execution requests to your endpoint on schedule.
5. The controller verifies the HMAC signature, executes the handler, and returns results with logs.