$ app.post('/webhooks/stripe', async (req, res) => { const event = stripe.webhooks.constructEvent( req.body, req.headers['stripe-signature'], process.env.STRIPE_WEBHOOK_SECRET ); // Your existing processing logic await handleStripeEvent(event); // Confirm to NotiLens that processing completed await notilens.track("stripe.webhook.processed", { type: event.type, customerId: event.data.object.customer }); res.json({ received: true });
});
app.post('/webhooks/stripe', async (req, res) => { const event = stripe.webhooks.constructEvent( req.body, req.headers['stripe-signature'], process.env.STRIPE_WEBHOOK_SECRET ); // Your existing processing logic await handleStripeEvent(event); // Confirm to NotiLens that processing completed await notilens.track("stripe.webhook.processed", { type: event.type, customerId: event.data.object.customer }); res.json({ received: true });
});
app.post('/webhooks/stripe', async (req, res) => { const event = stripe.webhooks.constructEvent( req.body, req.headers['stripe-signature'], process.env.STRIPE_WEBHOOK_SECRET ); // Your existing processing logic await handleStripeEvent(event); // Confirm to NotiLens that processing completed await notilens.track("stripe.webhook.processed", { type: event.type, customerId: event.data.object.customer }); res.json({ received: true });
});
// Track every signup
await notilens.track("user.signup.completed", { userId: user.id, plan: user.plan
}); // Track every activated user
await notilens.track("user.activated", { userId: user.id
});
// Track every signup
await notilens.track("user.signup.completed", { userId: user.id, plan: user.plan
}); // Track every activated user
await notilens.track("user.activated", { userId: user.id
});
// Track every signup
await notilens.track("user.signup.completed", { userId: user.id, plan: user.plan
}); // Track every activated user
await notilens.track("user.activated", { userId: user.id
});
// At the end of your cron job
const result = await processBillingRecords(); await notilens.track("billing.sync.job", { recordsProcessed: result.count, duration: result.durationMs
});
// At the end of your cron job
const result = await processBillingRecords(); await notilens.track("billing.sync.job", { recordsProcessed: result.count, duration: result.durationMs
});
// At the end of your cron job
const result = await processBillingRecords(); await notilens.track("billing.sync.job", { recordsProcessed: result.count, duration: result.durationMs
});
# .github/workflows/deploy.yml
name: Deploy on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Deploy to production run: ./deploy.sh - name: Notify deploy success if: success() uses: notilens/notify-action@v1 with: token: ${{ secrets.NOTILENS_TOKEN }} secret: ${{ secrets.NOTILENS_SECRET }} event: task.completed message: "Deployed to production — ${{ github.ref_name }}" tags: deploy,production open_url: https://myapp.com - name: Notify deploy failure if: failure() uses: notilens/notify-action@v1 with: token: ${{ secrets.NOTILENS_TOKEN }} secret: ${{ secrets.NOTILENS_SECRET }} event: task.failed message: "Production deployment failed — ${{github.ref_name }}"
# .github/workflows/deploy.yml
name: Deploy on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Deploy to production run: ./deploy.sh - name: Notify deploy success if: success() uses: notilens/notify-action@v1 with: token: ${{ secrets.NOTILENS_TOKEN }} secret: ${{ secrets.NOTILENS_SECRET }} event: task.completed message: "Deployed to production — ${{ github.ref_name }}" tags: deploy,production open_url: https://myapp.com - name: Notify deploy failure if: failure() uses: notilens/notify-action@v1 with: token: ${{ secrets.NOTILENS_TOKEN }} secret: ${{ secrets.NOTILENS_SECRET }} event: task.failed message: "Production deployment failed — ${{github.ref_name }}"
# .github/workflows/deploy.yml
name: Deploy on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Deploy to production run: ./deploy.sh - name: Notify deploy success if: success() uses: notilens/notify-action@v1 with: token: ${{ secrets.NOTILENS_TOKEN }} secret: ${{ secrets.NOTILENS_SECRET }} event: task.completed message: "Deployed to production — ${{ github.ref_name }}" tags: deploy,production open_url: https://myapp.com - name: Notify deploy failure if: failure() uses: notilens/notify-action@v1 with: token: ${{ secrets.NOTILENS_TOKEN }} secret: ${{ secrets.NOTILENS_SECRET }} event: task.failed message: "Production deployment failed — ${{github.ref_name }}"
// Track agent lifecycle
await nl.-weight: 500;">start('Agent run started', { task: 'report-agent' }); // Track token usage — ML detects anomalous spikes (loops)
await nl.metric({ tokens: response.usage.total_tokens }, { task: 'report-agent' }); // On completion
await nl.complete('Agent completed', { task: 'report-agent' }); // On loop/timeout detection
await nl.timeout('Agent exceeded expected duration', { task: 'report-agent' });
// Track agent lifecycle
await nl.-weight: 500;">start('Agent run started', { task: 'report-agent' }); // Track token usage — ML detects anomalous spikes (loops)
await nl.metric({ tokens: response.usage.total_tokens }, { task: 'report-agent' }); // On completion
await nl.complete('Agent completed', { task: 'report-agent' }); // On loop/timeout detection
await nl.timeout('Agent exceeded expected duration', { task: 'report-agent' });
// Track agent lifecycle
await nl.-weight: 500;">start('Agent run started', { task: 'report-agent' }); // Track token usage — ML detects anomalous spikes (loops)
await nl.metric({ tokens: response.usage.total_tokens }, { task: 'report-agent' }); // On completion
await nl.complete('Agent completed', { task: 'report-agent' }); // On loop/timeout detection
await nl.timeout('Agent exceeded expected duration', { task: 'report-agent' });
-weight: 500;">npm -weight: 500;">install @notilens/notilens
-weight: 500;">npm -weight: 500;">install @notilens/notilens
-weight: 500;">npm -weight: 500;">install @notilens/notilens
import { NotiLens } from '@notilens/notilens'; const nl = NotiLens.init('my-app', { token: 'YOUR_TOKEN', secret: 'YOUR_SECRET' }); // Track a business event
await nl.track('event.name', 'Event description', { meta: { ...metadata } }); // Task lifecycle
await nl.-weight: 500;">start('Job started', { task: 'job-name' });
await nl.complete('Job done', { task: 'job-name' });
await nl.fail('Job failed', { task: 'job-name' }); // Metrics
await nl.metric({ records: 1500, durationMs: 3200 }, { task: 'job-name' });
import { NotiLens } from '@notilens/notilens'; const nl = NotiLens.init('my-app', { token: 'YOUR_TOKEN', secret: 'YOUR_SECRET' }); // Track a business event
await nl.track('event.name', 'Event description', { meta: { ...metadata } }); // Task lifecycle
await nl.-weight: 500;">start('Job started', { task: 'job-name' });
await nl.complete('Job done', { task: 'job-name' });
await nl.fail('Job failed', { task: 'job-name' }); // Metrics
await nl.metric({ records: 1500, durationMs: 3200 }, { task: 'job-name' });
import { NotiLens } from '@notilens/notilens'; const nl = NotiLens.init('my-app', { token: 'YOUR_TOKEN', secret: 'YOUR_SECRET' }); // Track a business event
await nl.track('event.name', 'Event description', { meta: { ...metadata } }); // Task lifecycle
await nl.-weight: 500;">start('Job started', { task: 'job-name' });
await nl.complete('Job done', { task: 'job-name' });
await nl.fail('Job failed', { task: 'job-name' }); // Metrics
await nl.metric({ records: 1500, durationMs: 3200 }, { task: 'job-name' });
# Node.js
-weight: 500;">npm -weight: 500;">install @notilens/notilens # Python
-weight: 500;">pip -weight: 500;">install notilens # PHP
composer require notilens/notilens # Go
go get github.com/notilens/sdk-go # Rust
cargo add notilens # Ruby
gem -weight: 500;">install notilens
# Node.js
-weight: 500;">npm -weight: 500;">install @notilens/notilens # Python
-weight: 500;">pip -weight: 500;">install notilens # PHP
composer require notilens/notilens # Go
go get github.com/notilens/sdk-go # Rust
cargo add notilens # Ruby
gem -weight: 500;">install notilens
# Node.js
-weight: 500;">npm -weight: 500;">install @notilens/notilens # Python
-weight: 500;">pip -weight: 500;">install notilens # PHP
composer require notilens/notilens # Go
go get github.com/notilens/sdk-go # Rust
cargo add notilens # Ruby
gem -weight: 500;">install notilens - Are users actually signing up?
- Are payments completing — not just initiating?
- Are cron jobs processing records — not just running?
- Are AI agents producing output — not just executing? - Stripe sent the webhook ✓ but your backend never confirmed processing ✗ → broken flow alert
- Both signals arrived but volume dropped below normal baseline → silence alert
- Sudden spike in webhook volume → anomaly alert - Go to your Shopify Admin → Settings → Notifications
- Scroll to Webhooks → click Create webhook
- Select event: Order creation and Order payment
- Paste your NotiLens Shopify webhook URL
- Set format to JSON → Save
NotiLens watches incoming order volume against your baseline. If orders go abnormally quiet for your time of day — silence alert fires. No manual threshold needed. - No new users have signed up in 6 hours
- No new orders have come in since midnight
- A background job ran but processed zero records
- An API is responding but returning empty results - Server up/down — server downtime alerts
- Server silence — server silence monitoring for when your server stops reporting entirely
- API error rate spikes — API error rate monitoring - recordsProcessed consistently 0 — job ran but did nothing
- durationMs spikes above normal baseline — job is taking significantly longer than usual, often the first sign of a database or dependency issue before it becomes an outage - Billing sync
- Email delivery
- Data cleanup / reporting - Stripe webhook tracking
- Payment failure alerts
- Shopify order silence (if applicable) - Signup silence alert
- Server up/down
- One critical cron job heartbeat - API error rate
- GitHub CI/CD failures
- Second cron job - Agent monitoring
- Zapier/n8n/Make workflow monitoring