Skip to content

Instantly share code, notes, and snippets.

@taf2
Last active August 24, 2020 15:13
Show Gist options
  • Save taf2/95161636995c5b2a5cdf6106c1da6fae to your computer and use it in GitHub Desktop.
Save taf2/95161636995c5b2a5cdf6106c1da6fae to your computer and use it in GitHub Desktop.
Salesforce - Query for custom field picker in CallTrackingmetrics.
/*
Usage:
Configure in Variables the objects and their properties you want to search.
The properties must include an Id and Name. Optionally you can include an Email property.
You can use https://app.calltrackingmetrics.com/salesforce/object_attributes.json?object=<insert your object type here>
to discover the internal names for your Object's properties.
You'll want to configure a custom field picker that instead of using fixed values uses this to query salesforce. Presenting
to your agents a list of objectst hat might be related to your current activity.
*/
const jsforce = require('jsforce');
function phoneQuery(number, objects) {
let digits = number.replace(/\D/g,'').split("");
if (digits.length > 10) {
let country_code = digits.shift();
}
let npa = [];
npa.push(digits.shift());
npa.push(digits.shift());
npa.push(digits.shift());
npa = npa.join("");
let nxx = [];
nxx.push(digits.shift());
nxx.push(digits.shift());
nxx.push(digits.shift());
nxx = nxx.join("");
let lnumber = digits.join("");
//console.log("npa: " + npa + ", nxx:" + nxx + ", lnum:" + lnumber);
const search_number = [npa, nxx, lnumber].join("*");
return `FIND {${search_number}} IN PHONE FIELDS RETURNING ${objects}`;
}
exports.handler = function(event, context, callback) {
const conn = new jsforce.Connection({
instanceUrl : event.salesforce.instanceUrl,
accessToken : event.salesforce.token
});
const objects = process.env.Object.split("|").join(',');
const callId = event.activity.id;
// the pickers for custom fields will pass an options.input as the user input for the search
let searchQuery = event.options.input;
let sosl = null;
if (searchQuery && searchQuery.replace(/\D/g,'').length > 8) {
// removing all format characters the input is long enough to be a phone number try querying for numbers
sosl = phoneQuery(searchQuery.replace(/\D/g,''), objects)
} else {
// maybe we're looking for a name or maybe they did not provide us with any inputs
if (searchQuery && searchQuery.length) {
// ok maybe they want us to search by name
sosl = `FIND {${searchQuery}} IN NAME FIELDS RETURNING ${objects}`;
} else {
// ok we're doing a default query by phone number
let number = event.activity.caller_number;// convert to a searchable string
sosl = phoneQuery(number.replace(/\D/g,''), objects)
}
}
//console.log(sosl);
conn.search(sosl,
function(err, res) {
if (err) { console.log("error:", err); context.done(); return; }
//console.log("call id:" + callId);
const results = res.searchRecords.map( (r) => {
// guess each object type by name...
const attrs = r.attributes;
delete r.attributes;
const fields = Object.keys(r);
const emailField = fields.filter( (k) => { return k.match(/email/i); })[0];
const nameField = fields.filter( (k) => { return k.match(/name/i); })[0];
let email = null;
let name = null;
if (emailField) {
email = r[emailField];
}
if (nameField) {
name = r[nameField];
}
return {text: `<i>${attrs.type}</i>- ${name} <small>${email ? email : ''}</small>`, id: r.Id};
});
//console.log(results);
if (!results.length) {
// add 1 empty result so enduser can always type another search query
results.push({text: "no matches", id: null});
}
context.done(null, { results: results });
}
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment