updating actions

This commit is contained in:
2026-02-12 11:37:48 -06:00
parent 9072c93fe4
commit d6dfcf65d6
3 changed files with 129 additions and 49 deletions

View File

@@ -3,28 +3,38 @@
* Hello Action - Node.js Example Pack * Hello Action - Node.js Example Pack
* *
* A minimal Node.js action that returns "Hello, Node.js". * A minimal Node.js action that returns "Hello, Node.js".
* Demonstrates the basic structure of a Node.js action in Attune. * Demonstrates the basic structure of a self-contained action in Attune.
* *
* When invoked via the Node.js wrapper, the `run` export is called * Actions receive parameters as JSON on stdin and write results to stdout.
* with the action parameters as its argument.
*/ */
"use strict"; "use strict";
/** function main() {
* Return a simple greeting message. let data = "";
* @param {object} params - Action parameters (unused). process.stdin.setEncoding("utf8");
* @returns {{ message: string }} process.stdin.on("readable", () => {
*/ let chunk;
function run(params) { while ((chunk = process.stdin.read()) !== null) {
return { message: "Hello, Node.js" }; data += chunk;
}
});
process.stdin.on("end", () => {
// Parse the first line as JSON parameters
const firstLine = data.split("\n")[0].trim();
let params = {};
if (firstLine) {
try {
params = JSON.parse(firstLine);
} catch {
// ignore parse errors, use empty params
}
}
const name = params.name || "Node.js";
const result = { message: `Hello, ${name}` };
process.stdout.write(JSON.stringify(result) + "\n");
});
} }
// Direct execution support (without the wrapper) main();
if (require.main === module) {
const result = run({});
process.stdout.write(JSON.stringify({ result, status: "success" }) + "\n");
process.exit(0);
}
module.exports = { run };

View File

@@ -2,25 +2,79 @@
/** /**
* HTTP Example Action - Node.js Example Pack * HTTP Example Action - Node.js Example Pack
* *
* Demonstrates using the `node-fetch` library to make an HTTP call to example.com. * Demonstrates using the built-in https/http modules to make an HTTP call.
* Receives parameters via the Node.js wrapper (stdin JSON with code_path). * Receives parameters via stdin as JSON.
*/ */
const fetch = require("node-fetch"); "use strict";
async function run(params) { const https = require("https");
const url = params.url || "https://example.com"; const http = require("http");
const { URL } = require("url");
const response = await fetch(url, { timeout: 10000 }); function fetchUrl(url, timeout) {
const text = await response.text(); return new Promise((resolve, reject) => {
const parsed = new URL(url);
const mod = parsed.protocol === "https:" ? https : http;
return { const req = mod.get(url, { timeout }, (res) => {
status_code: response.status, let body = "";
url: response.url, res.on("data", (chunk) => {
content_length: text.length, body += chunk;
snippet: text.slice(0, 500), });
success: response.ok, res.on("end", () => {
}; resolve({
status_code: res.statusCode,
url: url,
content_length: body.length,
snippet: body.slice(0, 500),
success: res.statusCode >= 200 && res.statusCode < 400,
});
});
});
req.on("error", (err) => reject(err));
req.on("timeout", () => {
req.destroy();
reject(new Error("Request timed out"));
});
});
} }
module.exports = { run }; function main() {
let data = "";
process.stdin.setEncoding("utf8");
process.stdin.on("readable", () => {
let chunk;
while ((chunk = process.stdin.read()) !== null) {
data += chunk;
}
});
process.stdin.on("end", async () => {
// Parse the first line as JSON parameters
const firstLine = data.split("\n")[0].trim();
let params = {};
if (firstLine) {
try {
params = JSON.parse(firstLine);
} catch {
// ignore parse errors, use empty params
}
}
const url = params.url || "https://example.com";
const timeout = (params.timeout || 10) * 1000;
try {
const result = await fetchUrl(url, timeout);
process.stdout.write(JSON.stringify(result) + "\n");
} catch (err) {
process.stderr.write(
JSON.stringify({ error: err.message || String(err) }) + "\n",
);
process.exit(1);
}
});
}
main();

View File

@@ -5,26 +5,42 @@
* Consumes a counter value (typically from the counter sensor trigger payload) * Consumes a counter value (typically from the counter sensor trigger payload)
* and returns a formatted message containing the counter value. * and returns a formatted message containing the counter value.
* *
* Parameters are delivered via stdin as JSON from the Node.js wrapper. * Parameters are delivered via stdin as JSON.
*/ */
"use strict"; "use strict";
/** function main() {
* @param {object} params let data = "";
* @param {number} params.counter - The counter value from the trigger payload. process.stdin.setEncoding("utf8");
* @param {string} params.rule_ref - The rule reference the counter is scoped to. process.stdin.on("readable", () => {
* @returns {object} Formatted message and raw counter value. let chunk;
*/ while ((chunk = process.stdin.read()) !== null) {
function run(params) { data += chunk;
const counter = params.counter !== undefined ? params.counter : 0; }
const ruleRef = params.rule_ref || "unknown"; });
process.stdin.on("end", () => {
// Parse the first line as JSON parameters
const firstLine = data.split("\n")[0].trim();
let params = {};
if (firstLine) {
try {
params = JSON.parse(firstLine);
} catch {
// ignore parse errors, use empty params
}
}
return { const counter = params.counter !== undefined ? params.counter : 0;
message: `Counter value is ${counter} (from rule: ${ruleRef})`, const ruleRef = params.rule_ref || "unknown";
counter: counter,
rule_ref: ruleRef, const result = {
}; message: `Counter value is ${counter} (from rule: ${ruleRef})`,
counter: counter,
rule_ref: ruleRef,
};
process.stdout.write(JSON.stringify(result) + "\n");
});
} }
module.exports = { run }; main();