91 lines
5.0 KiB
JavaScript
91 lines
5.0 KiB
JavaScript
|
|
module.exports = function(RED) {
|
||
|
|
var https = require('https');
|
||
|
|
var http = require('http');
|
||
|
|
var url = require('url');
|
||
|
|
|
||
|
|
var OPERATIONS = {
|
||
|
|
'webhook:list': { method:'GET', path:'/ocs/v2.php/apps/webhook_listeners/api/v1/webhooks', query:['uri'] },
|
||
|
|
'webhook:get': { method:'GET', path:'/ocs/v2.php/apps/webhook_listeners/api/v1/webhooks/{id}' },
|
||
|
|
'webhook:create': { method:'POST', path:'/ocs/v2.php/apps/webhook_listeners/api/v1/webhooks',
|
||
|
|
body:['httpMethod','uri','event','eventFilter','userIdFilter','headers','authMethod','authData','tokenNeeded'] },
|
||
|
|
'webhook:update': { method:'POST', path:'/ocs/v2.php/apps/webhook_listeners/api/v1/webhooks/{id}',
|
||
|
|
body:['httpMethod','uri','event','eventFilter','userIdFilter','headers','authMethod','authData','tokenNeeded'] },
|
||
|
|
'webhook:delete': { method:'DELETE', path:'/ocs/v2.php/apps/webhook_listeners/api/v1/webhooks/{id}' },
|
||
|
|
'webhook:deleteByApp':{ method:'DELETE', path:'/ocs/v2.php/apps/webhook_listeners/api/v1/webhooks/byappid/{appid}' }
|
||
|
|
};
|
||
|
|
|
||
|
|
function WebhooksNode(config) {
|
||
|
|
RED.nodes.createNode(this, config);
|
||
|
|
var node = this;
|
||
|
|
this.configNode = RED.nodes.getNode(config.nextcloud);
|
||
|
|
this.operation = config.operation || 'webhook:list';
|
||
|
|
this.webhookId = config.webhookId; this.appId = config.appId;
|
||
|
|
this.bodyHttpMethod = config.bodyHttpMethod; this.bodyUri = config.bodyUri;
|
||
|
|
this.bodyEvent = config.bodyEvent; this.bodyEventFilter = config.bodyEventFilter;
|
||
|
|
this.bodyUserIdFilter = config.bodyUserIdFilter; this.bodyHeaders = config.bodyHeaders;
|
||
|
|
this.bodyAuthMethod = config.bodyAuthMethod; this.bodyAuthData = config.bodyAuthData;
|
||
|
|
this.bodyTokenNeeded = config.bodyTokenNeeded;
|
||
|
|
|
||
|
|
if (!this.configNode) { node.error("No Nextcloud configuration node selected"); return; }
|
||
|
|
|
||
|
|
node.on('input', function(msg) {
|
||
|
|
var op = OPERATIONS[msg.operation || node.operation];
|
||
|
|
if (!op) { node.error("Unknown operation: " + (msg.operation || node.operation), msg); return; }
|
||
|
|
|
||
|
|
var baseUrl = (node.configNode.baseUrl || '').replace(/\/+$/, '');
|
||
|
|
var username = node.configNode.credentials.username;
|
||
|
|
var password = node.configNode.credentials.password;
|
||
|
|
|
||
|
|
var path = op.path
|
||
|
|
.replace('{id}', msg.webhookId || node.webhookId || '')
|
||
|
|
.replace('{appid}', msg.appId || node.appId || '');
|
||
|
|
|
||
|
|
var queryParts = [];
|
||
|
|
if (op.query) {
|
||
|
|
op.query.forEach(function(q) {
|
||
|
|
var v = msg[q] !== undefined ? msg[q] : getField(node, q);
|
||
|
|
if (v !== undefined && v !== '') queryParts.push(encodeURIComponent(q) + '=' + encodeURIComponent(v));
|
||
|
|
});
|
||
|
|
}
|
||
|
|
var fullUrl = baseUrl + path + (queryParts.length ? '?' + queryParts.join('&') : '');
|
||
|
|
var parsedUrl = url.parse(fullUrl);
|
||
|
|
|
||
|
|
var headers = { 'OCS-APIRequest':'true','Accept':'application/json',
|
||
|
|
'Authorization':'Basic '+Buffer.from(username+':'+password).toString('base64') };
|
||
|
|
|
||
|
|
var bodyObj = {};
|
||
|
|
if (op.body) {
|
||
|
|
op.body.forEach(function(b) {
|
||
|
|
var v = msg[b] !== undefined ? msg[b] : getField(node, b);
|
||
|
|
if (v !== undefined && v !== '') bodyObj[b] = v;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
if (msg.eventFilter) bodyObj.eventFilter = msg.eventFilter;
|
||
|
|
if (msg.headers && typeof msg.headers === 'object') bodyObj.headers = msg.headers;
|
||
|
|
if (msg.authData) bodyObj.authData = msg.authData;
|
||
|
|
if (msg.tokenNeeded) bodyObj.tokenNeeded = msg.tokenNeeded;
|
||
|
|
|
||
|
|
var bodyStr = null;
|
||
|
|
if (Object.keys(bodyObj).length > 0) { headers['Content-Type']='application/json'; bodyStr=JSON.stringify(bodyObj); }
|
||
|
|
|
||
|
|
var opts = { hostname:parsedUrl.hostname, port:parsedUrl.port||(parsedUrl.protocol==='https:'?443:80),
|
||
|
|
path:parsedUrl.path, method:op.method, headers:headers, rejectUnauthorized:false };
|
||
|
|
|
||
|
|
node.log(op.method+' '+fullUrl);
|
||
|
|
var transport = parsedUrl.protocol==='https:'?https:http;
|
||
|
|
var req = transport.request(opts, function(res) {
|
||
|
|
var body=''; res.on('data',function(c){body+=c;});
|
||
|
|
res.on('end',function(){ msg.statusCode=res.statusCode; msg.operation=msg.operation||node.operation;
|
||
|
|
try{msg.payload=JSON.parse(body);}catch(e){msg.payload=body;} node.send(msg); });
|
||
|
|
});
|
||
|
|
req.on('error',function(err){msg.error=err.message;node.error(op.method+' '+fullUrl+' — '+err.message,msg);});
|
||
|
|
if(bodyStr) req.write(bodyStr);
|
||
|
|
req.end();
|
||
|
|
});
|
||
|
|
}
|
||
|
|
function getField(node,name) {
|
||
|
|
var m={ 'httpMethod':node.bodyHttpMethod,'uri':node.bodyUri,'event':node.bodyEvent,'uri':node.bodyUri };
|
||
|
|
return m[name];
|
||
|
|
}
|
||
|
|
RED.nodes.registerType("webhooks", WebhooksNode);
|
||
|
|
};
|