createCallLog
This interface is responsible for creating a new call log record in the associated CRM. The call must be associated with the contact passed in as a request parameter. Other associations may be made depending upon the CRM and the connector.
There is an underlying assumption of the framework that there is a one-to-one mapping between notes (or activities) and phone calls. Therefore, when logging a call in the target CRM only create a single log entry.
Input parameters
| Parameter | Description |
|---|---|
user |
An object describing the Chrome extension user associated with the action that triggered this interface. |
contactInfo |
An associative array describing the contact a call is associated with. |
authHeader |
The HTTP Authorization header to be transmitted with the API request to the target CRM. |
callLog |
All the metadata associated with the call to be logged. Call Log schema is described in our API Reference. |
note |
The notes saved by the user during and/or after the call. |
additionalSubmission |
All of the additional custom fields defined in the manifest and submitted by the user. |
aiNote |
AI summary of the phone call |
transcript |
Transcript of the phone call |
composedLogDetails |
Formated log details that can be directly put into log body |
Contact Info
{
id: "<string">,
type: "<string>",
phoneNumber: "<E.164 Phone Number>",
name: "<string>"
}
Return value(s)
An object with following properties:
| Parameter | Description |
|---|---|
logId |
ID of the log entry created within the CRM |
returnMessage |
message, messageType and ttl |
Example
return {
logId: "xxx-xxxxx", // ID of log entity on CRM platform
returnMessage:{
message: 'Call logged',
messageType: 'success', // 'success', 'warning' or 'danger'
ttl: 30000 // in miliseconds
}
}
Reference
// callLog: same as in https://developers.ringcentral.com/api-reference/Call-Log/readUserCallRecord
async function createCallLog({ user, contactInfo, authHeader, callLog, note, additionalSubmission, aiNote, transcript, composedLogDetails }) {
console.log(`adding call log... \n${JSON.stringify(callLog, null, 2)}`);
console.log(`body... \n${composedLogDetails}`);
console.log(`with additional info... \n${JSON.stringify(additionalSubmission, null, 2)}`);
const newCallLog = {
id: `CRM log id ${Date.now()}`,
subject: callLog.customSubject,
note: composedLogDetails,
contactName: contactInfo.name
}
// Using mock JSON as CRM response
const fs = require('fs');
const path = require('path');
const mockCallLogsPath = path.join(__dirname, '..', 'mockCallLogs.json');
const mockCallLogs = require(mockCallLogsPath);
mockCallLogs.push(newCallLog);
fs.writeFileSync(mockCallLogsPath, JSON.stringify(mockCallLogs, null, 2));
//----------------------------------------------------------------------------------
//--- CHECK: In extension, try create a new call log against an unknown contact ----
//----------------------------------------------------------------------------------
//--------------------------------------
//--- TODO: Add CRM API call here ------
//--- TODO: Delete above mock JSON -----
//--------------------------------------
// const postBody = {
// subject: callLog.customSubject ?? `[Call] ${callLog.direction} Call ${callLog.direction === 'Outbound' ? 'to' : 'from'} ${contactInfo.name} [${contactInfo.phone}]`,
// body: composedLogDetails,
// type: 'PhoneCommunication',
// received_at: moment(callLog.startTime).toISOString()
// }
// const addLogRes = await axios.post(
// `https://api.crm.com/activity`,
// postBody,
// {
// headers: { 'Authorization': authHeader }
// });
return {
logId: newCallLog.id,
returnMessage: {
message: 'Call logged',
messageType: 'success',
ttl: 2000
}
};
}
module.exports = createCallLog;
async function createCallLog({ user, contactInfo, authHeader, callLog, note, additionalSubmission, aiNote, transcript, composedLogDetails, hashedAccountId }) {
const dealId = additionalSubmission ? additionalSubmission.deals : '';
const leadId = additionalSubmission ? additionalSubmission.leads : '';
const personResponse = await axios.get(`https://${user.hostname}/api/v2/persons/${contactInfo.id}`, { headers: { 'Authorization': authHeader } });
const orgId = personResponse.data.data.org_id ?? '';
const timeUtc = moment(callLog.startTime).utcOffset(0).format('HH:mm')
const dateUtc = moment(callLog.startTime).utcOffset(0).format('YYYY-MM-DD');
let extraDataTracking = {
withSmartNoteLog: !!aiNote && (user.userSettings?.addCallLogAiNote?.value ?? true),
withTranscript: !!transcript && (user.userSettings?.addCallLogTranscript?.value ?? true)
};
let assigneeId = null;
if (additionalSubmission?.isAssignedToUser) {
if (additionalSubmission.adminAssignedUserToken) {
try {
const unAuthData = jwt.decodeJwt(additionalSubmission.adminAssignedUserToken);
const assigneeUser = await UserModel.findByPk(unAuthData.id);
if (assigneeUser) {
assigneeId = assigneeUser.platformAdditionalInfo.id;
}
}
catch (e) {
console.log('Error decoding admin assigned user token', e);
}
}
if (!assigneeId) {
const adminConfig = await AdminConfigModel.findByPk(hashedAccountId);
assigneeId = adminConfig.userMappings?.find(mapping => typeof (mapping.rcExtensionId) === 'string' ? mapping.rcExtensionId == additionalSubmission.adminAssignedUserRcId : mapping.rcExtensionId.includes(additionalSubmission.adminAssignedUserRcId))?.crmUserId;
}
}
const postBody = {
owner_id: Number(user.id.split('-')[0]),
subject: callLog.customSubject ?? `${callLog.direction} Call ${callLog.direction === 'Outbound' ? 'to' : 'from'} ${contactInfo.name}`,
duration: secondsToHoursMinutesSecondsInPipedriveFormat(callLog.duration), // secs
deal_id: dealId,
note: composedLogDetails,
done: true,
due_date: dateUtc,
due_time: timeUtc,
participants: [
{
person_id: Number(contactInfo.id),
primary: true
}
]
}
if (!dealId && leadId) {
postBody.lead_id = leadId;
}
if (orgId) {
postBody.org_id = orgId;
}
if (assigneeId) {
postBody.owner_id = Number(assigneeId);
}
const addLogRes = await axios.post(
`https://${user.hostname}/api/v2/activities`,
postBody,
{
headers: { 'Authorization': authHeader }
});
extraDataTracking = {
ratelimitRemaining: addLogRes.headers['x-ratelimit-remaining'],
ratelimitAmount: addLogRes.headers['x-ratelimit-limit'],
ratelimitReset: addLogRes.headers['x-ratelimit-reset']
};
return {
logId: addLogRes.data.data.id,
returnMessage: {
message: 'Call logged',
messageType: 'success',
ttl: 2000
},
extraDataTracking
};
}
Example Call Log Schema
{
"uri" : "https://platform.ringcentral.com/restapi/v1.0/account/1477535004/extension/1477535004/call-log/X2AvJPtwNQbNQA?view=Detailed",
"id" : "X2AvJPtwNQbNQA",
"sessionId" : "4503991004",
"telephonySessionId": "s-9a03590172ea4d39a7cf7d5b6dba6a3b",
"startTime" : "2018-09-11T13:24:09.000Z",
"duration" : 7,
"type" : "Voice",
"direction" : "Inbound",
"action" : "Phone Call",
"result" : "Accepted",
"to" : {
"phoneNumber" : "+18662019834",
"name" : "Jane Smith"
},
"from" : {
"phoneNumber" : "+16504445566",
"name" : "John Smith",
"location" : "Palo Alto, CA"
},
"extension" : {
"uri" : "https://platform.ringcentral.com/restapi/v1.0/account/1477535004/extension/1477535004",
"id" : 1477535004
},
"transport" : "PSTN",
"lastModifiedTime" : "2018-09-11T13:24:12.003Z",
"billing" : {
"costIncluded" : 0.000,
"costPurchased" : 0.000
},
"legs" : [ {
"startTime" : "2018-09-11T13:24:09.000Z",
"duration" : 7,
"type" : "Voice",
"direction" : "Inbound",
"action" : "Phone Call",
"result" : "Accepted",
"to" : {
"phoneNumber" : "+18662019834",
"name" : "Jane Smith"
},
"from" : {
"phoneNumber" : "+16504445566",
"name" : "John Smith",
"location" : "Palo Alto, CA"
},
"extension" : {
"uri" : "https://platform.ringcentral.com/restapi/v1.0/account/1477535004/extension/1477535004",
"id" : 1477535004
},
"transport" : "PSTN",
"legType" : "Accept",
"master" : true
} ]
}