Skip to content

Commit 31d261f

Browse files
committed
add rpa nodes
1 parent 7101447 commit 31d261f

4 files changed

Lines changed: 328 additions & 1 deletion

File tree

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<script type="text/x-red" data-template-name="rpa detector">
2+
<div class="form-row">
3+
<label ><i class="fa fa-tag"></i> Detector</label>
4+
<select id="node-input-queue-select">
5+
</select>
6+
<input id="node-input-queue" type="hidden">
7+
</div>
8+
<div class="form-row">
9+
<label><i class="fa fa-tag"></i> Auto acknowledgment</label>
10+
<input type="checkbox" id="node-input-noack" style="width: auto;">
11+
</div>
12+
<div class="form-row">
13+
<label ><i class="fa fa-tag"></i> Name</label>
14+
<input type="text" id="node-input-name" placeholder="Node name">
15+
</div>
16+
</script>
17+
<script type="text/x-red" data-help-name="rpa detector">
18+
Active everytime a trigger gets triggered on a robot
19+
</script>
20+
<script type="text/javascript">
21+
RED.nodes.registerType('rpa detector', {
22+
category: 'rpa',
23+
color: "#a6bbcf",
24+
defaults: {
25+
queue: { value: "", required: true },
26+
noack: { value: true, required: true },
27+
name: { value: "" }
28+
},
29+
inputs: 0,
30+
outputs: 1,
31+
icon: "bridge.png",
32+
label: function () {
33+
return this.name || "rpa detector";
34+
},
35+
labelStyle: function () {
36+
return this.name ? "node_label_italic" : "";
37+
},
38+
oneditprepare: function () {
39+
$.getJSON('rpa_detectors', function (data) {
40+
$.each(data, function (i, ele) {
41+
$('#node-input-queue-select').append($('<option>', {
42+
value: ele._id,
43+
text: ele.name
44+
}));
45+
});
46+
$('#node-input-queue-select').val($('#node-input-queue').val());
47+
});
48+
},
49+
oneditsave: function () {
50+
$('#node-input-queue').val($('#node-input-queue-select').val());
51+
}
52+
});
53+
</script>
54+
55+
56+
57+
58+
<script type="text/x-red" data-template-name="rpa workflow">
59+
<div class="form-row">
60+
<label ><i class="fa fa-tag"></i> Robot</label>
61+
<select id="node-input-queue-select">
62+
</select>
63+
<input id="node-input-queue" type="hidden">
64+
</div>
65+
<div class="form-row">
66+
<label ><i class="fa fa-tag"></i> Workflow</label>
67+
<select id="node-input-workflow-select">
68+
</select>
69+
<input id="node-input-workflow" type="hidden">
70+
</div>
71+
<div class="form-row">
72+
<label ><i class="fa fa-tag"></i> Local queue name</label>
73+
<input type="text" id="node-input-localqueue" placeholder="Queue name">
74+
</div>
75+
<div class="form-row">
76+
<label ><i class="fa fa-tag"></i> Name</label>
77+
<input type="text" id="node-input-name" placeholder="Node name">
78+
</div>
79+
</script>
80+
<script type="text/x-red" data-help-name="rpa workflow">
81+
Send payload as data to a robot, requesting it to run the selected Workflow
82+
</script>
83+
<script type="text/javascript">
84+
RED.nodes.registerType('rpa workflow', {
85+
category: 'rpa',
86+
color: "#a6bbcf",
87+
defaults: {
88+
queue: { value: "", required: true },
89+
workflow: { value: "", required: true },
90+
localqueue: { value: "" }
91+
},
92+
inputs: 1,
93+
outputs: 3,
94+
icon: "bridge.png",
95+
outputLabels: ["completed", "status", "failed"],
96+
label: function () {
97+
return this.name || "rpa workflow";
98+
},
99+
labelStyle: function () {
100+
return this.name ? "node_label_italic" : "";
101+
},
102+
oneditprepare: function () {
103+
$.getJSON('rpa_robots', function (data) {
104+
$('#node-input-queue-select').append($('<option>', {
105+
value: null,
106+
text: "none"
107+
}));
108+
$.each(data, function (i, ele) {
109+
$('#node-input-queue-select').append($('<option>', {
110+
value: ele._id,
111+
text: ele.name
112+
}));
113+
});
114+
$('#node-input-queue-select').val($('#node-input-queue').val());
115+
reloadWorkflows(true);
116+
$("#node-input-queue-select").change(function () {
117+
reloadWorkflows(false);
118+
})
119+
});
120+
var reloadWorkflows = function (firstrun) {
121+
$.getJSON('rpa_workflows', { queue: $('#node-input-queue-select').val() }, function (data) {
122+
$('#node-input-workflow-select').find('option').remove()
123+
$.each(data, function (i, ele) {
124+
$('#node-input-workflow-select').append($('<option>', {
125+
value: ele._id,
126+
text: ele.name
127+
}));
128+
});
129+
if (firstrun) {
130+
$('#node-input-workflow-select').val($('#node-input-workflow').val());
131+
}
132+
});
133+
}
134+
},
135+
oneditsave: function () {
136+
$('#node-input-queue').val($('#node-input-queue-select').val());
137+
$('#node-input-workflow').val($('#node-input-workflow-select').val());
138+
}
139+
140+
});
141+
</script>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Red } from "node-red";
2+
import * as rpa from "./rpa_nodes";
3+
4+
5+
export = function (RED: Red) {
6+
RED.nodes.registerType("rpa detector", rpa.rpa_detector_node);
7+
RED.nodes.registerType("rpa workflow", rpa.rpa_workflow_node);
8+
RED.httpAdmin.get("/rpa_detectors", RED.auth.needsPermission('serial.read'), rpa.get_rpa_detectors);
9+
RED.httpAdmin.get("/rpa_robots", RED.auth.needsPermission('serial.read'), rpa.get_rpa_robots);
10+
RED.httpAdmin.get("/rpa_workflows", RED.auth.needsPermission('serial.read'), rpa.get_rpa_workflows);
11+
12+
}
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
import * as RED from "node-red";
2+
import { Red } from "node-red";
3+
import { NoderedUtil } from "./NoderedUtil";
4+
import { Logger } from "../../Logger";
5+
import { amqp_consumer } from "../../amqp_consumer";
6+
import { amqp_publisher } from "../../amqp_publisher";
7+
import { Config } from "../../Config";
8+
9+
export interface Irpa_detector_node {
10+
queue: string;
11+
noack: boolean;
12+
}
13+
export class rpa_detector_node {
14+
public node: Red = null;
15+
public name: string = "";
16+
public con: amqp_consumer;
17+
public host: string = null;
18+
constructor(public config: Irpa_detector_node) {
19+
RED.nodes.createNode(this, config);
20+
try {
21+
this.node = this;
22+
this.node.on("close", this.onclose);
23+
this.host = Config.amqp_url;
24+
this.connect();
25+
} catch (error) {
26+
NoderedUtil.HandleError(this, error);
27+
}
28+
}
29+
async connect() {
30+
try {
31+
this.node.status({ fill: "blue", shape: "dot", text: "Connecting..." });
32+
this.con = new amqp_consumer(Logger.instanse, this.host, this.config.queue);
33+
this.con.OnMessage = this.OnMessage.bind(this);
34+
await this.con.connect(this.config.noack);
35+
this.node.status({ fill: "green", shape: "dot", text: "Connected" });
36+
} catch (error) {
37+
NoderedUtil.HandleError(this, error);
38+
}
39+
}
40+
async OnMessage(msg: any, ack: any) {
41+
try {
42+
var result: any = {};
43+
result.amqpacknowledgment = ack;
44+
45+
var data = JSON.parse(msg.content.toString());
46+
try {
47+
data.payload = JSON.parse(data.payload);
48+
} catch (error) {
49+
}
50+
result.payload = data.payload;
51+
result.jwt = data.jwt;
52+
this.node.send(result);
53+
} catch (error) {
54+
NoderedUtil.HandleError(this, error);
55+
}
56+
}
57+
onclose() {
58+
if (!NoderedUtil.IsNullUndefinded(this.con)) {
59+
this.con.close();
60+
}
61+
}
62+
}
63+
64+
65+
66+
export interface Irpa_workflow_node {
67+
queue: string;
68+
workflow: string;
69+
localqueue: string;
70+
}
71+
export class rpa_workflow_node {
72+
public node: Red = null;
73+
public name: string = "";
74+
public con: amqp_publisher;
75+
public host: string = null;
76+
constructor(public config: Irpa_workflow_node) {
77+
RED.nodes.createNode(this, config);
78+
try {
79+
this.node = this;
80+
this.node.on("input", this.oninput);
81+
this.node.on("close", this.onclose);
82+
this.host = Config.amqp_url;
83+
this.connect();
84+
} catch (error) {
85+
NoderedUtil.HandleError(this, error);
86+
}
87+
}
88+
async connect() {
89+
try {
90+
this.node.status({ fill: "blue", shape: "dot", text: "Connecting..." });
91+
this.con = new amqp_publisher(Logger.instanse, this.host, this.config.localqueue);
92+
this.con.OnMessage = this.OnMessage.bind(this);
93+
await this.con.connect();
94+
this.node.status({ fill: "green", shape: "dot", text: "Connected" });
95+
} catch (error) {
96+
NoderedUtil.HandleError(this, error);
97+
}
98+
}
99+
async OnMessage(msg: any, ack: any) {
100+
try {
101+
var result: any = {};
102+
result.amqpacknowledgment = ack;
103+
var json: string = msg.content.toString();
104+
var data = JSON.parse(json);
105+
result.jwt = data.jwt;
106+
107+
if (data.payload.command == "invokecompleted") {
108+
result.payload = data.payload.data;
109+
this.node.send(result);
110+
}
111+
else if (data.payload.command == "invokefailed" || data.payload.command == "invokeaborted") {
112+
result.payload = data.payload;
113+
this.node.send([null, null, result]);
114+
}
115+
else {
116+
result.payload = data.payload;
117+
this.node.send([null, result]);
118+
}
119+
// this.node.send(result);
120+
} catch (error) {
121+
NoderedUtil.HandleError(this, error);
122+
}
123+
}
124+
async oninput(msg: any) {
125+
try {
126+
this.node.status({});
127+
var rpacommand = {
128+
command: "invoke",
129+
workflowid: this.config.workflow,
130+
data: msg.payload
131+
}
132+
var data = {
133+
jwt: msg.jwt,
134+
payload: rpacommand
135+
}
136+
this.con.SendMessage(JSON.stringify(data), this.config.queue);
137+
// var data: any = {};
138+
// data.payload = msg.payload;
139+
// data.jwt = msg.jwt;
140+
// this.con.SendMessage(JSON.stringify(data), this.config.queue);
141+
this.node.status({});
142+
} catch (error) {
143+
NoderedUtil.HandleError(this, error);
144+
}
145+
}
146+
onclose() {
147+
if (!NoderedUtil.IsNullUndefinded(this.con)) {
148+
this.con.close();
149+
}
150+
}
151+
}
152+
153+
export async function get_rpa_detectors(req, res) {
154+
var token = await NoderedUtil.GetToken(null, null);
155+
var result: any[] = await NoderedUtil.Query('openrpa', { _type: "detector" },
156+
{ name: 1 }, { name: -1 }, 1000, 0, token.jwt)
157+
res.json(result);
158+
}
159+
export async function get_rpa_robots(req, res) {
160+
var token = await NoderedUtil.GetToken(null, null);
161+
var result: any[] = await NoderedUtil.Query('users', { _type: "user" },
162+
{ name: 1 }, { name: -1 }, 1000, 0, token.jwt)
163+
res.json(result);
164+
}
165+
export async function get_rpa_workflows(req, res) {
166+
var token = await NoderedUtil.GetToken(null, null);
167+
var q: any = { _type: "workflow" };
168+
if (req.query.queue != null && req.query.queue != undefined) {
169+
q = { _type: "workflow", $or: [{ _createdbyid: req.query.queue }, { _modifiedbyid: req.query.queue }] };
170+
}
171+
var result: any[] = await NoderedUtil.Query('openrpa', q,
172+
{ name: 1 }, { name: -1 }, 1000, 0, token.jwt)
173+
res.json(result);
174+
}

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.0.97
1+
0.0.98

0 commit comments

Comments
 (0)