findContactWithName
It is not uncommon that when logging a call, a contact cannot be found using the findContact interface which attempts to lookup a contact into the target CRM via a phone number. Sometimes however, a contact cannot be found, but is in fact known to be in the CRM. This is when this interface comes into play.
When a contact cannot be found, users are given the option to search the CRM for a contact by name. This allows users to associate calls with contacts in a more manual fashion when a contact is not found via a phone number.
This interface is called to facilitate that search process.
Request parameters
Parameter | Description |
---|---|
user |
An object describing the Chrome extension user associated with the action that triggered this interface. |
authHeader |
The HTTP Authorization header to be transmitted with the API request to the target CRM. |
name |
The text entered by the user that should be searched for within the CRM. |
Return value(s)
This interface returns a single object. That object describes the contacts that were found. It has following properties:
Parameter | Description |
---|---|
successful |
True or false is a contact was found or not. |
matchedContactInfo |
An array of objects containing id , name and optionally additionalInfo and isNewContact . |
extraDataTracking |
Information relating to rate limited, if applicable. |
Example
{
successful: true,
matchedContactInfo:[
{
id: 'contact id',
name: 'John Doe',
phone: '(123) 456-7890',
type: 'Lead',
additionalInfo: null,
isNewContact: false
}
],
extraDataTracking: {
ratelimitRemaining: null,
ratelimitAmount: null,
ratelimitReset: null
}
}
Reference
async function findContactWithName({ user, authHeader, name }) {
const matchedContactInfo = [];
let extraDataTracking = {};
/*
Clio's contact search functionality works correctly with name-based queries, including first name, last name, and full name.
It handles all variations without requiring the query to be split
*/
const personInfo = await axios.get(`https://${user.hostname}/api/v4/contacts.json?type=Person&query=${name}&fields=id,name,title,company,primary_phone_number`, {
headers: { 'Authorization': authHeader }
});
extraDataTracking = {
ratelimitRemaining: personInfo.headers['x-ratelimit-remaining'],
ratelimitAmount: personInfo.headers['x-ratelimit-limit'],
ratelimitReset: personInfo.headers['x-ratelimit-reset']
};
if (personInfo.data.data.length > 0) {
for (var result of personInfo.data.data) {
const matterInfo = await axios.get(
`https://${user.hostname}/api/v4/matters.json?client_id=${result.id}&fields=id,display_number,description,status`,
{
headers: { 'Authorization': authHeader }
});
let matters = matterInfo.data.data.length > 0 ? matterInfo.data.data.map(m => { return { const: m.id, title: m.display_number, description: m.description, status: m.status } }) : null;
matters = matters?.filter(m => m.status !== 'Closed');
let associatedMatterInfo = await axios.get(
`https://${user.hostname}/api/v4/relationships.json?contact_id=${result.id}&fields=matter{id,display_number,description,status}`,
{
headers: { 'Authorization': authHeader }
});
extraDataTracking = {
ratelimitRemaining: associatedMatterInfo.headers['x-ratelimit-remaining'],
ratelimitAmount: associatedMatterInfo.headers['x-ratelimit-limit'],
ratelimitReset: associatedMatterInfo.headers['x-ratelimit-reset']
};
let associatedMatters = associatedMatterInfo.data.data.length > 0 ? associatedMatterInfo.data.data.map(m => { return { const: m.matter.id, title: m.matter.display_number, description: m.matter.description, status: m.matter.status } }) : null;
associatedMatters = associatedMatters?.filter(m => m.status !== 'Closed');
let returnedMatters = [];
returnedMatters = returnedMatters.concat(matters ?? []);
returnedMatters = returnedMatters.concat(associatedMatters ?? []);
matchedContactInfo.push({
id: result.id,
name: result.name,
title: result.title ?? "",
type: 'contact',
company: result.company?.name ?? "",
phone: result.primary_phone_number ?? "",
additionalInfo: returnedMatters.length > 0 ?
{
matters: returnedMatters,
logTimeEntry: user.userSettings?.clioDefaultTimeEntryTick ?? true,
nonBillable: user.userSettings?.clioDefaultNonBillableTick ?? false
} :
{
logTimeEntry: user.userSettings?.clioDefaultTimeEntryTick ?? true
}
})
}
}
return {
successful: true,
matchedContactInfo,
extraDataTracking
}
}