Serverless examples
These examples send a notification with the JavaScript SDK from the platforms most apps already run on. Each one follows the same three rules:
- The REST API key stays in the platform’s secret store, never in code or in your app. Find it, and your app ID, in the dashboard under Settings.
- Users are targeted by
external_id, the ID your app passed toBigBrain.login. If you log users in with Supabase or Firebase Auth, use their user ID. - Each send has an
idempotency_keybuilt from the event, such as the order ID. Webhooks and triggers can run more than once, and PushGenius sends at most one notification per key, so a retry never notifies anyone twice.
Supabase Edge Functions
Notify a customer when their order ships, using a database webhook that calls an Edge Function each time a row in orders changes. Create the function:
supabase functions new order-shipped
Then replace supabase/functions/order-shipped/index.ts with:
import { BigBrain } from "npm:@pushgenius/javascript@0.1";
const bigBrain = new BigBrain({
appId: Deno.env.get("PUSHGENIUS_APP_ID")!,
apiKey: Deno.env.get("PUSHGENIUS_API_KEY")!,
});
// Called by a database webhook on UPDATE of public.orders.
// The body is { type, table, record, old_record }.
Deno.serve(async (req) => {
const { record, old_record } = await req.json();
const justShipped = record.status === "shipped" && old_record?.status !== "shipped";
if (!justShipped) return new Response("skipped");
await bigBrain.notifications.create({
headings: { en: "Your order shipped" },
contents: { en: `Order #${record.id} is on its way.` },
data: { order_id: String(record.id) },
include_aliases: { external_id: [record.user_id] },
// Webhooks can be retried; with the same key, the user still gets one notification.
idempotency_key: `order-shipped-${record.id}`,
});
return new Response("sent");
});Save your keys as secrets and deploy:
supabase secrets set PUSHGENIUS_APP_ID=YOUR_APP_ID PUSHGENIUS_API_KEY=YOUR_REST_API_KEY supabase functions deploy order-shipped
In the Supabase dashboard, open Database → Webhooks and create a webhook on the orders table for Update events. Choose Supabase Edge Functions as the type, pick order-shipped, and add the auth header with your service key. Edge Functions reject calls without a valid token, so strangers can’t trigger sends.
AWS Lambda
A handler you can invoke from your API, a queue, or Step Functions. Save it as index.mjs:
import { BigBrain } from "@pushgenius/javascript";
// Created once per Lambda container and reused across invocations.
const bigBrain = new BigBrain({
appId: process.env.PUSHGENIUS_APP_ID,
apiKey: process.env.PUSHGENIUS_API_KEY,
});
// Invoke with { "userId": "user-123", "orderId": "A-1001" }.
export const handler = async (event) => {
const { id, errors } = await bigBrain.notifications.create({
headings: { en: "Your order shipped" },
contents: { en: `Order ${event.orderId} is on its way.` },
data: { order_id: event.orderId },
include_aliases: { external_id: [event.userId] },
// Lambda retries failed async invocations; with the same key, the user gets one.
idempotency_key: `order-shipped-${event.orderId}`,
});
return { notificationId: id, errors };
};The SDK has no dependencies, so the zip is about 25 KB. Package and create the function on the Node.js 22 runtime:
npm install @pushgenius/javascript
zip -r function.zip index.mjs node_modules
aws lambda create-function --function-name order-shipped \
--runtime nodejs22.x --handler index.handler --zip-file fileb://function.zip \
--role arn:aws:iam::ACCOUNT_ID:role/YOUR_LAMBDA_ROLE --timeout 15 \
--environment "Variables={PUSHGENIUS_APP_ID=YOUR_APP_ID,PUSHGENIUS_API_KEY=YOUR_REST_API_KEY}"Raise the timeout from Lambda’s default of 3 seconds, as above, so the SDK has time to retry a slow request. Anyone who can view the function in the AWS console can read its environment variables. To keep the key out of view, store it in Secrets Manager and read it when the container starts.
Cloud Functions for Firebase
Notify the recipient of each new chat message by triggering on new Firestore documents. In functions/package.json, set "type": "module" (the SDK is an ES module) and "engines": { "node": "22" }. Then install the SDK:
cd functions && npm install @pushgenius/javascript
In functions/index.js:
import { onDocumentCreated } from "firebase-functions/v2/firestore";
import { defineSecret, defineString } from "firebase-functions/params";
import { BigBrain } from "@pushgenius/javascript";
const appId = defineString("PUSHGENIUS_APP_ID");
const apiKey = defineSecret("PUSHGENIUS_API_KEY");
// Runs for each new message in a chat and notifies the recipient.
export const notifyRecipient = onDocumentCreated(
{ document: "chats/{chatId}/messages/{messageId}", secrets: [apiKey] },
async (event) => {
const message = event.data?.data();
if (!message) return;
// Secrets are only readable while the function runs, so create the client here.
const bigBrain = new BigBrain({ appId: appId.value(), apiKey: apiKey.value() });
await bigBrain.notifications.create({
headings: { en: message.senderName },
contents: { en: message.text },
data: { chat_id: event.params.chatId },
include_aliases: { external_id: [message.recipientId] },
// event.id is the same if Firebase delivers this event twice.
idempotency_key: event.id,
});
},
);Put PUSHGENIUS_APP_ID=YOUR_APP_ID in functions/.env, then save the key as a secret and deploy:
firebase functions:secrets:set PUSHGENIUS_API_KEY firebase deploy --only functions
Secrets and requests to services outside Google need the Blaze plan. To try it in the emulator, put PUSHGENIUS_API_KEY=YOUR_REST_API_KEY in functions/.secret.local and run firebase emulators:start --only functions,firestore.
Cloudflare Workers
Send a daily summary to everyone on a cron schedule. The SDK uses only web-standard APIs, so it needs no nodejs_compat flag. Use version 0.1.1 or later. Install it in your Worker project:
npm install @pushgenius/javascript
In src/index.js:
import { BigBrain } from "@pushgenius/javascript";
export default {
// Runs on the cron schedule in wrangler.jsonc.
async scheduled(controller, env) {
const bigBrain = new BigBrain({
appId: env.PUSHGENIUS_APP_ID,
apiKey: env.PUSHGENIUS_API_KEY,
});
await bigBrain.notifications.create({
headings: { en: "Your daily summary is ready" },
contents: { en: "Tap to see what happened today." },
included_segments: ["Subscribed Users"],
// One key per scheduled time, so the same run never sends twice.
idempotency_key: `daily-summary-${controller.scheduledTime}`,
});
},
};In wrangler.jsonc, schedule it for 17:00 UTC and set the app ID:
{
"name": "daily-summary",
"main": "src/index.js",
"compatibility_date": "2026-10-01",
"triggers": { "crons": ["0 17 * * *"] },
"vars": { "PUSHGENIUS_APP_ID": "YOUR_APP_ID" }
}Save the key as a secret and deploy:
npx wrangler secret put PUSHGENIUS_API_KEY npx wrangler deploy
To try it locally, put PUSHGENIUS_API_KEY=YOUR_REST_API_KEY in .dev.vars, run npx wrangler dev --test-scheduled, and open http://localhost:8787/__scheduled.