mirror of
https://github.com/Hopiu/webapi-eca.git
synced 2026-03-16 22:10:31 +00:00
Debugging tools and use case implementation
This commit is contained in:
parent
8346b8bd7d
commit
003fe4111d
20 changed files with 514 additions and 207 deletions
18
README.md
18
README.md
|
|
@ -43,7 +43,7 @@ Apply your settings, for example:
|
|||
"io-level": "info", # the log-level for the std I/O stream
|
||||
"file-level": "info", # the log-level for the log file
|
||||
"file-path": "server.log" # log file path, relative to cwd
|
||||
( add "nolog": "true" if no log shall be generated at all. Mainly used for unit tests )
|
||||
"nolog": "false" # false if no log shall be generated at all. Mainly used for unit tests
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -54,9 +54,13 @@ Start the server:
|
|||
*Congratulations, your own WebAPI based ECA engine server is now up and running!*
|
||||
|
||||
|
||||
Optional command line tools:
|
||||
----------------------------
|
||||
|
||||
Optional command line scripts
|
||||
-----------------------------
|
||||
|
||||
Run test suite:
|
||||
|
||||
run_tests.sh
|
||||
|
||||
Create the doc *(to be accessed via the webserver, e.g.: localhost:8125/doc/)*:
|
||||
|
||||
> **WARNING:**
|
||||
|
|
@ -65,8 +69,4 @@ Create the doc *(to be accessed via the webserver, e.g.: localhost:8125/doc/)*:
|
|||
|
||||
> *`!!! 5` needs to be relaced with `doctype html`*
|
||||
|
||||
run_doc.sh
|
||||
|
||||
Run test suite:
|
||||
|
||||
run_tests.sh
|
||||
run_doc.sh
|
||||
|
|
@ -177,7 +177,7 @@ forgeModule = ( user, oPayload, dbMod, callback ) =>
|
|||
if answ.code is 200
|
||||
funcs = []
|
||||
funcs.push name for name, id of cm.module
|
||||
@log.info "CM | Storing new module with functions #{ funcs.join() }"
|
||||
@log.info "CM | Storing new module with functions #{ funcs.join( ', ' ) }"
|
||||
answ.message =
|
||||
" Module #{ oPayload.id } successfully stored! Found following function(s): #{ funcs }"
|
||||
oPayload.functions = JSON.stringify funcs
|
||||
|
|
|
|||
|
|
@ -49,20 +49,15 @@ exports.getPublicKey = () =>
|
|||
|
||||
|
||||
issueApiCall = ( logger ) ->
|
||||
( method, url, credentials, cb ) ->
|
||||
try
|
||||
if method is 'get'
|
||||
func = needle.get
|
||||
else
|
||||
func = needle.post
|
||||
|
||||
func url, credentials, ( err, resp, body ) =>
|
||||
( method, url, data, options, cb ) ->
|
||||
try
|
||||
needle.request method, url, data, options, ( err, resp, body ) =>
|
||||
try
|
||||
cb err, resp, body
|
||||
catch err
|
||||
logger 'Error during apicall! ' + err.message
|
||||
logger 'Error during needle request! ' + err.message
|
||||
catch err
|
||||
logger 'Error before apicall! ' + err.message
|
||||
logger 'Error before needle request! ' + err.message
|
||||
|
||||
logFunction = ( uId, rId, mId ) ->
|
||||
( msg ) ->
|
||||
|
|
@ -108,10 +103,9 @@ exports.compileString = ( src, userId, ruleId, modId, lang, dbMod, cb ) =>
|
|||
sandbox =
|
||||
id: userId + '.' + modId + '.vm'
|
||||
params: params
|
||||
apicall: issueApiCall logFunc
|
||||
# needle: needle
|
||||
needlereq: issueApiCall logFunc
|
||||
log: logFunc
|
||||
# debug: console.log
|
||||
debug: console.log
|
||||
exports: {}
|
||||
|
||||
#TODO child_process to run module!
|
||||
|
|
@ -124,7 +118,10 @@ exports.compileString = ( src, userId, ruleId, modId, lang, dbMod, cb ) =>
|
|||
# Start Node with the flags —nouse_idle_notification and —expose_gc, and then when you want to run the GC, just call global.gc().
|
||||
catch err
|
||||
answ.code = 400
|
||||
answ.message = 'Loading Module failed: ' + err.message
|
||||
msg = err.message
|
||||
if not msg
|
||||
msg = 'Try to run the script locally to track the error! Sadly we cannot provide the line number'
|
||||
answ.message = 'Loading Module failed: ' + msg
|
||||
cb
|
||||
answ: answ
|
||||
module: sandbox.exports
|
||||
|
|
|
|||
6
examples/action-invokers/continuously.coffee
Normal file
6
examples/action-invokers/continuously.coffee
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#
|
||||
# Pushes an event into the system each time the function is polled
|
||||
#
|
||||
exports.push = ( pushEvent ) ->
|
||||
pushEvent
|
||||
content: "This is an event that will be sent again and again every ten seconds"
|
||||
142
examples/action-invokers/probinder.coffee
Normal file
142
examples/action-invokers/probinder.coffee
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
|
||||
###
|
||||
ProBinder ACTION INVOKER
|
||||
------------------------
|
||||
|
||||
Global variables
|
||||
This module requires user-specific parameters:
|
||||
- username
|
||||
- password
|
||||
- companyId: company where to post the binder entries
|
||||
- contextId: context where to post the binder entries
|
||||
###
|
||||
urlService = 'https://probinder.com/service/'
|
||||
credentials =
|
||||
username: params.username
|
||||
password: params.password
|
||||
|
||||
#
|
||||
# The standard callback can be used if callback is not provided, e.g. if
|
||||
# the function is called from outside
|
||||
#
|
||||
standardCallback = ( funcName ) ->
|
||||
( err, resp, body ) ->
|
||||
if err
|
||||
log "ERROR: During function '#{ funcName }'"
|
||||
else
|
||||
if resp.statusCode is 200
|
||||
log "Function '#{ funcName }' ran through without error"
|
||||
else
|
||||
log "ERROR: During function '#{ funcName }': #{ body.error.message }"
|
||||
|
||||
###
|
||||
Call the ProBinder service with the given parameters.
|
||||
|
||||
@param {Object} args the required function arguments object
|
||||
@param {Object} [args.data] the data to be posted
|
||||
@param {String} args.service the required service identifier to be appended to the url
|
||||
@param {String} args.method the required method identifier to be appended to the url
|
||||
@param {function} [args.callback] the function to receive the request answer
|
||||
###
|
||||
exports.call = ( args ) ->
|
||||
if not args.service or not args.method
|
||||
log 'ERROR in call function: Missing arguments!'
|
||||
else
|
||||
if not args.callback
|
||||
args.callback = standardCallback 'call'
|
||||
url = urlService + args.service + '/' + args.method
|
||||
needlereq 'post', url, args.data, credentials, args.callback
|
||||
|
||||
###
|
||||
Calls the user's unread content service.
|
||||
|
||||
@param {Object} [args] the optional object containing the callback function
|
||||
@param {function} [args.callback] refer to call function
|
||||
###
|
||||
exports.getUnreadContents = ( args ) ->
|
||||
if not args.callback
|
||||
args.callback = standardCallback 'getUnreadContents'
|
||||
exports.call
|
||||
service: '36'
|
||||
method: 'unreadcontent'
|
||||
callback: args.callback
|
||||
|
||||
|
||||
###
|
||||
Calls the content get service with the content id and the service id provided.
|
||||
|
||||
@param {Object} args the object containing the service id and the content id,
|
||||
success and error callback methods
|
||||
@param {String} args.serviceid the service id that is able to process this content
|
||||
@param {String} args.contentid the content id
|
||||
@param {function} [args.callback] receives the needle answer from the "call" function
|
||||
###
|
||||
exports.getContent = ( args ) ->
|
||||
if not args.callback
|
||||
args.callback = standardCallback 'getContent'
|
||||
exports.call
|
||||
service: '2'
|
||||
method: 'get'
|
||||
data:
|
||||
id: args.contentid
|
||||
service: args.serviceid
|
||||
callback: args.callback
|
||||
|
||||
|
||||
###
|
||||
Does everything to post something in a binder
|
||||
|
||||
@param {Object} args the object containing the content
|
||||
@param {String} args.content the content to be posted
|
||||
###
|
||||
exports.newContent = ( args ) ->
|
||||
if not args.callback
|
||||
args.callback = standardCallback 'newContent'
|
||||
exports.call
|
||||
service: '27'
|
||||
method: 'save'
|
||||
data:
|
||||
companyId: params.companyId
|
||||
context: params.contextId
|
||||
text: args.content
|
||||
callback: args.callback
|
||||
|
||||
###
|
||||
Does everything to post a file info in a binder tabe
|
||||
|
||||
@param {Object} args the object containing the content
|
||||
@param {String} args.service the content service
|
||||
@param {String} args.id the content id
|
||||
###
|
||||
exports.makeFileEntry = ( args ) ->
|
||||
if not args.callback
|
||||
args.callback = standardCallback 'makeFileEntry'
|
||||
exports.getContent
|
||||
serviceid: args.service
|
||||
contentid: args.id
|
||||
callback: ( err, resp, body ) ->
|
||||
exports.call
|
||||
service: '27'
|
||||
method: 'save'
|
||||
data:
|
||||
companyId: params.companyId
|
||||
context: params.contextId
|
||||
text: "New file (#{ body.title }) in tab \"#{ body.context[0].name }\",
|
||||
find it <a href=\"https://probinder.com/file/#{ body.fileIds[0] }\">here</a>!'"
|
||||
callback: args.callback
|
||||
|
||||
###
|
||||
Sets the content as read.
|
||||
|
||||
@param {Object} args the object containing the content
|
||||
@param {String} args.content the content to be posted
|
||||
###
|
||||
exports.setRead = ( args ) ->
|
||||
if not args.callback
|
||||
args.callback = standardCallback 'setRead'
|
||||
exports.call
|
||||
service: '2'
|
||||
method: 'setread'
|
||||
data:
|
||||
id: args.id
|
||||
callback: args.callback
|
||||
26
examples/event-pollers/emailyak.coffee
Normal file
26
examples/event-pollers/emailyak.coffee
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
#
|
||||
# EmailYak EVENT POLLER
|
||||
# ---------------------
|
||||
#
|
||||
# Requires user params:
|
||||
# - apikey: The user's EmailYak API key
|
||||
#
|
||||
|
||||
url = 'https://api.emailyak.com/v1/' + params.apikey + '/json/get/new/email/'
|
||||
|
||||
exports.newMail = ( pushEvent ) ->
|
||||
|
||||
# needlereq allows the user to make calls to API's
|
||||
# Refer to https://github.com/tomas/needle for more information
|
||||
#
|
||||
# Syntax: needle.request method, url, data, [options], callback
|
||||
#
|
||||
needlereq 'get', url, null, null, ( err, resp, body ) ->
|
||||
if err
|
||||
log 'Error in EmailYak EM newMail: ' + err.message
|
||||
else
|
||||
if resp.statusCode is 200
|
||||
mails = JSON.parse( body ).Emails
|
||||
pushEvent mail for mail in mails
|
||||
|
||||
37
examples/runscript.coffee
Normal file
37
examples/runscript.coffee
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
###
|
||||
runscript.js
|
||||
------------
|
||||
|
||||
A script that helps to track errors happening durin coffee
|
||||
compilation and running of module code
|
||||
###
|
||||
|
||||
|
||||
if not process.argv[ 2 ]
|
||||
console.log 'Please provide a path to a coffee file'
|
||||
process.exit()
|
||||
|
||||
fs = require 'fs'
|
||||
vm = require 'vm'
|
||||
cs = require 'coffee-script'
|
||||
|
||||
issueApiCall = ( method, url, data, options, cb ) ->
|
||||
cb new Error 'not possible'
|
||||
|
||||
params = {}
|
||||
data = fs.readFileSync process.argv[ 2 ], 'utf8'
|
||||
src = cs.compile data
|
||||
|
||||
sandbox =
|
||||
id: 'test.vm'
|
||||
params: params
|
||||
needlereq: issueApiCall
|
||||
log: console.log
|
||||
debug: console.log
|
||||
exports: {}
|
||||
|
||||
vm.runInNewContext src, sandbox, sandbox.id
|
||||
|
||||
console.log "If no error happened until here it seems the script
|
||||
compiled and ran correctly! Congrats!"
|
||||
39
examples/runscript.js
Normal file
39
examples/runscript.js
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
// Generated by CoffeeScript 1.7.1
|
||||
(function() {
|
||||
var cs, data, fs, issueApiCall, params, sandbox, src, vm;
|
||||
|
||||
if (!process.argv[2]) {
|
||||
console.log('Please provide a path to a coffee file');
|
||||
process.exit();
|
||||
}
|
||||
|
||||
fs = require('fs');
|
||||
|
||||
vm = require('vm');
|
||||
|
||||
cs = require('coffee-script');
|
||||
|
||||
issueApiCall = function(method, url, data, options, cb) {
|
||||
return cb(new Error('not possible'));
|
||||
};
|
||||
|
||||
params = {};
|
||||
|
||||
data = fs.readFileSync(process.argv[2], 'utf8');
|
||||
|
||||
src = cs.compile(data);
|
||||
|
||||
sandbox = {
|
||||
id: 'test.vm',
|
||||
params: params,
|
||||
needlereq: issueApiCall,
|
||||
log: console.log,
|
||||
debug: console.log,
|
||||
exports: {}
|
||||
};
|
||||
|
||||
vm.runInNewContext(src, sandbox, sandbox.id);
|
||||
|
||||
console.log('If no error happened until here it seems the script compiled and ran correctly! Congrats!');
|
||||
|
||||
}).call(this);
|
||||
|
|
@ -246,7 +246,7 @@ Components Manager
|
|||
id = _ref[name];
|
||||
funcs.push(name);
|
||||
}
|
||||
_this.log.info("CM | Storing new module with functions " + (funcs.join()));
|
||||
_this.log.info("CM | Storing new module with functions " + (funcs.join(', ')));
|
||||
answ.message = " Module " + oPayload.id + " successfully stored! Found following function(s): " + funcs;
|
||||
oPayload.functions = JSON.stringify(funcs);
|
||||
dbMod.storeModule(user.username, oPayload);
|
||||
|
|
|
|||
|
|
@ -53,27 +53,22 @@ Dynamic Modules
|
|||
})(this);
|
||||
|
||||
issueApiCall = function(logger) {
|
||||
return function(method, url, credentials, cb) {
|
||||
var err, func;
|
||||
return function(method, url, data, options, cb) {
|
||||
var err;
|
||||
try {
|
||||
if (method === 'get') {
|
||||
func = needle.get;
|
||||
} else {
|
||||
func = needle.post;
|
||||
}
|
||||
return func(url, credentials, (function(_this) {
|
||||
return needle.request(method, url, data, options, (function(_this) {
|
||||
return function(err, resp, body) {
|
||||
try {
|
||||
return cb(err, resp, body);
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
return logger('Error during apicall! ' + err.message);
|
||||
return logger('Error during needle request! ' + err.message);
|
||||
}
|
||||
};
|
||||
})(this));
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
return logger('Error before apicall! ' + err.message);
|
||||
return logger('Error before needle request! ' + err.message);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
@ -114,7 +109,7 @@ Dynamic Modules
|
|||
}
|
||||
}
|
||||
fTryToLoad = function(params) {
|
||||
var logFunc, oDecrypted, sandbox;
|
||||
var logFunc, msg, oDecrypted, sandbox;
|
||||
if (params) {
|
||||
try {
|
||||
oDecrypted = cryptico.decrypt(params, _this.oPrivateRSAkey);
|
||||
|
|
@ -132,8 +127,9 @@ Dynamic Modules
|
|||
sandbox = {
|
||||
id: userId + '.' + modId + '.vm',
|
||||
params: params,
|
||||
apicall: issueApiCall(logFunc),
|
||||
needlereq: issueApiCall(logFunc),
|
||||
log: logFunc,
|
||||
debug: console.log,
|
||||
exports: {}
|
||||
};
|
||||
try {
|
||||
|
|
@ -141,7 +137,11 @@ Dynamic Modules
|
|||
} catch (_error) {
|
||||
err = _error;
|
||||
answ.code = 400;
|
||||
answ.message = 'Loading Module failed: ' + err.message;
|
||||
msg = err.message;
|
||||
if (!msg) {
|
||||
msg = 'Try to run the script locally to track the error! Sadly we cannot provide the line number';
|
||||
}
|
||||
answ.message = 'Loading Module failed: ' + msg;
|
||||
}
|
||||
return cb({
|
||||
answ: answ,
|
||||
|
|
|
|||
|
|
@ -1,55 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
/*
|
||||
* EmailYak EVENT MODULE
|
||||
*/
|
||||
|
||||
var credentials = null;
|
||||
|
||||
function loadCredentials(cred) {
|
||||
if(!cred || !cred.key) {
|
||||
console.error('ERROR in EmailYak EM: credentials file corrupt');
|
||||
} else {
|
||||
credentials = cred;
|
||||
console.log('Successfully loaded EmailYak EM credentials');
|
||||
}
|
||||
}
|
||||
|
||||
//FIXME every second mail gets lost?
|
||||
// 1) for http.request options, set Connection:keep-alive
|
||||
// 2) set Agent.maxSockets = 1024 (so more connection to play around
|
||||
// with )
|
||||
// 3) very critical: DO a timeout for the http.request.
|
||||
//
|
||||
// e.g.
|
||||
// var responseHdr = function (clientResponse) {
|
||||
// if (clientResposne) {
|
||||
//
|
||||
// } else {
|
||||
// clientRequest.abort();
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// var timeoutHdr = setTimeout(function() {
|
||||
// clientRequest.emit('req-timeout');
|
||||
// }, 5000); // timeout after 5 secs
|
||||
//
|
||||
// clientRequest.on("req-timeout", responseHdr);
|
||||
// clientRequest.on('error', function(e) {
|
||||
// clearTimeout(timeoutHdr);
|
||||
// console.error('Ok.. clientrequest error' + myCounter);
|
||||
// next({err:JSON.stringify(e)});
|
||||
// });
|
||||
function newMail(callback) { //FIXME not beautiful to have to set prop each time here
|
||||
needle.get('https://api.emailyak.com/v1/' + credentials.key + '/json/get/new/email/',
|
||||
function (error, response, body){
|
||||
if (!error && response.statusCode == 200) {
|
||||
var mails = JSON.parse(body).Emails;
|
||||
for(var i = 0; i < mails.length; i++) callback(mails[i]);
|
||||
} else console.error('ERROR in EmailYak EM newMail: ' + error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
exports.loadCredentials = loadCredentials;
|
||||
exports.newMail = newMail;
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
[
|
||||
{
|
||||
"id": "rule_1",
|
||||
"event": "mail",
|
||||
"actions": [
|
||||
{
|
||||
"module": "probinder->newContent",
|
||||
"arguments": {
|
||||
"content": "Rule#1: $X.subject"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "rule_2",
|
||||
"event": "mail",
|
||||
"condition": { "sender": "sender2" },
|
||||
"actions": [
|
||||
{
|
||||
"module": "probinder->newContent",
|
||||
"arguments": {
|
||||
"content": "Rule#2: $X.subject"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "rule_emailyak",
|
||||
"event": "yakmail",
|
||||
"condition": { "FromAddress": "dominic.bosch.db@gmail.com" },
|
||||
"actions": [
|
||||
{
|
||||
"module": "probinder->newContent",
|
||||
"arguments": {
|
||||
"content": "Received from EmailYak: $X.textbody"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "rule_pull_emailyak",
|
||||
"event": "emailyak->newMail",
|
||||
"condition": { "FromAddress": "dominic.bosch.db@gmail.com" },
|
||||
"actions": [
|
||||
{
|
||||
"module": "probinder->newContent",
|
||||
"arguments": {
|
||||
"content": "Received from EmailYak: $X.textbody"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "rule_pull_probinder",
|
||||
"event": "probinder->unread",
|
||||
"condition": { "serviceId": "32" },
|
||||
"actions": [
|
||||
{
|
||||
"module": "probinder->makeFileEntry",
|
||||
"arguments": {
|
||||
"service": "$X.serviceId",
|
||||
"id": "$X.id"
|
||||
}
|
||||
},
|
||||
{
|
||||
"module": "probinder->setRead",
|
||||
"arguments": {
|
||||
"id": "$X.id"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
@ -16,7 +16,7 @@ fOnLoad = () ->
|
|||
# editor.session.setUseSoftTabs false
|
||||
|
||||
document.title = 'Rule Forge!'
|
||||
$( '#pagetitle' ).text '{{{user.username}}}, forge your rule!'
|
||||
$( '#pagetitle' ).text '{{{user.username}}}, forge your ECA Rule!'
|
||||
|
||||
# Fetch Event Poller user-specific parameters
|
||||
fFetchEventParams = ( name ) ->
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
editor.getSession().setMode("ace/mode/json");
|
||||
editor.setShowPrintMargin(false);
|
||||
document.title = 'Rule Forge!';
|
||||
$('#pagetitle').text('{{{user.username}}}, forge your rule!');
|
||||
$('#pagetitle').text('{{{user.username}}}, forge your ECA Rule!');
|
||||
fFetchEventParams = function(name) {
|
||||
var arr, obj;
|
||||
if (name) {
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
<link href='http://fonts.googleapis.com/css?family=Roboto:300' rel='stylesheet' type='text/css'>
|
||||
<link href='http://fonts.googleapis.com/css?family=Nunito' rel='stylesheet' type='text/css'>
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<script src='//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js' type='text/javascript'></script>
|
||||
<script src='http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js' type='text/javascript'></script>
|
||||
<script type='text/javascript'>
|
||||
var checkIncludes = function () {
|
||||
if( window.$ === undefined ) {
|
||||
|
|
@ -23,6 +25,7 @@
|
|||
{{{menubar}}}
|
||||
<div id="info"></div>
|
||||
<div id="mainbody">
|
||||
<p></p>
|
||||
<div id="pagetitle"></div>
|
||||
{{{content}}}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -7,38 +7,147 @@ Action Invoker Name: <input id="input_id" type="text" />
|
|||
<tr>
|
||||
<td id="editor_col" valign="top">
|
||||
<div id="editor">
|
||||
#
|
||||
# ProBinder Action Invoker
|
||||
#
|
||||
# Action Invoker requires user params:
|
||||
# - username: The ProBinder login username
|
||||
# - password: The ProBinder login password
|
||||
#
|
||||
###
|
||||
ProBinder ACTION INVOKER
|
||||
------------------------
|
||||
|
||||
Global variables
|
||||
This module requires user-specific parameters:
|
||||
- username
|
||||
- password
|
||||
- companyId: company where to post the binder entries
|
||||
- contextId: context where to post the binder entries
|
||||
###
|
||||
urlService = 'https://probinder.com/service/'
|
||||
credentials =
|
||||
username: params.username
|
||||
password: params.password
|
||||
|
||||
#
|
||||
# createBinderEntry function requires arguments:
|
||||
# The standard callback can be used if callback is not provided, e.g. if
|
||||
# the function is called from outside
|
||||
#
|
||||
# - company: The ProBidner company of the binder
|
||||
# - context: The ProBinder context (the binder ID)
|
||||
#
|
||||
exports.createBinderEntry = ( evt ) ->
|
||||
url = 'https://probinder.com/service/27/save'
|
||||
|
||||
credentials =
|
||||
username: params.username
|
||||
password: params.password
|
||||
|
||||
data =
|
||||
companyId: evt.company
|
||||
context: evt.context
|
||||
text: evt.content
|
||||
|
||||
needle.post url, data, credentials, ( err, resp, body ) ->
|
||||
standardCallback = ( funcName ) ->
|
||||
( err, resp, body ) ->
|
||||
if err
|
||||
log err
|
||||
if resp.statusCode isnt 200
|
||||
log 'Request not successful:'
|
||||
log body
|
||||
log "ERROR: During function '#{ funcName }'"
|
||||
else
|
||||
if resp.statusCode is 200
|
||||
log "Function '#{ funcName }' ran through without error"
|
||||
else
|
||||
log "ERROR: During function '#{ funcName }': #{ body.error.message }"
|
||||
|
||||
###
|
||||
Call the ProBinder service with the given parameters.
|
||||
|
||||
@param {Object} args the required function arguments object
|
||||
@param {Object} [args.data] the data to be posted
|
||||
@param {String} args.service the required service identifier to be appended to the url
|
||||
@param {String} args.method the required method identifier to be appended to the url
|
||||
@param {function} [args.callback] the function to receive the request answer
|
||||
###
|
||||
exports.call = ( args ) ->
|
||||
if not args.service or not args.method
|
||||
log 'ERROR in call function: Missing arguments!'
|
||||
else
|
||||
if not args.callback
|
||||
args.callback = standardCallback 'call'
|
||||
url = urlService + args.service + '/' + args.method
|
||||
needlereq 'post', url, args.data, credentials, args.callback
|
||||
|
||||
###
|
||||
Calls the user's unread content service.
|
||||
|
||||
@param {Object} [args] the optional object containing the callback function
|
||||
@param {function} [args.callback] refer to call function
|
||||
###
|
||||
exports.getUnreadContents = ( args ) ->
|
||||
if not args.callback
|
||||
args.callback = standardCallback 'getUnreadContents'
|
||||
exports.call
|
||||
service: '36'
|
||||
method: 'unreadcontent'
|
||||
callback: args.callback
|
||||
|
||||
|
||||
###
|
||||
Calls the content get service with the content id and the service id provided.
|
||||
|
||||
@param {Object} args the object containing the service id and the content id,
|
||||
success and error callback methods
|
||||
@param {String} args.serviceid the service id that is able to process this content
|
||||
@param {String} args.contentid the content id
|
||||
@param {function} [args.callback] receives the needle answer from the "call" function
|
||||
###
|
||||
exports.getContent = ( args ) ->
|
||||
if not args.callback
|
||||
args.callback = standardCallback 'getContent'
|
||||
exports.call
|
||||
service: '2'
|
||||
method: 'get'
|
||||
data:
|
||||
id: args.contentid
|
||||
service: args.serviceid
|
||||
callback: args.callback
|
||||
|
||||
|
||||
###
|
||||
Does everything to post something in a binder
|
||||
|
||||
@param {Object} args the object containing the content
|
||||
@param {String} args.content the content to be posted
|
||||
###
|
||||
exports.newContent = ( args ) ->
|
||||
if not args.callback
|
||||
args.callback = standardCallback 'newContent'
|
||||
exports.call
|
||||
service: '27'
|
||||
method: 'save'
|
||||
data:
|
||||
companyId: params.companyId
|
||||
context: params.contextId
|
||||
text: args.content
|
||||
callback: args.callback
|
||||
|
||||
###
|
||||
Does everything to post a file info in a binder tabe
|
||||
|
||||
@param {Object} args the object containing the content
|
||||
@param {String} args.service the content service
|
||||
@param {String} args.id the content id
|
||||
###
|
||||
exports.makeFileEntry = ( args ) ->
|
||||
if not args.callback
|
||||
args.callback = standardCallback 'makeFileEntry'
|
||||
exports.getContent
|
||||
serviceid: args.service
|
||||
contentid: args.id
|
||||
callback: ( err, resp, body ) ->
|
||||
exports.call
|
||||
service: '27'
|
||||
method: 'save'
|
||||
data:
|
||||
companyId: params.companyId
|
||||
context: params.contextId
|
||||
text: "New file (#{ body.title }) in tab \"#{ body.context[0].name }\",
|
||||
find it <a href=\"https://probinder.com/file/#{ body.fileIds[0] }\">here</a>!'"
|
||||
callback: args.callback
|
||||
|
||||
###
|
||||
Sets the content as read.
|
||||
|
||||
@param {Object} args the object containing the content
|
||||
@param {String} args.content the content to be posted
|
||||
###
|
||||
exports.setRead = ( args ) ->
|
||||
if not args.callback
|
||||
args.callback = standardCallback 'setRead'
|
||||
exports.call
|
||||
service: '2'
|
||||
method: 'setread'
|
||||
data:
|
||||
id: args.id
|
||||
callback: args.callback
|
||||
</div>
|
||||
<button id="but_submit">save</button>
|
||||
</td>
|
||||
|
|
@ -53,6 +162,14 @@ This action invoker requires user-specific properties:
|
|||
<td><img src="red_cross_small.png"></td>
|
||||
<td><input type="text" value="password" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="red_cross_small.png"></td>
|
||||
<td><input type="text" value="companyId" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="red_cross_small.png"></td>
|
||||
<td><input type="text" value="contextId" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="red_cross_small.png"></td>
|
||||
<td><input type="text" /></td>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ Event Poller Name: <input id="input_id" type="text" />
|
|||
<div id="editor">
|
||||
#
|
||||
# EmailYak EVENT POLLER
|
||||
# ---------------------
|
||||
#
|
||||
# Requires user params:
|
||||
# - apikey: The user's EmailYak API key
|
||||
|
|
@ -17,13 +18,19 @@ Event Poller Name: <input id="input_id" type="text" />
|
|||
url = 'https://api.emailyak.com/v1/' + params.apikey + '/json/get/new/email/'
|
||||
|
||||
exports.newMail = ( pushEvent ) ->
|
||||
needle.get url, ( err, resp, body ) ->
|
||||
if not err and resp.statusCode is 200
|
||||
mails = JSON.parse( body ).Emails
|
||||
pushEvent mail for mail in mails
|
||||
else
|
||||
log.error 'Error in EmailYak EM newMail: ' + err.message
|
||||
|
||||
# needlereq allows the user to make calls to API's
|
||||
# Refer to https://github.com/tomas/needle for more information
|
||||
#
|
||||
# Syntax: needle.request method, url, data, [options], callback
|
||||
#
|
||||
needlereq 'get', url, null, null, ( err, resp, body ) ->
|
||||
if err
|
||||
log 'Error in EmailYak EM newMail: ' + err.message
|
||||
else
|
||||
if resp.statusCode is 200
|
||||
mails = JSON.parse( body ).Emails
|
||||
pushEvent mail for mail in mails
|
||||
</div>
|
||||
<button id="but_submit">save</button>
|
||||
</td>
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
fCreateLink( 'Edit Modules',
|
||||
fRedirect( 'forge?page=edit_modules' )
|
||||
);
|
||||
fCreateLink( 'Edit rules',
|
||||
fCreateLink( 'Edit Rules',
|
||||
fRedirect( 'forge?page=edit_rules' )
|
||||
);
|
||||
// fCreateLink( 'admin', fRedirect( 'admin' ) );
|
||||
|
|
|
|||
61
webpages/public/index.html
Normal file
61
webpages/public/index.html
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
<link href='http://fonts.googleapis.com/css?family=Roboto:300' rel='stylesheet' type='text/css'>
|
||||
<link href='http://fonts.googleapis.com/css?family=Nunito' rel='stylesheet' type='text/css'>
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<script src='http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js' type='text/javascript'></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="menubar">
|
||||
<script>
|
||||
var menubar = $( '#menubar' );
|
||||
|
||||
var fRedirect = function( url ) {
|
||||
return function() {
|
||||
window.location.href = url;
|
||||
}
|
||||
};
|
||||
|
||||
var fCreateLink = function( text, fAction ) {
|
||||
var link = $( '<div>' ).text( text );
|
||||
link.click( fAction );
|
||||
menubar.append(link);
|
||||
};
|
||||
|
||||
fCreateLink( 'Forge Event Poller',
|
||||
fRedirect( 'forge?page=forge_event_poller' )
|
||||
);
|
||||
fCreateLink( 'Forge Action Invoker',
|
||||
fRedirect( 'forge?page=forge_action_invoker' )
|
||||
);
|
||||
fCreateLink( 'Forge Rule',
|
||||
fRedirect( 'forge?page=forge_rule' )
|
||||
);
|
||||
fCreateLink( 'Invoke Event',
|
||||
fRedirect( 'forge?page=forge_event' )
|
||||
);
|
||||
fCreateLink( 'Edit Modules',
|
||||
fRedirect( 'forge?page=edit_modules' )
|
||||
);
|
||||
fCreateLink( 'Edit Rules',
|
||||
fRedirect( 'forge?page=edit_rules' )
|
||||
);
|
||||
fCreateLink( 'Logout', function() {
|
||||
$.post( '/logout' ).done( fRedirect( document.URL ) );
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<div id="info"></div>
|
||||
<div id="mainbody">
|
||||
<p></p>
|
||||
|
||||
<div id="pagetitle">Welcome to the WebAPI ECA-Engine!</div>
|
||||
<p>
|
||||
Enjoy creating your own ECA rules, together with the required action invoker modules!
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
body {
|
||||
font-family: sans-serif, "Times New Roman", Georgia, Serif;
|
||||
font-size: 80%;
|
||||
font-family: 'Roboto', sans-serif, "Times New Roman", Georgia, Serif;
|
||||
/*font-size: 0.9em;*/
|
||||
margin: 0px;
|
||||
background-color: #EEF;
|
||||
}
|
||||
|
|
@ -75,7 +75,7 @@ input[type=text]:focus {
|
|||
}
|
||||
|
||||
#pagetitle {
|
||||
font-size: 1.5em;
|
||||
font-size: 2em;
|
||||
font-weight: bold;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
|
|
|
|||
Loading…
Reference in a new issue