Skip to content

Instantly share code, notes, and snippets.

@gotjoshua
Last active November 26, 2024 12:42
Show Gist options
  • Save gotjoshua/a9df1be322a65d3d8b4130f674b710ea to your computer and use it in GitHub Desktop.
Save gotjoshua/a9df1be322a65d3d8b4130f674b710ea to your computer and use it in GitHub Desktop.
civi v3
// ripped/forked from:
// https://raw.githubusercontent.com/TechToThePeople/node-civicrm/c0056935e9309865dad1ec533f0473f61395d0a3/civicrm.js
import request from 'npm:request';
import qs from 'npm:qs';
import _ from 'npm:underscore';
import async from 'npm:async';
var p:any // needed to fork the whole stupid v3 js sdk so i could add this line
/*
ex:
var config = {
server:'http://example.org',
path:'/sites/all/modules/civicrm/extern/rest.php',
key:'your key from settings.civicrm.php',
api_key:'the user key'
};
*/
export var crmAPI = function civicrm(options) {
this.options = {
path: '/sites/all/modules/civicrm/extern/rest.php',
sequential: 1,
json: 1,
debug: false,
concurrency: 8, // max number of queries to run in parallel
};
_.extend(this.options, options);
this.queue = async.queue(function (query, callback) {
p.directcall.call(query.this, query.entity, query.action, query.params, function (r) {
callback();
query.callback(r);
});
//function (data) {callback(data)});
//process.nextTick();
/*
if (r.is_error) {
if (r.sql && r.sql.indexOf("nativecode=1213") !== -1) {
console.log("deadlock, retry");
this.call (query.entity,query.action,query.params,function(r){callback();query.callback(r)});
});
} else {
callback();
}
} else {
callback();
}
});
*/
}, this.options.concurrency);
};
p = crmAPI.prototype;
p.urlize = function (entity, action) {
return this.options.server + this.options.path + '?' + qs.stringify({
entity: entity,
action: action,
});
}
p.debug = function (enable) {
this.options.debug = enable || true;
}
p.directcall = function (entity, action, params, callback) {
var post = _.clone(this.options);
delete post['action'];
delete post['entity'];
delete post['server'];
delete post['path'];
delete post['concurrency'];
if (typeof (params) === "object") {
if (Object.keys(params).some(function (key) { //if chained api calls, transform in json
return (typeof params[key] == "object");
})) {
post.json = JSON.stringify(params);
} else {
_.extend(post, params);
}
} else {
post.id = params;
}
var uri = this.urlize(entity, action);
var t = {};
var debug = this.options.debug;
if (debug)
console.log("->api." + entity + "." + action + " " + JSON.stringify(params));
request.post({
uri: uri,
form: post
}
, function (error, response, body) {
if (error) {
t = { is_error: 1, error_message: error };
callback(t);
return;
}
if (debug)
console.log(" <-" + response.statusCode + " api." + entity + "." + action + " " + JSON.stringify(params));
if (!error && response.statusCode == 200) {
try {
t = JSON.parse(body);
} catch (e) {
t = { is_error: 1, error_message: "couldn't parse " + body };
// callback ({is_error:1,error_message:"couldn't parse "+body});
return;
} finally {
callback(t);
}
} else {
if (response.statusCode >= 500 && response.statusCode < 600) { // 50x error, let's retry once
request.post({ uri: uri, form: post }
, function (error, response, body) {
if (!error && response.statusCode == 200) {
try {
callback(JSON.parse(body));
} catch (e) {
callback({ is_error: 1, error_message: "couldn't parse " + body }); return;
}
} else {
callback({ is_error: 1, http_code: response.statusCode, error_message: 'http error ' + uri, error_code: 'http_' + response.statusCode, uri: uri, values: [] }); return;
}
})
.on('error', function (err) {
t = { is_error: 1, error_message: error };
callback(t);
});
} else {
callback({ is_error: 1, http_code: response.statusCode, error_message: 'http error ' + uri, error_code: 'http_' + response.statusCode, uri: uri, values: [] });
}
}
})
};
p.call = function (entity, action, params, callback) {
this.queue.push({ this: this, entity: entity, action: action, params: params, callback: callback });
}
p.get = function (entity, params, callback) {
// this.queue.push({entity:entity, action:"get",params:params,callback:callback});
this.call(entity, 'get', params, callback);
}
p.getSingle = function (entity, params, callback) {
this.call(entity, 'getsingle', params, callback);
}
p.getQuick = function (entity, params, callback) {
this.call(entity, 'getquick', params, callback);
}
p.create = function (entity, params, callback) {
this.call(entity, 'create', params, callback);
}
p.update = function (entity, params, callback) {
// todo, test if params.id is set
this.call(entity, 'create', params, callback);
}
p.delete = function (entity, params, callback) {
this.call(entity, 'delete', params, callback);
}
export const crm3 = function (options) {
return new crmAPI(options);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment