CtrlK
BlogDocsLog inGet started
Tessl Logo

call-log-composition

Use this skill when working with call log composition, formatting call details, handling AI notes, transcripts, and understanding the call log flow in App Connect.

67

1.87x
Quality

52%

Does it follow best practices?

Impact

92%

1.87x

Average score across 3 eval scenarios

SecuritybySnyk

Passed

No known issues

Optimize this skill with Tessl

npx tessl skill review --optimize ./.agent-skills/call-log-composition/SKILL.md
SKILL.md
Quality
Evals
Security

Call Log Composition

Overview

Call logs are composed using packages/core/lib/callLogComposer.js which formats call details, AI notes, and transcripts according to the CRM's preferred format (HTML, Markdown, or Plain Text).

Log Format Types

const { LOG_DETAILS_FORMAT_TYPE } = require('@app-connect/core/lib/constants');

// Available formats:
LOG_DETAILS_FORMAT_TYPE.HTML       // HTML formatted logs
LOG_DETAILS_FORMAT_TYPE.MARKDOWN   // Markdown formatted logs  
LOG_DETAILS_FORMAT_TYPE.PLAIN_TEXT // Plain text formatted logs

Using composeCallLog

const { composeCallLog } = require('@app-connect/core/lib/callLogComposer');

const composedLogDetails = composeCallLog({
    logFormat: LOG_DETAILS_FORMAT_TYPE.HTML,
    callLog: {
        direction: 'Inbound',
        startTime: 1704067200000,
        duration: 120,
        result: 'Connected',
        from: { phoneNumber: '+1234567890', name: 'John Doe' },
        to: { phoneNumber: '+0987654321', name: 'Jane Smith' }
    },
    contactInfo: {
        name: 'John Doe',
        phoneNumber: '+1234567890'
    },
    note: 'Customer inquired about product pricing',
    aiNote: 'AI Summary: Customer showed interest in premium plan',
    transcript: 'Agent: Hello...\nCustomer: Hi...',
    user: {
        timezoneOffset: '-05:00',
        userSettings: {
            addCallLogAiNote: { value: true },
            addCallLogTranscript: { value: true }
        }
    },
    recordingLink: 'https://recording.url/abc123'
});

Output Formats

HTML Format

<b>Agent notes</b><br>
Customer inquired about product pricing<br><br>
<b>Call details</b><br>
- Direction: Inbound<br>
- Date/time: Jan 1, 2024 10:00 AM<br>
- Duration: 2 minutes<br>
- From: John Doe (+1234567890)<br>
- To: Jane Smith (+0987654321)<br>
- Result: Connected<br>
- Recording: <a href="https://recording.url/abc123">Link</a><br><br>
<b>AI notes</b><br>
AI Summary: Customer showed interest in premium plan<br><br>
<b>Transcript</b><br>
Agent: Hello...<br>
Customer: Hi...

Markdown Format

## Agent notes
Customer inquired about product pricing

## Call details
- Direction: Inbound
- Date/time: Jan 1, 2024 10:00 AM
- Duration: 2 minutes
- From: John Doe (+1234567890)
- To: Jane Smith (+0987654321)
- Result: Connected
- Recording: [Link](https://recording.url/abc123)

## AI notes
AI Summary: Customer showed interest in premium plan

## Transcript
Agent: Hello...
Customer: Hi...

Plain Text Format

- Note: Customer inquired about product pricing
- Direction: Inbound
- Date/time: Jan 1, 2024 10:00 AM
- Duration: 2 minutes
- From: John Doe (+1234567890)
- To: Jane Smith (+0987654321)
- Result: Connected
- Recording: https://recording.url/abc123
- AI notes: AI Summary: Customer showed interest in premium plan
- Transcript: Agent: Hello... Customer: Hi...

Upsert Functions

For updating specific parts of an existing log:

const { 
    upsertCallAgentNote,
    upsertCallSessionId,
    upsertCallRecordingLink 
} = require('@app-connect/core/lib/callLogComposer');

// Update agent note in existing log body
const updatedBody = upsertCallAgentNote({
    body: existingLogBody,
    note: 'Updated customer note',
    logFormat: LOG_DETAILS_FORMAT_TYPE.HTML
});

// Add session ID
const withSessionId = upsertCallSessionId({
    body: updatedBody,
    id: 'session-123',
    logFormat: LOG_DETAILS_FORMAT_TYPE.HTML
});

Connector Implementation

In your connector's createCallLog:

async function createCallLog({ 
    user, 
    contactInfo, 
    authHeader, 
    callLog, 
    additionalSubmission, 
    aiNote, 
    transcript, 
    composedLogDetails,  // Already composed by handler
    hashedAccountId 
}) {
    // composedLogDetails is pre-composed based on getLogFormatType()
    
    const postBody = {
        subject: `${callLog.direction} Call with ${contactInfo.name}`,
        note: composedLogDetails,  // Use directly
        // ... other fields
    };
    
    // Make API call to CRM
    const response = await axios.post(apiUrl, postBody, { headers });
    
    return {
        logId: response.data.id,
        returnMessage: { message: 'Call logged', messageType: 'success', ttl: 2000 },
        extraDataTracking: {
            withSmartNoteLog: !!aiNote && (user.userSettings?.addCallLogAiNote?.value ?? true),
            withTranscript: !!transcript && (user.userSettings?.addCallLogTranscript?.value ?? true)
        }
    };
}

User Settings

Users can control AI note and transcript inclusion:

// Check user preferences
const includeAiNote = user.userSettings?.addCallLogAiNote?.value ?? true;
const includeTranscript = user.userSettings?.addCallLogTranscript?.value ?? true;

Call Log Flow

  1. Call ends → RingCentral sends call data
  2. Handler receivespackages/core/handlers/log.js
  3. Compose logcomposeCallLog() formats details
  4. Connector createsconnector.createCallLog() sends to CRM
  5. Store referenceCallLogModel stores mapping

Parsing Existing Logs

When retrieving logs for editing:

async function getCallLog({ user, callLogId, authHeader }) {
    const response = await axios.get(`${apiUrl}/logs/${callLogId}`, { headers });
    
    const logBody = response.data.note;
    
    // Extract agent note from HTML format
    const note = logBody
        .split('<b>Agent notes</b>')[1]
        ?.split('<b>Call details</b>')[0]
        ?.replaceAll('<br>', '') ?? '';
    
    return {
        callLogInfo: {
            subject: response.data.subject,
            note,
            fullBody: logBody
        }
    };
}
Repository
ringcentral/rc-unified-crm-extension
Last updated
Created

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.