### Install Dependencies Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/examples/order/README.md Installs project dependencies using either npm or yarn package managers. Ensure you have Node.js and a package manager installed. ```sh npm install ``` ```sh yarn ``` -------------------------------- ### Install Dependencies with npm or yarn Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/examples/granting-loans/README.md Installs the necessary project dependencies using either npm or yarn package managers. This is a prerequisite for running the example. ```sh npm install ``` ```sh yarn install ``` -------------------------------- ### Run the Example with Node.js Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/examples/granting-loans/README.md Executes the Camunda External Task Client JS example using Node.js. This command starts the client to subscribe to and process external tasks. ```sh node index.js ``` -------------------------------- ### Install camunda-external-task-client-js with npm or yarn Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/README.md This snippet shows how to install the camunda-external-task-client-js package using either npm or yarn. This is a prerequisite for using the client in your NodeJS project. ```sh npm install -s camunda-external-task-client-js ``` ```sh yarn add camunda-external-task-client-js ``` -------------------------------- ### Listen to Camunda Client Subscription and Poll Events Source: https://context7.com/camunda/camunda-external-task-client-js/llms.txt This example demonstrates how to manually listen to client events related to subscriptions and polling in the Camunda External Task Client. It shows how to log when subscribed to a topic, when polling starts, succeeds, or encounters errors. Requires 'camunda-external-task-client-js'. ```javascript import { Client, logger } from "camunda-external-task-client-js"; const client = new Client({ baseUrl: "http://localhost:8080/engine-rest", use: logger }); // Listen to client events manually client.on("subscribe", (topic, subscription) => { console.log(`Subscribed to topic: ${topic}`); }); client.on("unsubscribe", () => { console.log("Unsubscribed from topic"); }); client.on("poll:start", () => { console.log("Polling started"); }); client.on("poll:success", (tasks) => { console.log(`Fetched ${tasks.length} tasks`); }); client.on("poll:error", (error) => { console.error("Polling error:", error); }); client.on("poll:stop", () => { console.log("Polling stopped"); }); ``` -------------------------------- ### Simulate Loan Document Generation and Approval Source: https://context7.com/camunda/camunda-external-task-client-js/llms.txt This snippet demonstrates asynchronous functions for simulating loan document generation and waiting for approval. It highlights basic async operations and an example of handling termination signals for graceful shutdown of a client process. ```javascript async function generateLoanDocument(customerId, amount, approved) { // Simulate document generation return "./generated/loan-doc.pdf"; } async function waitForApproval(customerId, timeout) { // Simulate waiting for approval return { approved: true, approver: "manager@example.com", comments: "Approved" }; } // Graceful shutdown process.on("SIGTERM", () => { console.log("Shutting down worker..."); client.stop(); process.exit(0); }); ``` -------------------------------- ### Set and Get Date Variables (JavaScript) Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/docs/Variables.md Demonstrates how to set date variables using `variables.set()` with a Date object or `variables.setTyped()` with a Date object or string. It also shows how to retrieve these date variables and confirms their type. ```javascript // 'variables.set()' can be used to set a date by providing a date object variables.set("someDate", new Date()); // 'variables.setTyped()' can be used to set a date by either: // 1- providing a date object as a value: variables.setTyped("anotherDate", { type: "date", value: new Date(), valueInfo: {} }); // 2- providing a date string as a value: variables.setTyped("anotherDate", { type: "date", value: "2016-01-25T13:33:42.165+0100", valueInfo: {} }); // `variables.get("anotherDate")` is a date object console.log(typeof variables.get("anotherDate")); // output: object // `variables.getTyped("anotherDate").value` is date object console.log(typeof variables.getTyped("anotherDate").value); // output: object ``` -------------------------------- ### Subscribe to External Tasks and Handle Logic with Camunda Client JS Source: https://context7.com/camunda/camunda-external-task-client-js/llms.txt Demonstrates how to subscribe to specific external task topics using the Camunda External Task Client JS. It shows how to define a handler function that accesses task variables, performs business logic, sets process variables, and completes the task. It also includes an example of subscription with custom options like lock duration and variable filtering, and how to unsubscribe. ```javascript import { Client, logger, Variables } from "camunda-external-task-client-js"; const client = new Client({ baseUrl: "http://localhost:8080/engine-rest", use: logger }); // Basic subscription client.subscribe("creditScoreChecker", async function({ task, taskService }) { // Access task variables const defaultScore = task.variables.get("defaultScore"); const customerId = task.variables.get("customerId"); // Business logic const creditScores = [defaultScore, 9, 1, 4, 10]; const averageScore = creditScores.reduce((a, b) => a + b, 0) / creditScores.length; // Set process variables const processVariables = new Variables() .set("creditScores", creditScores) .set("averageScore", averageScore) .set("evaluationDate", new Date()); // Complete task with error handling try { await taskService.complete(task, processVariables); console.log("Task completed successfully!"); } catch (e) { console.error(`Failed to complete task: ${e}`); } }); // Subscription with custom options const subscription = client.subscribe("invoiceCreator", { lockDuration: 30000, // Custom lock duration variables: ["customerId", "amount"], // Fetch only specific variables businessKey: "invoice-2024", // Filter by business key processDefinitionKey: "invoice-process", // Filter by process definition tenantIdIn: ["tenant1", "tenant2"], // Filter by tenant IDs localVariables: true, // Include local variables includeExtensionProperties: true // Include extension properties }, async function({ task, taskService }) { const amount = task.variables.get("amount"); await taskService.complete(task, new Variables().set("processed", true)); } ); // Unsubscribe when needed // subscription.unsubscribe(); ``` -------------------------------- ### Start External Task Client Polling Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/docs/Client.md Initiates the polling process for the Camunda external task client. This method triggers the client to start fetching and locking tasks based on the configured subscriptions and polling intervals. ```javascript client.start(); ``` -------------------------------- ### Listen to Camunda Client Lock and Extend Lock Events Source: https://context7.com/camunda/camunda-external-task-client-js/llms.txt This example demonstrates handling client events for lock extension and task locking within the Camunda External Task Client. It logs success messages when locks are extended or acquired. Requires 'camunda-external-task-client-js'. ```javascript import { Client, logger } from "camunda-external-task-client-js"; const client = new Client({ baseUrl: "http://localhost:8080/engine-rest", use: logger }); client.on("extendLock:success", (task) => { console.log(`Lock extended for task ${task.id}`); }); client.on("unlock:success", (task) => { console.log(`Task ${task.id} unlocked`); }); client.on("lock:success", (task) => { console.log(`Task ${task.id} locked`); }); ``` -------------------------------- ### Get All Variable Values Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/docs/Variables.md Fetches all variables as an object containing their untyped values. This provides a quick overview of all variables associated with the task. ```javascript // Given: // { // score: { value: 5, type: "integer", valueInfo: {} } // isWinning: { value: false, type: "boolean", valueInfo: {} } // } const values = variables.getAll(); console.log(values); ``` -------------------------------- ### Read Task Variables Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/docs/handler.md This example shows how to subscribe to a topic and access all process variables associated with a fetched task using the `task.variables.getAll()` method. It's useful for inspecting all available data for a task. ```javascript client.subscribe("bar", async function({ task, taskService }) { // output all process variables console.log(task.variables.getAll()); }); ``` -------------------------------- ### Set and Get JSON Variables (JavaScript) Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/docs/Variables.md Illustrates how to set JSON objects as variables using `variables.set()` with an object or `variables.setTyped()` with a typed JSON object. It also covers retrieving these JSON variables and verifying their object type. ```javascript // 'variables.set()' can be used to set a JSON object by providing an object variables.set("meal", { id: 0, name: "pasta" }); // The same is also possible with `variables.setTyped()` variables.setTyped({ type: "json", value: { id: 0, name: "pasta" }, valueInfo: {} }); // `variables.get("meal")` is an object console.log(variables.get("someJSON")); // output: { id: 0, name: "pasta" } // `variables.getTyped("meal").value` is an object console.log(variables.getTyped("someJSON").value); // output: { id: 0, name: "pasta" } ``` -------------------------------- ### Configure Camunda Client with Custom Logger Level Source: https://context7.com/camunda/camunda-external-task-client-js/llms.txt This example shows how to configure the Camunda External Task Client with a custom log level for the logger middleware. This allows for more detailed or restricted logging output. Supported levels include error, warn, info, verbose, debug, and silly. Requires 'camunda-external-task-client-js'. ```javascript import { Client, logger } from "camunda-external-task-client-js"; // Use logger with custom log level const verboseClient = new Client({ baseUrl: "http://localhost:8080/engine-rest", use: logger.level("debug") // Levels: error, warn, info, verbose, debug, silly }); ``` -------------------------------- ### Get All Typed Variable Values Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/docs/Variables.md Retrieves all variables with their complete typed information. This is useful for tasks requiring detailed inspection or modification of multiple variables. ```javascript // Given: // { // score: { value: 5, type: "integer", valueInfo: {} } // isWinning: { value: false, type: "boolean", valueInfo: {} } // } const typedValues = variables.getAllTyped(); console.log(typedValues); ``` -------------------------------- ### Handle Task Failure with Retries Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/docs/handler.md This example illustrates how to handle a failed external task. It shows how to use `taskService.handleFailure` with options for error messages, details, retries, and retry timeouts, allowing for robust error management. ```javascript // Susbscribe to the topic: 'topicName' client.subscribe("topicName", async function({ task, taskService }) { // Put your business logic // Handle a Failure await taskService.handleFailure(task, { errorMessage: "some failure message", errorDetails: "some details", retries: 1, retryTimeout: 1000 }); }); ``` -------------------------------- ### Get Variable Value Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/docs/Variables.md Retrieves the untyped value of a specific variable by its name. This method is suitable when you only need the raw value without type information. ```javascript // Given: // score: { value: 5, type: "integer", valueInfo: {} } const score = variables.get("score"); console.log(score); ``` -------------------------------- ### Get Typed Variable Value Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/docs/Variables.md Retrieves the full typed representation of a variable, including its value, type, and value information. This is useful when you need to inspect or manipulate the variable's type. ```javascript // Given // score: { value: 5, type: "integer", valueInfo: {} } const score = variables.getTyped("score"); console.log(score); ``` -------------------------------- ### Initialize KeycloakAuthInterceptor and Camunda Client (JavaScript) Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/docs/KeycloakAuthInterceptor.md This snippet demonstrates how to initialize the KeycloakAuthInterceptor with Keycloak configuration details and then use it to configure the Camunda external task client. It shows the necessary imports and the structure for setting up authentication for the client. ```javascript const { Client, KeycloakAuthInterceptor } = require("camunda-external-task-client-js"); const keycloakAuthentication = new KeycloakAuthInterceptor({ tokenEndpoint: "https://your.keyclock.domain/realms/your-realm/protocol/openid-connect/token", clientId: "your-client-id", clientSecret: "your-client-secret" }); const client = new Client({ baseUrl: "http://localhost:8080/engine-rest", interceptors: keycloakAuthentication }); ``` -------------------------------- ### Subscribe to a Camunda External Task Topic Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/README.md This JavaScript snippet demonstrates how to create a client instance and subscribe to an external task topic. It includes configuration for the Camunda engine's base URL and a logger utility. The subscription callback function receives task and taskService objects, allowing for business logic implementation and task completion. ```js import { Client, logger } from "camunda-external-task-client-js"; // configuration for the Client: // - 'baseUrl': url to the Process Engine // - 'logger': utility to automatically log important events const config = { baseUrl: "http://localhost:8080/engine-rest", use: logger }; // create a Client instance with custom configuration const client = new Client(config); // susbscribe to the topic: 'creditScoreChecker' client.subscribe("creditScoreChecker", async function({ task, taskService }) { // Put your business logic // complete the task await taskService.complete(task); }); ``` -------------------------------- ### Initialize and Subscribe to External Tasks Client Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/docs/Client.md Demonstrates how to initialize the Camunda external task client with a base URL and subscribe to a specific topic ('foo') to handle incoming tasks. The subscription callback receives task details and a task service for further operations. ```javascript const { Client } = require("camunda-external-task-handler-js"); const client = new Client({baseUrl: "http://localhost:8080/engine-rest"}); client.subscribe("foo", async function({task, taskService}) { // Put your business logic }); ``` -------------------------------- ### Initialize and Set Variables Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/docs/Variables.md Demonstrates how to initialize a new Variables instance and set multiple variables at once. This is useful for preparing a set of variables to be sent with an external task. ```javascript const { Variables } = require("camunda-external-task-client-js"); // ... somewhere in the handler function const variables = new Variables().setAll({ foo: "some foo value" }); console.log("foo", variables.get("foo")); ``` -------------------------------- ### Initialize Client with Logger Middleware (JavaScript) Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/docs/logger.md Demonstrates how to initialize the Camunda External Task Client and integrate the logger middleware. The logger middleware is passed using the 'use' option during client instantiation. ```javascript const { Client, logger } = require("camunda-external-task-client-js"); const client = new Client({ use: logger, baseUrl: "http://localhost:8080/engine-rest" }); ``` -------------------------------- ### Create and Load File Variable with JS Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/docs/File.md Demonstrates how to create a File instance, load its content from a local path, and set it as a process variable using the Camunda External Task Client for JavaScript. Requires the 'camunda-external-task-handler-js' library. ```javascript const { Client, logger, File } = require("camunda-external-task-handler-js"); const client = new Client({ baseUrl: "http://localhost:8080/engine-rest" }); client.subscribe("foo", async function({ task, taskService}) { const file = await new File({ localPath: "./data.txt" }).load(); variables.set("dataFile", file); }); ``` -------------------------------- ### Initialize Camunda External Task Client in Node.js Source: https://context7.com/camunda/camunda-external-task-client-js/llms.txt Demonstrates how to create and configure a Camunda External Task Client instance in Node.js. This includes setting the base URL for the Camunda REST API, worker ID, polling parameters, and optional middleware like logging. It also shows advanced configurations for sorting tasks and controlling polling manually. ```javascript import { Client, logger } from "camunda-external-task-client-js"; // Basic client configuration const client = new Client({ baseUrl: "http://localhost:8080/engine-rest", // Required: Camunda REST API URL workerId: "worker-1", // Optional: Worker identifier (default: "some-random-id") maxTasks: 10, // Optional: Max tasks to fetch per poll (default: 10) interval: 300, // Optional: Polling interval in ms (default: 300) lockDuration: 50000, // Optional: Default lock duration in ms (default: 50000) autoPoll: true, // Optional: Start polling automatically (default: true) maxParallelExecutions: 5, // Optional: Limit concurrent task executions usePriority: true, // Optional: Enable priority-based fetching (default: true) use: logger // Optional: Attach middleware/logger }); // Advanced configuration with sorting const advancedClient = new Client({ baseUrl: "http://localhost:8080/engine-rest", use: logger, usePriority: false, sorting: [ { sortBy: Client.SortBy.CreateTime, // Sort by creation time sortOrder: Client.SortOrder.DESC // Descending order } ], asyncResponseTimeout: 10000 // Long polling timeout in ms }); // Manual polling control const manualClient = new Client({ baseUrl: "http://localhost:8080/engine-rest", autoPoll: false }); manualClient.start(); // Start polling manually // manualClient.stop(); // Stop polling when needed ``` -------------------------------- ### Configure Camunda Client with Default Logger Middleware Source: https://context7.com/camunda/camunda-external-task-client-js/llms.txt This snippet demonstrates how to initialize the Camunda External Task Client with the default logger middleware. The logger provides console output for subscribe, complete, and error operations. It requires the 'camunda-external-task-client-js' library. ```javascript import { Client, logger } from "camunda-external-task-client-js"; // Use logger with default info level const client = new Client({ baseUrl: "http://localhost:8080/engine-rest", use: logger // Logs: subscribe, complete, errors }); ``` -------------------------------- ### Upload and Process File Variables with Camunda External Task Client Source: https://context7.com/camunda/camunda-external-task-client-js/llms.txt Demonstrates uploading files from local paths and remote URLs as process variables using the File class. It also shows how to retrieve and process file variables from incoming tasks. ```javascript import { Client, Variables, File } from "camunda-external-task-client-js"; const client = new Client({ baseUrl: "http://localhost:8080/engine-rest", use: logger }); // Upload file from local filesystem client.subscribe("documentProcessor", async function({ task, taskService }) { // Load file from disk const invoice = await new File({ localPath: "./assets/invoice.pdf", mimetype: "application/pdf" // Optional: specify MIME type }).load(); const attachment = await new File({ localPath: "./assets/contract.docx", filename: "contract-signed.docx", // Optional: override filename encoding: "utf-8" // Optional: specify encoding }).load(); // Set files as process variables const variables = new Variables() .setAll({ invoice, attachment }) .set("uploadDate", new Date()); await taskService.complete(task, variables); }); // Download and process file from task variables client.subscribe("documentReader", async function({ task, taskService }) { // Get file variable (returns File instance) const documentTyped = task.variables.getTyped("document"); if (documentTyped && documentTyped.type === "file") { const file = documentTyped.value; // file.content contains the file data as Buffer // file.filename contains the original filename // file.mimetype contains the MIME type // file.encoding contains the encoding console.log(`Processing file: ${file.filename}`); console.log(`File size: ${file.content.length} bytes`); console.log(`MIME type: ${file.mimetype}`); // Process file content const processed = processFileContent(file.content); await taskService.complete(task, new Variables().set("processed", true)); } }); // Load file from remote URL client.subscribe("remoteFileHandler", async function({ task, taskService }) { const fileUrl = task.variables.get("fileUrl"); const remoteFile = await new File({ remotePath: fileUrl, // Remote URL to file filename: "downloaded-file.pdf" }).load(); await taskService.complete(task, new Variables().set("file", remoteFile)); }); ``` -------------------------------- ### Implement Camunda External Task Worker in JavaScript Source: https://context7.com/camunda/camunda-external-task-client-js/llms.txt This snippet shows how to set up and configure the Camunda External Task Client for JavaScript. It includes client instantiation with authentication, worker ID, task fetching options, and custom interceptors. It also demonstrates subscribing to external tasks like 'creditScoreChecker', 'documentGenerator', and 'manualApproval', detailing how to process tasks, manage variables, handle success and failure scenarios, and extend locks. ```javascript import { Client, logger, Variables, File, BasicAuthInterceptor } from "camunda-external-task-client-js"; // Configure client with authentication and advanced options const client = new Client({ baseUrl: "http://localhost:8080/engine-rest", workerId: "loan-processor-worker-1", maxTasks: 5, interval: 500, lockDuration: 30000, maxParallelExecutions: 3, use: logger.level("info"), interceptors: new BasicAuthInterceptor({ username: "demo", password: "demo" }), sorting: [ { sortBy: Client.SortBy.CreateTime, sortOrder: Client.SortOrder.DESC } ] }); // Credit score calculation task client.subscribe("creditScoreChecker", { lockDuration: 20000, variables: ["customerId", "loanAmount", "defaultScore"], processDefinitionKey: "loan-approval-process" }, async function({ task, taskService }) { console.log(`Processing credit check for task ${task.id}`); const customerId = task.variables.get("customerId"); const loanAmount = task.variables.get("loanAmount"); const defaultScore = task.variables.get("defaultScore"); try { // Simulate credit check API call const creditScores = await fetchCreditScores(customerId); const averageScore = creditScores.reduce((a, b) => a + b, 0) / creditScores.length; const processVariables = new Variables() .set("creditScores", creditScores) .set("averageScore", averageScore) .set("checkTimestamp", new Date()) .set("approved", averageScore > 600); const localVariables = new Variables() .set("checkedBy", "worker-1") .setTransient("debugInfo", { scores: creditScores }); await taskService.complete(task, processVariables, localVariables); console.log(`Credit check completed for customer ${customerId}`); } catch (error) { console.error(`Credit check failed: ${error.message}`); await taskService.handleFailure(task, { errorMessage: "Credit check service unavailable", errorDetails: error.stack, retries: 3, retryTimeout: 10000 }); } } ); // Document generation task with file handling client.subscribe("documentGenerator", { lockDuration: 60000 }, async function({ task, taskService }) { const customerId = task.variables.get("customerId"); const loanAmount = task.variables.get("loanAmount"); const approved = task.variables.get("approved"); try { // Generate document const documentPath = await generateLoanDocument(customerId, loanAmount, approved); // Load and attach file const document = await new File({ localPath: documentPath, filename: `loan-${customerId}-${Date.now()}.pdf`, mimetype: "application/pdf" }).load(); const variables = new Variables() .set("loanDocument", document) .set("documentGenerated", true) .set("generatedAt", new Date()); await taskService.complete(task, variables); } catch (error) { // Business error - insufficient data if (error.code === "MISSING_DATA") { await taskService.handleBpmnError( task, "INSUFFICIENT_DATA", "Missing required customer data", new Variables().set("missingFields", error.fields) ); } else { // Technical error - retry await taskService.handleFailure(task, { errorMessage: error.message, retries: 2, retryTimeout: 5000 }); } } } ); // Long-running approval task with lock extension client.subscribe("manualApproval", { lockDuration: 30000 }, async function({ task, taskService }) { const customerId = task.variables.get("customerId"); // Set up periodic lock extension const lockExtender = setInterval(async () => { try { await taskService.extendLock(task, 30000); console.log(`Extended lock for approval task ${task.id}`); } catch (e) { clearInterval(lockExtender); console.error("Failed to extend lock:", e); } }, 20000); try { // Wait for external approval (polling database, webhook, etc.) const approval = await waitForApproval(customerId, 120000); clearInterval(lockExtender); const variables = new Variables() .set("manuallyApproved", approval.approved) .set("approvedBy", approval.approver) .set("approvalComments", approval.comments) .set("approvalTimestamp", new Date()); await taskService.complete(task, variables); } catch (error) { clearInterval(lockExtender); throw error; } } ); // Helper functions (simulated) async function fetchCreditScores(customerId) { // Simulate API call return [720, 680, 710]; } ``` -------------------------------- ### Configure Basic Authentication with Camunda External Task Client Source: https://context7.com/camunda/camunda-external-task-client-js/llms.txt Shows how to add HTTP Basic Authentication headers to all requests made by the Camunda External Task Client to the Camunda REST API. ```javascript import { Client, BasicAuthInterceptor, logger } from "camunda-external-task-client-js"; // Configure client with Basic Auth const client = new Client({ baseUrl: "http://localhost:8080/engine-rest", use: logger, interceptors: new BasicAuthInterceptor({ username: "demo", password: "demo123" }) }); client.subscribe("secureTask", async function({ task, taskService }) { // All requests to Camunda API will include Basic Auth header await taskService.complete(task); }); ``` -------------------------------- ### Configure Camunda Client with Multiple Middleware Functions Source: https://context7.com/camunda/camunda-external-task-client-js/llms.txt This snippet illustrates initializing the Camunda External Task Client with an array of middleware functions, including the logger and custom middleware. This allows for chained processing of client operations. Dependencies include 'camunda-external-task-client-js' and any custom middleware functions. ```javascript import { Client, logger } from "camunda-external-task-client-js"; // Multiple middleware functions const multiMiddlewareClient = new Client({ baseUrl: "http://localhost:8080/engine-rest", use: [logger, customMiddleware1, customMiddleware2] }); ``` -------------------------------- ### Listening to Camunda Client Events (JavaScript) Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/docs/Client.md This snippet demonstrates how to subscribe to various client events emitted by the Camunda External Task Client. These events provide insights into the client's lifecycle, including subscription status, polling actions, and task handling outcomes. It's recommended to refer to the logger for detailed event usage. ```javascript client.on("subscribe", function(topic, topicSubscription) { /* ... */ }); client.on("unsubscribe", function(topic, topicSubscription) { /* ... */ }); client.on("poll:start", function() { /* ... */ }); client.on("poll:stop", function() { /* ... */ }); client.on("poll:success", function(tasks) { /* ... */ }); client.on("poll:error", function(error) { /* ... */ }); client.on("complete:success", function(task) { /* ... */ }); client.on("complete:error", function(task, error) { /* ... */ }); client.on("handleFailure:success", function(task) { /* ... */ }); client.on("handleFailure:error", function(task, error) { /* ... */ }); client.on("handleBpmnError:success", function(task) { /* ... */ }); client.on("handleBpmnError:error", function(task, error) { /* ... */ }); client.on("extendLock:success", function(task) { /* ... */ }); client.on("extendLock:error", function(task, error) { /* ... */ }); client.on("unlock:success", function(task) { /* ... */ }); client.on("unlock:error", function(task, error) { /* ... */ }); client.on("lock:success", function(task) { /* ... */ }); client.on("lock:error", function(task, error) { /* ... */ }); ``` -------------------------------- ### Handle Task with Variables Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/docs/handler.md This snippet demonstrates how to create a client, define a handler function to process an external task, retrieve and set process variables, and complete the task. It utilizes the Camunda External Task Client JS library. ```javascript const { Client, logger, Variables } = require("camunda-external-task-client-js"); // create a Client instance with custom configuration const client = new Client({ baseUrl: "http://localhost:8080/engine-rest", use: logger }); // create a handler function const handler = async function({ task, taskService }) { // get the process variable 'score' const score = Variables.get("score"); // set a process variable 'winning' const processVariables = new Variables().set("winning", score > 5); // set a local variable 'winningDate' const localVariables = new Variables().set("winningDate", new Date()); // complete the task await taskService.complete(task, processVariables, localVariables); }; // susbscribe to the topic: 'topicName' client.subscribe("topicName", handler); ``` -------------------------------- ### Configure Keycloak Authentication with Camunda External Task Client Source: https://context7.com/camunda/camunda-external-task-client-js/llms.txt Illustrates integration with Keycloak for OAuth2/OIDC authentication, including automatic token caching and renewal for requests to the Camunda REST API. ```javascript import { Client, KeycloakAuthInterceptor, logger } from "camunda-external-task-client-js"; // Configure client with Keycloak Auth const client = new Client({ baseUrl: "http://localhost:8080/engine-rest", use: logger, interceptors: new KeycloakAuthInterceptor({ tokenEndpoint: "https://keycloak.example.com/auth/realms/camunda/protocol/openid-connect/token", clientId: "camunda-client", clientSecret: "your-client-secret", cacheOffset: 10 // Optional: seconds before expiry to refresh (default: 10) }) }); // Multiple interceptors const multiAuthClient = new Client({ baseUrl: "http://localhost:8080/engine-rest", interceptors: [ new BasicAuthInterceptor({ username: "user", password: "pass" }), customInterceptor // Custom request interceptor ] }); client.subscribe("keycloakSecuredTask", async function({ task, taskService }) { // Keycloak Bearer token automatically added to requests // Token is cached and refreshed automatically await taskService.complete(task); }); ``` -------------------------------- ### Add Basic Authentication to Camunda Client Requests (JavaScript) Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/docs/BasicAuthInterceptor.md This snippet demonstrates how to instantiate and use the BasicAuthInterceptor to secure requests to the Camunda REST API. It requires the 'camunda-external-task-client-js' library. The interceptor takes a configuration object with username and password, and is then passed to the client constructor. ```javascript const { Client, BasicAuthInterceptor } = require("camunda-external-task-client-js"); const basicAuthentication = new BasicAuthInterceptor({ username: "demo", password: "demo" }); const client = new Client({ baseUrl: "http://localhost:8080/engine-rest", interceptors: basicAuthentication }); ``` -------------------------------- ### Camunda JS: Complete Task Successfully Source: https://context7.com/camunda/camunda-external-task-client-js/llms.txt Demonstrates how to successfully complete an external task using the TaskService. It involves setting process and local variables before calling the complete method. This is the standard way to signal that a task has been processed. ```javascript import { Client, Variables } from "camunda-external-task-client-js"; const client = new Client({ baseUrl: "http://localhost:8080/engine-rest", use: logger }); // Complete task successfully client.subscribe("successHandler", async function({ task, taskService }) { const processVars = new Variables().set("result", "success"); const localVars = new Variables().set("executedBy", "worker-1"); await taskService.complete(task, processVars, localVars); }); ``` -------------------------------- ### Listen to Camunda Client Task Completion and Failure Events Source: https://context7.com/camunda/camunda-external-task-client-js/llms.txt This snippet shows how to handle client events related to task completion and failures in the Camunda External Task Client. It logs success or error messages for task completion, BPMN errors, and handling failures. Requires 'camunda-external-task-client-js'. ```javascript import { Client, logger } from "camunda-external-task-client-js"; const client = new Client({ baseUrl: "http://localhost:8080/engine-rest", use: logger }); client.on("complete:success", (task) => { console.log(`Task ${task.id} completed`); }); client.on("complete:error", (task, error) => { console.error(`Task ${task.id} completion failed:`, error); }); client.on("handleFailure:success", (task) => { console.log(`Failure handled for task ${task.id}`); }); client.on("handleBpmnError:success", (task) => { console.log(`BPMN error handled for task ${task.id}`); }); ``` -------------------------------- ### Subscribe to Topic with Options | Camunda External Task Client JS Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/docs/Client.md Subscribes a handler function to a specific topic to fetch and process external tasks. Supports various options for filtering tasks like process definition versions, business keys, and tenant IDs. The handler receives task details and a task service for interaction. Returns a topic subscription object with an unsubscribe method. ```javascript const { Client } = require("camunda-external-task-client-js"); const client = new Client({ baseUrl: "http://localhost:8080/engine-rest" }); const topicSubscription = client.subscribe( "foo", { // Put your options here processDefinitionVersionTag: "v2" }, async function({task, taskService}) { // Put your business logic } ); // unsubscribe from a topic topicSubscription.unsubscribe(); ``` -------------------------------- ### Complete a Camunda External Task Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/README.md This JavaScript snippet shows the basic process of completing an external task after performing business logic. It subscribes to a topic and then calls `taskService.complete(task)` to signal successful execution to the Camunda engine. ```js // Susbscribe to the topic: 'topicName' client.subscribe("topicName", async function({ task, taskService }) { // Put your business logic // Complete the task await taskService.complete(task); }); ``` -------------------------------- ### Handle Camunda External Task with Variables in JavaScript Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/README.md This JavaScript code snippet subscribes to a Camunda external task topic, retrieves a process variable named 'score', sets a new process variable 'winning' based on the 'score', sets a local variable 'winningDate', and then completes the task. It requires the `camunda-external-task-client-js` library. ```javascript import { Variables } from "camunda-external-task-client-js"; client.subscribe("topicName", async function({ task, taskService }) { // get the process variable 'score' const score = task.variables.get("score"); // set a process variable 'winning' const processVariables = new Variables(); processVariables.set("winning", score > 5); // set a local variable 'winningDate' const localVariables = new Variables(); localVariables.set("winningDate", new Date()); // complete the task await taskService.complete(task, processVariables, localVariables); }); ``` -------------------------------- ### Format Success Message (JavaScript) Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/docs/logger.md Illustrates the usage of the `logger.success()` method to format and log a success message. This method takes a string as input and returns a formatted success output. ```javascript console.log(logger.success("This is a success message!")); ``` -------------------------------- ### Manage Process and Local Variables with Variables Class in Camunda JS Client Source: https://context7.com/camunda/camunda-external-task-client-js/llms.txt Illustrates how to use the `Variables` class in the Camunda External Task Client JS for type-safe management of process and local variables. It covers reading variables with automatic type detection, retrieving all variables, creating and setting various types of variables (boolean, number, array, object, Date), batch setting, explicit typed variable setting, transient variables, and creating local variables. ```javascript import { Client, Variables } from "camunda-external-task-client-js"; const client = new Client({ baseUrl: "http://localhost:8080/engine-rest", use: logger }); client.subscribe("variableHandler", async function({ task, taskService }) { // Reading variables - automatic type detection const score = task.variables.get("score"); // Get simple value const metadata = task.variables.get("metadata"); // Get JSON object const timestamp = task.variables.get("timestamp"); // Get Date object // Get typed value with metadata const typedScore = task.variables.getTyped("score"); // Returns: { value: 85, type: "integer", valueInfo: {} } // Get all variables const allValues = task.variables.getAll(); // Returns: { score: 85, metadata: {...}, timestamp: Date } const allTyped = task.variables.getAllTyped(); // Returns: { score: { value: 85, type: "integer", ... }, ... } // Creating and setting process variables const processVariables = new Variables(); processVariables.set("winning", score > 5); // Boolean processVariables.set("winningAmount", 1000.50); // Number processVariables.set("items", [1, 2, 3]); // Array processVariables.set("config", { key: "value" }); // Object processVariables.set("processedAt", new Date()); // Date // Batch setting variables processVariables.setAll({ status: "approved", approvedBy: "john.doe", count: 42 }); // Setting typed variables explicitly processVariables.setTyped("customField", { value: "custom-data", type: "string", valueInfo: {} }); // Transient variables (not persisted to database) processVariables.setTransient("tempData", "temporary-value"); // Creating local variables (task scope only) const localVariables = new Variables(); localVariables.set("localTimestamp", new Date()); localVariables.set("workerInfo", { workerId: "worker-1", version: "1.0" }); // Complete task with both process and local variables await taskService.complete(task, processVariables, localVariables); }); ``` -------------------------------- ### Complete Task with Default Variables Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/docs/handler.md This snippet demonstrates subscribing to a topic and completing an external task using `taskService.complete(task)`. It's the simplest way to acknowledge and finish a task without modifying process variables. ```javascript // Susbscribe to the topic: 'topicName' client.subscribe("topicName", async function({ task, taskService }) { // Put your business logic // Complete the task await taskService.complete(task); }); ``` -------------------------------- ### Handle Failure for a Camunda External Task Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/README.md This JavaScript snippet illustrates how to handle a failure for an external task. After executing business logic, `taskService.handleFailure` is called with error details, including an error message, optional details, and retry configuration. ```js // Susbscribe to the topic: 'topicName' client.subscribe("topicName", async function({ task, taskService }) { // Put your business logic // Handle a Failure await taskService.handleFailure(task, { errorMessage: "some failure message", errorDetails: "some details", retries: 1, retryTimeout: 1000 }); }); ``` -------------------------------- ### Configure Logger Level (JavaScript) Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/docs/logger.md Shows how to configure a specific log level for the logger middleware when initializing the client. The `logger.level()` method is used to set the desired level, such as 'debug'. If no level is specified, 'info' is used by default. ```javascript const { Client, logger } = require("camunda-external-task-client-js"); const client = new Client({ use: logger.level('debug'), baseUrl: "http://localhost:8080/engine-rest" }); ``` -------------------------------- ### Camunda JS: Handle Technical Failures with Retries Source: https://context7.com/camunda/camunda-external-task-client-js/llms.txt Illustrates how to handle technical failures in an external task. If an operation fails, the handleFailure method is used to report the error, specify the number of retries remaining, and set a timeout for the next attempt. This prevents task starvation due to transient issues. ```javascript import { Client, Variables } from "camunda-external-task-client-js"; const client = new Client({ baseUrl: "http://localhost:8080/engine-rest", use: logger }); // Handle technical failures with retries client.subscribe("retryableTask", async function({ task, taskService }) { try { // Attempt operation that might fail const result = await externalApiCall(); await taskService.complete(task, new Variables().set("result", result)); } catch (error) { // Report failure with retry configuration await taskService.handleFailure(task, { errorMessage: "External API call failed", errorDetails: error.stack, retries: 3, // Number of retries remaining retryTimeout: 5000 // Wait 5 seconds before retry }); } }); ``` -------------------------------- ### Define Custom Middleware Function for Camunda Client Source: https://context7.com/camunda/camunda-external-task-client-js/llms.txt This snippet shows how to define a custom middleware function for the Camunda External Task Client. This function can hook into client events like 'subscribe' to perform custom logic. It receives the client instance as an argument. Requires 'camunda-external-task-client-js'. ```javascript import { Client, logger } from "camunda-external-task-client-js"; // Custom middleware function function customMiddleware(client) { client.on("subscribe", (topic) => { // Custom logic on subscription console.log(`Custom handler for topic: ${topic}`); }); } const client = new Client({ baseUrl: "http://localhost:8080/engine-rest", use: [logger, customMiddleware] }); ``` -------------------------------- ### Format Error Message (JavaScript) Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/docs/logger.md Demonstrates how to use the `logger.error()` method to format and log an error message. This function accepts a string and returns it as a formatted error output. ```javascript console.log(logger.error("This is an error message!")); ``` -------------------------------- ### Set Multiple Variables Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/docs/Variables.md Updates or adds multiple variables at once using an object containing key-value pairs. The types are automatically inferred. This is efficient for bulk updates. ```javascript // Given: // { // score: { value: 6, type: "integer", valueInfo: {} } // isWinning: { value: true, type: "boolean", valueInfo: {} } // } variables.setAll({ score: 8, message: "Score is on 🔥" }); console.log(variables.getAll()); ``` -------------------------------- ### Camunda JS: Handle BPMN Errors (Business Errors) Source: https://context7.com/camunda/camunda-external-task-client-js/llms.txt Shows how to handle business logic errors by reporting BPMN errors. When a specific business condition is met (e.g., validation failure), handleBpmnError is called with a BPMN error code and message, triggering specific error handling paths in the BPMN process. Variables can be passed to the error handler. ```javascript import { Client, Variables } from "camunda-external-task-client-js"; const client = new Client({ baseUrl: "http://localhost:8080/engine-rest", use: logger }); // Handle BPMN errors (business errors) client.subscribe("businessValidation", async function({ task, taskService }) { const amount = task.variables.get("amount"); const customerId = task.variables.get("customerId"); // Validation logic if (amount > 10000 && !await hasApproval(customerId)) { // Trigger BPMN error boundary event const errorVariables = new Variables() .set("errorTimestamp", new Date()) .set("attemptedAmount", amount); await taskService.handleBpmnError( task, "APPROVAL_REQUIRED", // BPMN error code "Amount exceeds approval threshold", // Error message errorVariables // Variables to pass to error handler ); return; } await taskService.complete(task, new Variables().set("validated", true)); }); ``` -------------------------------- ### Unlock a Camunda External Task Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/README.md This JavaScript snippet demonstrates how to immediately unlock an external task. This action makes the task available to be fetched and locked by another worker, useful if the current worker cannot complete the task and wants to release it. ```js // Susbscribe to the topic: 'topicName' client.subscribe("topicName", async function({ task, taskService }) { // Put your business logic // Unlock the task await taskService.unlock(task); }); ``` -------------------------------- ### Camunda JS: Unlock Task Manually Source: https://context7.com/camunda/camunda-external-task-client-js/llms.txt Demonstrates how to manually unlock a task using the TaskService. This releases the task, making it available for other workers to pick up immediately. It is useful in scenarios where a worker decides not to process a task based on certain conditions. ```javascript import { Client, Variables } from "camunda-external-task-client-js"; const client = new Client({ baseUrl: "http://localhost:8080/engine-rest", use: logger }); // Unlock task manually client.subscribe("conditionalTask", async function({ task, taskService }) { const canProcess = await checkCondition(); if (!canProcess) { // Unlock task so another worker can pick it up await taskService.unlock(task); return; } await taskService.complete(task); }); ``` -------------------------------- ### Set Multiple Typed Variables Source: https://github.com/camunda/camunda-external-task-client-js/blob/master/docs/Variables.md Adds or updates multiple variables simultaneously, providing explicit type information for each. This offers granular control over variable data types during batch operations. ```javascript // Given: // { // score: { value: 6, type: "integer", valueInfo: {} } // isWinning: { value: true, type: "boolean", valueInfo: {} } // } variables.setAllTyped({ score: { value: 8, type: "short", valueInfo: {} }, message: { value: "Score is on 🔥", type: "string", valueInfo: {} } }); console.log(variables.getAllTyped()); ```