### Starting a Tunnelmole Tunnel Source: https://queuebear.com/api/index Demonstrates how to start a Tunnelmole tunnel to forward traffic from a public URL to a local development server. This is essential for QueueBear to reach your local endpoints during development. ```bash tmole 3000 # Output: https://xxxx.tunnelmole.com is forwarding to localhost:3000 ``` -------------------------------- ### Complete QueueBear Workflow Example with Context Methods Source: https://queuebear.com/api/index A full example of a QueueBear workflow defined using TypeScript's 'serve' function. It demonstrates sequential execution of steps including sending emails, sleeping, and running cached operations. ```typescript // app/api/workflows/onboarding/route.ts import { serve } from "queuebear"; interface OnboardingInput { userId: string; email: string; } export const POST = serve( async (context) => { const { userId, email } = context.input; // Step 1: Send welcome email (cached if already done) await context.run("send-welcome", async () => { await sendEmail(email, "welcome"); }); // Step 2: Wait 3 days await context.sleep("wait-3-days", 60 * 60 * 24 * 3); // Step 3: Send tips email await context.run("send-tips", async () => { await sendEmail(email, "tips"); }); return { completed: true }; }, { signingSecret: process.env.QUEUEBEAR_SIGNING_SECRET, } ); ``` -------------------------------- ### Tunnelmole Installation via npm Source: https://queuebear.com/api/.html Installs the Tunnelmole command-line tool globally using npm, which is an alternative method for installation on any platform that supports Node.js version 16 or higher. ```bash npm install -g tunnelmole ``` -------------------------------- ### Install QueueBear TypeScript SDK Source: https://queuebear.com/api/index Install the QueueBear TypeScript SDK using npm. This is the first step to integrating QueueBear into your Node.js or TypeScript project. ```bash npm install queuebear ``` -------------------------------- ### Tunnelmole Installation for Local Development Source: https://queuebear.com/api/index Provides commands for installing Tunnelmole, a tool used to expose local development servers to the internet. This is crucial for testing QueueBear webhooks and workflows locally. ```bash curl -O https://install.tunnelmole.com/t357g/install && sudo bash install ``` ```bash npm install -g tunnelmole ``` -------------------------------- ### Framework Integration (Express) Source: https://queuebear.com/api/.html Example of integrating the QueueBear `serve()` function into an Express.js application. ```APIDOC #### Express ```javascript import express from "express"; import { serve } from "queuebear"; const app = express(); app.use(express.json()); const handler = serve(async (context) => { await context.run("step-1", async () => { /* ... */ }); return { success: true }; }); app.post("/api/workflows/my-workflow", async (req, res) => { const response = await handler( new Request(req.url, { method: "POST", headers: req.headers as HeadersInit, body: JSON.stringify(req.body), }) ); res.status(response.status).json(await response.json()); }); ``` ``` -------------------------------- ### Tunnelmole Installation Script Source: https://queuebear.com/api/.html Provides shell commands for installing Tunnelmole, a tool used to expose local development servers to the internet, enabling QueueBear to reach your local webhook endpoints during development. ```shell curl -O https://install.tunnelmole.com/t357g/install && sudo bash install ``` -------------------------------- ### Framework Integration (Next.js) Source: https://queuebear.com/api/.html Example of integrating the QueueBear `serve()` function into a Next.js application using the App Router. ```APIDOC ### Framework Integration #### Next.js (App Router) ```typescript // app/api/workflows/my-workflow/route.ts import { serve } from "queuebear"; export const POST = serve(async (context) => { await context.run("step-1", async () => { /* ... */ }); return { success: true }; }); ``` ``` -------------------------------- ### Local Development with Tunnelmole Source: https://queuebear.com/api/index Guide on using Tunnelmole to expose local development servers to QueueBear's services, enabling testing of webhooks and workflow triggers. ```APIDOC ## Local Development ### Overview When developing locally, your webhook endpoints run on `localhost`, which is not directly accessible by QueueBear's servers. Tunnelmole is a free tool that creates a secure public URL for your local development environment, allowing QueueBear to send requests to it. ### Installing Tunnelmole **For Linux, macOS, and Windows WSL:** ```bash curl -O https://install.tunnelmole.com/t357g/install && sudo bash install ``` **For Node.js (all platforms, requires Node 16+):** ```bash npm install -g tunnelmole ``` ### Starting a Tunnel Once installed, start a tunnel to your local server's port (e.g., 3000): ```bash tmole 3000 ``` **Output:** `https://xxxx.tunnelmole.com is forwarding to localhost:3000` Copy the provided `https://xxxx.tunnelmole.com` URL. ### Using the Tunnel URL Replace `localhost` URLs with your Tunnelmole URL when interacting with QueueBear services locally: **For publishing messages:** ```javascript await qb.messages.publish("https://xxxx.tunnelmole.com/api/webhooks", { event: "user.created", userId: "123" }); ``` **For triggering workflows:** ```javascript await qb.workflows.trigger( "onboarding", "https://xxxx.tunnelmole.com/api/workflows/onboarding", { userId: "123" } ); ``` ### Tips for Local Testing * **Environment Variables:** Store your tunnel URL in a `.env` file for easy switching between local and production environments. * **Public URLs:** Ensure that any `callbackUrl` or `failureCallbackUrl` you use in your requests also point to publicly accessible URLs (like your Tunnelmole URL) for local testing. * **Dynamic URLs:** Be aware that Tunnelmole URLs change each time the service restarts. Update your configurations accordingly. ``` -------------------------------- ### Next.js App Router Workflow Integration Source: https://queuebear.com/api/index Example of integrating QueueBear workflows within a Next.js App Router project. It demonstrates how to define a POST handler for a workflow using the `serve()` function. ```typescript // app/api/workflows/my-workflow/route.ts import { serve } from "queuebear"; export const POST = serve(async (context) => { await context.run("step-1", async () => { /* ... */ }); return { success: true }; }); ``` -------------------------------- ### POST /v1/projects/:projectId/workflows/{workflowId}/trigger Source: https://queuebear.com/api/index Starts a new run of a specified workflow. You can provide input data, metadata, an idempotency key, and a maximum duration for the workflow. ```APIDOC ## POST /v1/projects/:projectId/workflows/{workflowId}/trigger ### Description Start a new workflow run. ### Method POST ### Endpoint `/v1/projects/:projectId/workflows/{workflowId}/trigger` ### Parameters #### Path Parameters - **projectId** (string) - Required - The ID of the project. - **workflowId** (string) - Required - The ID of the workflow to trigger. #### Request Body - **workflowUrl** (string) - Required - The URL of the workflow definition. - **input** (object) - Optional - Input data for the workflow run. - **metadata** (object) - Optional - Metadata associated with the workflow run. - **idempotencyKey** (string) - Optional - A key to ensure the request is processed only once. - **maxDuration** (number) - Optional - The maximum duration in seconds for the workflow run. ### Request Example ```json { "workflowUrl": "https://your-app.com/api/workflows/onboarding", "input": { "userId": "123", "email": "user@example.com" }, "metadata": { "source": "signup" }, "idempotencyKey": "onboarding-user-123", "maxDuration": 604800 } ``` ### Response (Success response details not provided in the input text.) ``` -------------------------------- ### Next.js App Router Workflow Integration Source: https://queuebear.com/api/.html Example of integrating QueueBear's `serve` function within a Next.js App Router API route. This demonstrates how to set up a workflow endpoint that handles incoming requests and executes defined steps. ```javascript //app/api/workflows/my-workflow/route.ts import { serve } from "queuebear"; export const POST = serve(async (context) => { await context.run("step-1", async () => { /* ... */ }); return { success: true }; }); ``` -------------------------------- ### GET /v1/projects/:projectId/schedules/{scheduleId} Source: https://queuebear.com/api/index Fetches the detailed information for a specific schedule identified by its ID. ```APIDOC ## GET /v1/projects/:projectId/schedules/{scheduleId} ### Description Get details of a specific schedule. ### Method GET ### Endpoint `/v1/projects/:projectId/schedules/{scheduleId}` ### Parameters #### Path Parameters - **projectId** (string) - Required - The ID of the project. - **scheduleId** (string) - Required - The ID of the schedule. ### Request Example (No request body for GET requests.) ### Response #### Success Response (200) - **scheduleId** (string) - The unique identifier for the schedule. - **destination** (string) - The URL where the job is sent. - **cron** (string) - The cron expression defining the schedule. - **timezone** (string) - The timezone associated with the cron expression. - **method** (string) - The HTTP method used for the job. - **retries** (number) - The number of retries configured for the job. - **isActive** (boolean) - Indicates if the schedule is currently active. - **isPaused** (boolean) - Indicates if the schedule is currently paused. - **lastExecutedAt** (string) - Timestamp of the last execution. - **nextExecutionAt** (string) - Timestamp of the next scheduled execution. - **executionCount** (number) - Total number of times the job has been executed. - **failureCount** (number) - Number of times the job has failed. ### Response Example ```json { "scheduleId": "sched_a1b2c3d4e5f6...", "destination": "https://api.example.com/cron-job", "cron": "0 9 * * *", "timezone": "America/New_York", "method": "POST", "retries": 3, "isActive": true, "isPaused": false, "lastExecutedAt": "2024-01-15T14:00:00Z", "nextExecutionAt": "2024-01-16T14:00:00Z", "executionCount": 42, "failureCount": 2 } ``` ``` -------------------------------- ### GET /v1/projects/:projectId/dlq/{dlqId} Source: https://queuebear.com/api/index Retrieves detailed information about a specific entry in the Dead Letter Queue. ```APIDOC ## GET /v1/projects/:projectId/dlq/{dlqId} ### Description Get details of a specific DLQ entry. ### Method GET ### Endpoint `/v1/projects/:projectId/dlq/{dlqId}` ### Parameters #### Path Parameters - **projectId** (string) - Required - The ID of the project. - **dlqId** (string) - Required - The ID of the DLQ entry. ### Request Example (No request body for GET requests.) ### Response #### Success Response (200) - **id** (string) - The unique identifier for the DLQ entry. - **originalMessageId** (string) - The ID of the original message. - **destination** (string) - The destination URL. - **method** (string) - The HTTP method of the original request. - **body** (string) - The body of the original message (as a JSON string). - **failureReason** (string) - The reason for the failure. - **lastStatusCode** (integer) - The HTTP status code of the last failed attempt. - **totalAttempts** (number) - The total number of attempts made. - **recoveredAt** (string|null) - Timestamp when the message was recovered, if applicable. - **recoveryMessageId** (string|null) - The ID of the new message created upon recovery. ### Response Example ```json { "id": "uuid...", "originalMessageId": "msg_a1b2c3d4e5f6...", "destination": "https://api.example.com/webhook", "method": "POST", "body": "{\"event\": \"user.created\"}", "failureReason": "Connection timeout", "lastStatusCode": 504, "totalAttempts": 4, "recoveredAt": null, "recoveryMessageId": null } ``` ``` -------------------------------- ### GET /v1/projects/:projectId/schedules Source: https://queuebear.com/api/index Retrieves a list of all schedules associated with a specific project. Supports pagination with limit and offset parameters. ```APIDOC ## GET /v1/projects/:projectId/schedules ### Description List all schedules for the project. ### Method GET ### Endpoint `/v1/projects/:projectId/schedules` ### Parameters #### Path Parameters - **projectId** (string) - Required - The ID of the project. #### Query Parameters - **limit** (integer) - Optional - Maximum number of results to return (1-100, default: 50). - **offset** (integer) - Optional - Pagination offset. ### Request Example (No request body for GET requests.) ### Response (Success response details not provided in the input text. Expected to return a list of schedules.) ``` -------------------------------- ### GET /v1/projects/:projectId/workflows/runs/:runId Source: https://queuebear.com/api/index Retrieves detailed information about a specific workflow run, including all its execution steps. ```APIDOC ## GET /v1/projects/:projectId/workflows/runs/:runId ### Description Retrieves detailed information about a specific workflow run, including all its execution steps. ### Method GET ### Endpoint `/v1/projects/:projectId/workflows/runs/:runId` ### Parameters #### Path Parameters - **runId** (string) - Required - The ID of the workflow run to retrieve. ### Response #### Success Response (200) - **runId** (string) - The ID of the workflow run. - **status** (string) - The current status of the workflow run (e.g., pending, running, completed, failed). - **steps** (array) - An array of step details for the workflow run. - **stepId** (string) - The ID of the step. - **name** (string) - The name of the step. - **status** (string) - The status of the step. - **startTime** (string) - Timestamp when the step started. - **endTime** (string) - Timestamp when the step ended. #### Response Example ```json { "runId": "run_a1b2c3d4e5f6...", "status": "completed", "steps": [ { "stepId": "step_xyz789", "name": "Fetch User Data", "status": "completed", "startTime": "2023-10-27T10:01:00Z", "endTime": "2023-10-27T10:02:00Z" } ] } ``` ### Workflow Run Status Values - **pending**: Queued, not yet started - **running**: Currently executing - **sleeping**: Paused in a sleep step - **waiting_event**: Waiting for external event - **completed**: Finished successfully - **failed**: Failed - **cancelled**: Manually cancelled - **timed_out**: Exceeded max duration ``` -------------------------------- ### Trigger Workflow (Node.js) Source: https://queuebear.com/api/index Starts a new run of a specified workflow. This SDK method requires a workflow URL and can accept input data, metadata, an idempotency key, and a maximum duration for the workflow run. ```javascript await qb.workflows.trigger({ workflowUrl: "https://your-app.com/api/workflows/onboarding", input: { "userId": "123", "email": "user@example.com" }, metadata: { "source": "signup" }, idempotencyKey: "onboarding-user-123", maxDuration: 604800 }); ``` -------------------------------- ### Trigger a Workflow (JavaScript) Source: https://queuebear.com/api/.html Starts a new execution of a specified workflow. Requires the workflow URL and can include input data, metadata, an idempotency key, and a maximum duration. ```javascript { "workflowUrl": "https://your-app.com/api/workflows/onboarding", "input": { "userId": "123", "email": "user@example.com" }, "metadata": { "source": "signup" }, "idempotencyKey": "onboarding-user-123", "maxDuration": 604800 } ``` -------------------------------- ### GET /v1/projects/:projectId/workflows/:workflowId/runs Source: https://queuebear.com/api/index Lists all runs for a specific workflow. This endpoint supports filtering by status and pagination using limit and offset parameters. ```APIDOC ## GET /v1/projects/:projectId/workflows/:workflowId/runs ### Description Lists all runs for a specific workflow. This endpoint supports filtering by status and pagination using limit and offset parameters. ### Method GET ### Endpoint `/v1/projects/:projectId/workflows/:workflowId/runs` ### Parameters #### Query Parameters - **status** (string) - Optional - Filter by status (e.g., pending, running, completed, failed) - **limit** (integer) - Optional - Maximum number of results to return (1-100, default: 50) - **offset** (integer) - Optional - Pagination offset ### Response #### Success Response (200) - **runs** (array) - A list of workflow run objects. - **runId** (string) - The ID of the workflow run. - **status** (string) - The current status of the workflow run. - **createdAt** (string) - Timestamp when the run was created. - **completedAt** (string) - Timestamp when the run was completed. #### Response Example ```json { "runs": [ { "runId": "run_abc123", "status": "completed", "createdAt": "2023-10-27T10:00:00Z", "completedAt": "2023-10-27T10:05:00Z" } ] } ``` ``` -------------------------------- ### GET /v1/projects/:projectId/dlq Source: https://queuebear.com/api/index Retrieves a list of all entries in the Dead Letter Queue for a given project. These are messages that failed all retry attempts. ```APIDOC ## GET /v1/projects/:projectId/dlq ### Description List all DLQ entries. ### Method GET ### Endpoint `/v1/projects/:projectId/dlq` ### Parameters #### Path Parameters - **projectId** (string) - Required - The ID of the project. ### Request Example (No request body for GET requests.) ### Response #### Success Response (200) - **entries** (array) - An array of DLQ entry objects. - **id** (string) - The unique identifier for the DLQ entry. - **originalMessageId** (string) - The ID of the original message that failed. - **destination** (string) - The intended destination of the failed message. - **failureReason** (string) - The reason for the message failure. - **totalAttempts** (number) - The total number of attempts made for this message. ### Response Example ```json { "entries": [ { "id": "uuid...", "originalMessageId": "msg_a1b2c3d4e5f6...", "destination": "https://api.example.com/webhook", "failureReason": "Connection timeout", "totalAttempts": 4 } ] } ``` ``` -------------------------------- ### Serve Workflow Source: https://queuebear.com/api/.html Creates an HTTP handler for your workflow using the `serve()` function. This handler receives requests from QueueBear, executes your workflow logic, and manages step caching. ```APIDOC ## Serve Function ### Description The `serve()` function creates an HTTP handler for your workflow. It receives requests from QueueBear, executes your workflow code, and manages step caching automatically. ### Usage ```javascript import { serve } from "queuebear"; export const POST = serve(async (context) => { // Your workflow logic here return result; }, options); ``` ### Options **Option** | **Type** | **Description** ---|---|--- `signingSecret` | `string` | Secret to verify requests come from QueueBear ``` -------------------------------- ### QueueBear Context Methods Source: https://queuebear.com/api/.html Details on the available context methods within QueueBear serve() handlers for managing workflow steps. ```APIDOC ## Context Methods Available in `serve()` handlers: ### `context.run(stepName, fn, options?)` Execute a step with automatic caching. The result of `fn` is cached based on `stepName`. #### Parameters - **stepName** (string) - A unique name for the step to enable caching. - **fn** (function) - An asynchronous function representing the step's logic. - **options** (object) - Optional configuration for the step. #### Example ```javascript const result = await context.run("fetch-user", async () => { return await db.users.findById(userId); }); ``` ### `context.sleep(stepName, seconds)` Pause workflow execution for a specified duration. #### Parameters - **stepName** (string) - A unique name for the sleep step. - **seconds** (number) - The duration in seconds to pause. #### Example ```javascript await context.sleep("wait-1-hour", 3600); ``` ### `context.sleepUntil(stepName, date)` Pause workflow execution until a specific date and time. #### Parameters - **stepName** (string) - A unique name for the sleep step. - **date** (Date) - The specific date and time to resume execution. #### Example ```javascript await context.sleepUntil("wait-until-tomorrow", new Date("2024-01-15T09:00:00Z")); ``` ### `context.call(stepName, config)` Make an HTTP call as a cached step. Handles request details and response caching. #### Parameters - **stepName** (string) - A unique name for the HTTP call step. - **config** (object) - Configuration for the HTTP call: - **url** (string) - The URL to make the request to. - **method** (string) - The HTTP method (e.g., 'GET', 'POST'). - **headers** (object) - Optional request headers. - **body** (any) - Optional request body. #### Example ```javascript const data = await context.call("fetch-api", { url: "https://api.example.com/data", method: "POST", headers: { Authorization: "Bearer xxx" }, body: { key: "value" }, }); ``` ### `context.waitForEvent(stepName, eventName, options?)` Wait for an external event to be published. The workflow pauses until the event occurs or a timeout is reached. #### Parameters - **stepName** (string) - A unique name for the event waiting step. - **eventName** (string) - The name of the event to wait for. - **options** (object) - Optional configuration: - **eventKey** (string) - A key to correlate events. - **timeoutSeconds** (number) - Maximum time in seconds to wait for the event. #### Example ```javascript const payload = await context.waitForEvent("wait-approval", "order.approved", { eventKey: "order-123", timeoutSeconds: 86400, // 1 day }); ``` ### `context.notify(eventName, payload?)` Send a fire-and-forget event. This is used for signaling or triggering other systems without blocking workflow execution. #### Parameters - **eventName** (string) - The name of the event to publish. - **payload** (object) - Optional data to include with the event. #### Example ```javascript await context.notify("user.onboarded", { userId: "123" }); ``` ### `context.parallel(steps)` Execute multiple steps concurrently. Returns an array of results in the same order as the input steps. #### Parameters - **steps** (array) - An array of step objects, each with a `name` and an `fn` (async function). #### Example ```javascript const [user, orders, preferences] = await context.parallel([ { name: "fetch-user", fn: () => fetchUser(userId) }, { name: "fetch-orders", fn: () => fetchOrders(userId) }, { name: "fetch-preferences", fn: () => fetchPreferences(userId) }, ]); ``` ### `context.getCompletedSteps()` Retrieve a list of all steps that have successfully completed in the current workflow execution. Useful for debugging. #### Example ```javascript const steps = await context.getCompletedSteps(); console.log(`Completed ${steps.length} steps`); ``` ``` -------------------------------- ### Context Methods in `serve()` Handlers Source: https://queuebear.com/api/index Details on the available context methods within QueueBear workflow handlers for managing step execution, pausing, external calls, events, and parallel processing. ```APIDOC ## Context Methods Available in `serve()` handlers for managing workflow steps: ### `context.run(stepName, fn, options?)` **Description:** Executes a step with automatic caching. If the step has been run before with the same `stepName`, the cached result is returned. **Parameters:** - **stepName** (string) - Required - A unique name for the step. - **fn** (function) - Required - The asynchronous function to execute for the step. - **options** (object) - Optional - Configuration options for the step. **Example:** ```javascript const result = await context.run("fetch-user", async () => { return await db.users.findById(userId); }); ``` ### `context.sleep(stepName, seconds)` **Description:** Pauses the workflow execution for a specified duration. **Parameters:** - **stepName** (string) - Required - A unique name for the sleep step. - **seconds** (number) - Required - The number of seconds to pause. **Example:** ```javascript await context.sleep("wait-1-hour", 3600); ``` ### `context.sleepUntil(stepName, date)` **Description:** Pauses the workflow execution until a specific date and time. **Parameters:** - **stepName** (string) - Required - A unique name for the sleep step. - **date** (Date) - Required - The target date and time to resume execution. **Example:** ```javascript await context.sleepUntil("wait-until-tomorrow", new Date("2024-01-15")); ``` ### `context.call(stepName, config)` **Description:** Makes an HTTP call as a cached step. Useful for fetching data from external APIs. **Parameters:** - **stepName** (string) - Required - A unique name for the call step. - **config** (object) - Required - Configuration for the HTTP call. - **url** (string) - Required - The URL to call. - **method** (string) - Required - The HTTP method (e.g., 'GET', 'POST'). - **headers** (object) - Optional - Request headers. - **body** (object) - Optional - Request body. **Example:** ```javascript const data = await context.call("fetch-api", { url: "https://api.example.com/data", method: "POST", headers: { Authorization: "Bearer xxx" }, body: { key: "value" }, }); ``` ### `context.waitForEvent(stepName, eventName, options?)` **Description:** Waits for an external event to be published to QueueBear. The workflow pauses until the event is received or a timeout occurs. **Parameters:** - **stepName** (string) - Required - A unique name for the wait event step. - **eventName** (string) - Required - The name of the event to wait for. - **options** (object) - Optional - Configuration options. - **eventKey** (string) - Optional - A specific key to match for the event. - **timeoutSeconds** (number) - Optional - The maximum time to wait in seconds. **Example:** ```javascript const payload = await context.waitForEvent("wait-approval", "order.approved", { eventKey: "order-123", timeoutSeconds: 86400, // 1 day }); ``` ### `context.notify(eventName, payload?)` **Description:** Sends a fire-and-forget event notification. This method does not wait for a response. **Parameters:** - **eventName** (string) - Required - The name of the event to notify. - **payload** (object) - Optional - Data to send with the event. **Example:** ```javascript await context.notify("user.onboarded", { userId: "123" }); ``` ### `context.parallel(steps)` **Description:** Executes multiple steps concurrently. Returns an array of results in the same order as the input steps. **Parameters:** - **steps** (array) - Required - An array of step objects, each with a `name` and a `fn`. - **name** (string) - Required - The name of the step. - **fn** (function) - Required - The asynchronous function to execute. **Example:** ```javascript const [user, orders, preferences] = await context.parallel([ { name: "fetch-user", fn: () => fetchUser(userId) }, { name: "fetch-orders", fn: () => fetchOrders(userId) }, { name: "fetch-preferences", fn: () => fetchPreferences(userId) }, ]); ``` ### `context.getCompletedSteps()` **Description:** Retrieves a list of all steps that have successfully completed during the current workflow execution. Useful for debugging. **Example:** ```javascript const steps = await context.getCompletedSteps(); console.log(`Completed ${steps.length} steps`); ``` ``` -------------------------------- ### Workflows SDK Overview Source: https://queuebear.com/api/index Provides an overview of the QueueBear Workflows SDK for building durable and fault-tolerant workflows. ```APIDOC ## Workflows SDK Build durable, fault-tolerant workflows with automatic step caching. Workflows consist of two parts: a workflow endpoint created with `serve()`, and a client that uses `qb.workflows` to trigger and manage runs. ### `serve()` Function The `serve()` function creates an HTTP handler for your workflow. It receives requests from QueueBear, executes your workflow code, and manages step caching automatically. ```javascript import { serve } from "queuebear"; export const POST = serve(async (context) => { // Your workflow logic here return result; }, options); ``` #### Options - **signingSecret** (`string`) - Secret to verify requests come from QueueBear. ### Framework Integration #### Next.js (App Router) ```javascript // app/api/workflows/my-workflow/route.ts import { serve } from "queuebear"; export const POST = serve(async (context) => { await context.run("step-1", async () => { /* ... */ }); return { success: true }; }); ``` #### Express ```javascript import express from "express"; import { serve } from "queuebear"; const app = express(); app.use(express.json()); const handler = serve(async (context) => { await context.run("step-1", async () => { /* ... */ }); return { success: true }; }); app.post("/api/workflows/my-workflow", async (req, res) => { const response = await handler( new Request(req.url, { method: "POST", headers: req.headers as HeadersInit, body: JSON.stringify(req.body), }) ); res.status(response.status).json(await response.json()); }); ``` ``` -------------------------------- ### Get Message Details with QueueBear SDK Source: https://queuebear.com/api/index Retrieve detailed information about a specific message, including its status and delivery history, using the QueueBear TypeScript SDK. ```typescript const message = await qb.messages.get(messageId); console.log(message.status); // "pending" | "completed" | "failed" console.log(message.deliveryLogs); // Delivery attempt history ``` -------------------------------- ### Initialize QueueBear TypeScript SDK Source: https://queuebear.com/api/index Initialize the QueueBear SDK client with your API key and project ID. This client instance will be used to interact with QueueBear API endpoints. ```typescript import { QueueBear } from "queuebear"; const qb = new QueueBear({ apiKey: "qb_live_xxx", projectId: "proj_xxx", }); ``` -------------------------------- ### Express Workflow Integration Source: https://queuebear.com/api/.html Shows how to integrate QueueBear's `serve` function with an Express.js application. This involves creating an Express route that acts as a proxy, forwarding requests to the QueueBear handler and returning the response. ```javascript import express from "express"; import { serve } from "queuebear"; const app = express(); app.use(express.json()); const handler = serve(async (context) => { await context.run("step-1", async () => { /* ... */ }); return { success: true }; }); app.post("/api/workflows/my-workflow", async (req, res) => { const response = await handler( new Request(req.url, { method: "POST", headers: req.headers as HeadersInit, body: JSON.stringify(req.body), }) ); res.status(response.status).json(await response.json()); }); ``` -------------------------------- ### Workflows API Source: https://queuebear.com/api/.html API for triggering and managing durable workflows. ```APIDOC ## Workflows API ### Description Trigger and manage durable workflows. ### Endpoints (Specific endpoints for Workflows API are not detailed in the provided text, but the SDK has a `qb.workflows` interface.) ``` -------------------------------- ### Create Workflow Handler with serve() Source: https://queuebear.com/api/index Defines an HTTP handler for a workflow using the `serve()` function from the QueueBear SDK. This function manages workflow execution, step caching, and input/output typing. ```typescript import { serve } from "queuebear"; // Define input and output types for your workflow interface InputType { userId: string; } interface ResultType { success: boolean; } export const POST = serve(async (context) => { // Your workflow logic here const result = { success: true }; await context.run("process-data", async () => { // Simulate work await new Promise(resolve => setTimeout(resolve, 100)); }); return result; }, { signingSecret: "your-signing-secret", // Replace with your actual secret }); ``` -------------------------------- ### Serve Workflow Logic Source: https://queuebear.com/api/.html Defines an HTTP handler for a workflow using the `serve` function. This function takes your workflow logic, which can be asynchronous and utilize context for steps and event waiting. It handles request verification and step caching automatically. ```javascript import { serve } from "queuebear"; export const POST = serve(async (context) => { // Your workflow logic here return result; }, options); ``` -------------------------------- ### Trigger Workflow and Get Run ID Source: https://queuebear.com/api/index Triggers a workflow using the QueueBear SDK, passing input data and optional configurations like idempotency keys and max duration. It returns the unique run ID for the triggered workflow. ```javascript const { runId } = await qb.workflows.trigger( "user-onboarding", "https://your-app.com/api/workflows/onboarding", { userId: "123", email: "user@example.com" }, { idempotencyKey: "onboarding-user-123", maxDuration: 60 * 60 * 24 * 7, // 7 day timeout } ); console.log(runId); ``` -------------------------------- ### Get Workflow Run Status Source: https://queuebear.com/api/.html Retrieves the current status of a workflow run using its run ID. This function provides the status of the workflow and details about each step within the run. It's useful for monitoring the progress of asynchronous workflows. ```javascript const status = await qb.workflows.getStatus(runId); console.log(status.status); // "running" | "sleeping" | "completed" console.log(status.steps); // Array of step details ``` -------------------------------- ### List Schedules (Node.js) Source: https://queuebear.com/api/index Retrieves a list of all schedules for the current project. This SDK method can accept optional query parameters for pagination like 'limit' and 'offset'. ```javascript const { schedules } = await qb.schedules.list(); ``` -------------------------------- ### Get Workflow Run Status and Steps Source: https://queuebear.com/api/index Retrieves the current status and detailed step information for a specific workflow run using its unique run ID. The status indicates the progress of the workflow, and steps provide granular execution details. ```javascript const status = await qb.workflows.getStatus(runId); console.log(status.status); console.log(status.steps); ``` -------------------------------- ### Hono Integration with QueueBear Serve Source: https://queuebear.com/api/index Integrates QueueBear's 'serve' functionality with a Hono application to handle workflow execution. It sets up a POST endpoint for triggering workflows and utilizes context methods for step management. ```typescript import { Hono } from "hono"; import { serve } from "queuebear"; const app = new Hono(); const handler = serve(async (context) => { await context.run("step-1", async () => { /* ... */ }); return { success: true }; }); app.post("/api/workflows/my-workflow", async (c) => { return await handler(c.req.raw); }); ``` -------------------------------- ### Schedules API Source: https://queuebear.com/api/.html API for creating and managing cron-based recurring jobs. ```APIDOC ## Schedules API ### Description Create and manage cron-based recurring jobs. ### Endpoints (Specific endpoints for Schedules API are not detailed in the provided text, but the SDK has a `qb.schedules` interface.) ``` -------------------------------- ### Get DLQ Entry Details (Node.js) Source: https://queuebear.com/api/index Fetches detailed information about a specific entry in the Dead Letter Queue (DLQ) using its DLQ ID. The SDK returns a DLQ entry object containing original message details and failure information. ```javascript const entry = await qb.dlq.get(dlqId); console.log(entry.body); // Original message body console.log(entry.totalAttempts); // Number of failed attempts ``` -------------------------------- ### QueueBear Context Methods: run, sleep, sleepUntil, call, waitForEvent, notify, parallel, getCompletedSteps Source: https://queuebear.com/api/index Demonstrates the usage of various QueueBear context methods within a 'serve' handler. These methods facilitate step execution with caching, pausing workflows, making HTTP calls, waiting for events, sending notifications, parallel execution, and retrieving completed steps. ```typescript const result = await context.run("fetch-user", async () => { return await db.users.findById(userId); }); ``` ```typescript await context.sleep("wait-1-hour", 3600); ``` ```typescript await context.sleepUntil("wait-until-tomorrow", new Date("2024-01-15")); ``` ```typescript const data = await context.call("fetch-api", { url: "https://api.example.com/data", method: "POST", headers: { Authorization: "Bearer xxx" }, body: { key: "value" }, }); ``` ```typescript const payload = await context.waitForEvent("wait-approval", "order.approved", { eventKey: "order-123", timeoutSeconds: 86400, // 1 day }); ``` ```typescript await context.notify("user.onboarded", { userId: "123" }); ``` ```typescript const [user, orders, preferences] = await context.parallel([ { name: "fetch-user", fn: () => fetchUser(userId) }, { name: "fetch-orders", fn: () => fetchOrders(userId) }, { name: "fetch-preferences", fn: () => fetchPreferences(userId) }, ]); ``` ```typescript const steps = await context.getCompletedSteps(); console.log(`Completed ${steps.length} steps`); ``` -------------------------------- ### Trigger Workflow and Get Run ID Source: https://queuebear.com/api/.html Triggers a workflow with specified parameters and returns the run ID. It accepts a workflow name, URL, input data, and optional metadata like idempotency key and max duration. The response contains the unique run ID for the initiated workflow. ```javascript const { runId } = await qb.workflows.trigger( "user-onboarding", "https://your-app.com/api/workflows/onboarding", { userId: "123", email: "user@example.com" }, { idempotencyKey: "onboarding-user-123", maxDuration: 60 * 60 * 24 * 7, // 7 day timeout } ); ``` -------------------------------- ### Publish a Message with cURL Source: https://queuebear.com/api/index Publish a message using cURL to the QueueBear API. This demonstrates how to send a POST request with a JSON payload and appropriate authentication headers. ```bash curl -X POST "https://api.queuebear.com/v1/projects/proj_xxx/publish" \ -H "Authorization: Bearer qb_live_xxxxx" \ -H "Content-Type: application/json" \ -d '{ "destination": "https://api.example.com/webhook", "body": {"event": "user.created", "userId": "123"}, "delay": "30s", "retries": 5, "callbackUrl": "https://api.example.com/callback", "headers": {"X-Custom-Header": "value"} }' ``` -------------------------------- ### Using Tunnelmole URL with QueueBear SDK Source: https://queuebear.com/api/index Illustrates how to use the public URL generated by Tunnelmole when interacting with QueueBear's SDK for publishing messages and triggering workflows during local development. ```javascript // Use tunnelmole URL instead of localhost await qb.messages.publish("https://xxxx.tunnelmole.com/api/webhooks", { event: "user.created", userId: "123" }); // Works for workflows too await qb.workflows.trigger( "onboarding", "https://xxxx.tunnelmole.com/api/workflows/onboarding", { userId: "123" } ); ``` -------------------------------- ### Workflows API Source: https://queuebear.com/api/.html Trigger and manage durable, fault-tolerant workflows with automatic step caching and resumption. ```APIDOC ## POST /v1/projects/:projectId/workflows/{workflowId}/trigger ### Description Start a new workflow run. ### Method POST ### Endpoint `/v1/projects/:projectId/workflows/{workflowId}/trigger` ### Parameters #### Path Parameters - **projectId** (string) - Required - The ID of the project. - **workflowId** (string) - Required - The ID of the workflow to trigger. #### Request Body - **workflowUrl** (string) - Required - The URL of the workflow definition. - **input** (object) - Optional - The input data for the workflow. - **metadata** (object) - Optional - Metadata to associate with the workflow run. - **idempotencyKey** (string) - Optional - A unique key to prevent duplicate runs. - **maxDuration** (integer) - Optional - The maximum duration for the workflow in seconds (e.g., 604800 for 1 week). ### Request Example ```json { "workflowUrl": "https://your-app.com/api/workflows/onboarding", "input": { "userId": "123", "email": "user@example.com" }, "metadata": { "source": "signup" }, "idempotencyKey": "onboarding-user-123", "maxDuration": 604800 } ``` ### Response (Success response details not provided in the source text) ``` -------------------------------- ### Express.js Workflow Integration Source: https://queuebear.com/api/index Shows how to integrate QueueBear workflows into an Express.js application. It involves setting up an Express route to handle incoming POST requests and forward them to the QueueBear `serve()` handler. ```javascript import express from "express"; import { serve } from "queuebear"; const app = express(); app.use(express.json()); const handler = serve(async (context) => { await context.run("step-1", async () => { /* ... */ }); return { success: true }; }); app.post("/api/workflows/my-workflow", async (req, res) => { const request = new Request(req.url, { method: "POST", headers: req.headers as HeadersInit, body: JSON.stringify(req.body), }); const response = await handler(request); res.status(response.status).json(await response.json()); }); const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); }); ```