Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.


Panel
borderColor#eeeeee
bgColorwhite
titleColorwhite
borderWidth1
titleBGColor#232323
borderStylesolid
titleIn this page

Table of Contents
depth2

...

Warning
titleDisclaimer

NewVoiceMedia can give advice on how to customize features, but, ultimately, customizing your integration safely is your responsibility. If you raise a support ticket, NewVoiceMedia support may ask you to disable automated features to help them diagnose the issue. Automated features include triggers, workflow rules, and processes.

NewVoiceMedia call lifecycle overview

The following information describes the lifecycle of a NewVoiceMedia call. This information demonstrates the importance of taking care when customizing NewVoiceMedia and Salesforce.

Expand
titleExpand | Collapse

Whenever a call takes place, our package performs the following actions. All actions happen in the context of one of two users:

Unless otherwise described, all actions happen in the context of the current user.

  1. NewVoiceMedia delivers, or transfers, the call to an agent
    1. OpenCTI pops a Salesforce record (for example, a contact or lead).
    2. ContactWorld creates an Interaction Event record. This record contains the following information:
      • the call GUID
      • the agent the call was delivered to
      • a time stamp
      NewVoiceMedia also creates an Interaction Event Note record. This record is a child of the interaction event record and stores related notes.
  2. The agent takes notes or links the call to another object, or both, using the Log a call action.
    1. NewVoiceMedia updates the Interaction Event record with information about the linked object.
    2. NewVoiceMedia updates Interaction Event Note record with the note text.
    3. Optionally, NewVoiceMedia creates a Chatter post.
  3. If the agent transfers the call, NewVoiceMedia repeats steps 1 and 2 for the new agent handling the call.
  4. When the call ends:
    1. The API user creates a Call End Event object.
    2. A trigger creates a task from the Call End Event object. The trigger copies all relevant information, in the context of the Salesforce API user.
    3. After the trigger creates the task, NewVoiceMedia deletes the Call End Event in the context of the Salesforce API user.
  5. When the agent views the task that represents the call, a Visualforce component displays all the Interaction Event Note records that belong to the call. These Interaction Event Note records belong to the call because they have the same call GUID.

These operations are all internal to our package, and can change between package versions. Therefore we discourage customizing or interacting with these objects directly.

Custom objects

The following objects are for internal use by NewVoiceMedia . Creating, updating or deleting these objects can have a negative impact on NewVoiceMedia in Salesforce.

Expand
titleExpand | Collapse


PackageObjectDescription

NewVoiceMedia


Background ActionUsed for scheduling.

Call End Event

Represents a call ending in NewVoiceMedia. Contains all the information required to create a task in Salesforce.

The package contains a trigger which creates an associated task record. If you delete Call End Event records in a trigger of your own, the package trigger may not execute.

Call End Event records are transient and NewVoiceMedia deletes the records soon after creation. If you write a trigger for this object, your trigger may not be execute.

We recommend, if required, that you interact with the task record created after the call, rather than with the Call End Event record.


CaseRoutingRequestAutomatically routes or releases cases whenever a case status changes.

Interaction EventContains information that links a call's task record to a related Salesforce record or records. These records can be contacts, leads, accounts, and so on. If you change this object, tasks may be orphaned.

Interaction Event NoteContains the notes for the call.

Connect


Dial ListContains the definition of a dial list.

Dial EntryUsed to store an entry in a dial list.


Warning
If you have to change any of these objects, make the changes after business hours or when the associated features are not in use. For example, if you change Dial Entries, don't do it while agents are using Connect.


Best practices when creating triggers

Triggers and automation cause the most issues when customizing NewVoiceMedia or Salesforce. If you experience an issue with NewVoiceMedia in Salesforce, support will ask you to disable your custom triggers. This enables us to verify that the standard installation is working.

 Create easy-to-disable triggers

Expand
titleExpand | Collapse

We recommend that you make your triggers easy to disable. To create easy-to-disable triggers, perform the following steps:

  1. Create, or edit, a custom settings object, for example, ContactWorldIntegrationSettings.
  2. Add a custom field of Checkbox type, for example, Enable Triggers.
  3. Create a custom settings record for your org. Select or clear Enable Triggers as required.

When you create triggers and in all existing triggers, include the following code. This code checks that you have selected the Enable Triggers check box before running the trigger code. If you have not selected the check box, your trigger code does not run.

Code Block
languagejava
titleConditionally disable triggers
linenumberstrue
trigger MyTrigger on Task (before insert, before update) {
 
    if (!ContactWorldIntegrationSettings.getOrgDefaults().Enable_Triggers__c) return;
 
	// Do Stuff
}

Using this method, you can enable or disable all relevant triggers.

Use bulkified triggers

Expand
titleExpand | Collapse

Trigger-bulkification is a Salesforce technique. Using trigger-bulkification, triggers can handle creation or updates of more than one record at a time. This technique helps avoid hitting governor limits on your triggers during a mass creation or update. Bulkifying means grouping up all your data manipulation operations into as few operations as possible. In practical terms, this usually means moving such operations outside of for-loops. For more information about bulkifying triggers, see Salesforce help and http://blog.jeffdouglas.com/2009/04/20/writing-bulk-triggers-for-salesforce/.

Avoid trigger looping

Expand
titleExpand | Collapse

Performing data-manipulation (DML) operations in triggers that run after record inserts or updates can cause trigger looping. For example, a task object has a trigger which modifies a lead, and a lead object has a trigger that modifies a task. The task's trigger initiates the lead's trigger, and then the lead's trigger initiates the task's trigger, and so on. This situation results in an endless loop of trigger execution.

To avoid this situation, wherever possible, use triggers that run before update or insert. DML is not allowed in triggers that run before update or insert.

If you cannot run your triggers before insert or update, use the following code. The code protects your triggers from firing repeatedly by checking whether they are already executing:

Code Block
languagejava
titleClass to detect recursive calls
linenumberstrue
public Class CheckRecursive{
    private static boolean run = true;
    public static boolean runOnce(){
        if (run) {
            run = false;
            return true;
        } else {
            return run;
        }
    }
}

The runOnce method only returns true the first time the trigger runs in a single execution context. If you check the value before running your trigger, you will prevent trigger looping.

Code Block
languagejava
titleTrigger that avoids recursion
linenumberstrue
trigger MyTrigger on Task (after update) {
 
    // Exit if we're being called recursively
    if(!checkRecursive.runOnce()) return;
    
    // Do stuff!
}

For more information about avoiding trigger looping, see Salesforce help.

Best practices when writing queries for large data sets

Non-selective queries can fail if you run the query on more than 100,000 records. If your organisation handles a large volume of phone calls, the number of ContactWorld records can exceed that limit over time.

Make your queries selective

Expand
titleExpand | Collapse

The following fields in our custom objects are indexed:

  • NVMContactWorld__InteractionEvent__c.NVMContactWorld__Key__c
  • NVMContactWorld__InteractionEvent__c.NVMContactWorld__IndexedCallObjectIdentifier__c
  • NVMContactWorld__InteractionEvent__c.NVMContactWorld__What__c
  • NVMContactWorld__InteractionEvent__c.NVMContactWorld__Who__c
  • User.NVMContactWorld__NVM_Agent_Id__c

If you have to query our objects, use these fields in the WHERE clause to make the query selective.

Alternatively, to protect your code from selectivity issues, surround your queries in try-catch blocks:

Code Block
languagejava
titleCatch query errors
linenumberstrue
try {
    // Can Throw if over > 100,000 records
    List <Task> = [SELECT Id FROM Task WHERE ...];
}
catch (exception e)
{
    // Handle this!
}

For more information on how to make your queries selective, see :https://help.salesforce.com/apex/HTViewSolution?urlname=How-to-make-my-SOQL-query-selective&language=en_US

Best practices when creating validation rules

Validation rules on some objects or fields can prevent our managed package from creating objects. If you experience an issue with ContactWorld in Salesforce, support will ask you to disable your custom validation rules. This enables us to verify that the standard installation is working.

Create easy-to-disable validation rules

Expand
titleExpand | Collapse

We recommend that you make your validation rules easy to disable. To create easy-to-disable validation rules, perform the following steps:

  1. Create, or edit, a custom settings object, for example, ContactWorldIntegrationSettings.
  2. Add a custom field of Checkbox type, for example, Enable Validation Rules.
  3. Create a custom settings record for your org. Select or clear Enable Validation Rules as required.
  4. Create custom settings records for profiles, users, or both, as required. Select or clear Enable Validation Rules as required.

When you create validation rules and in all existing validation rules, include code which checks that you have selected the Enable Validation Rules check box before running. If you have not selected the check box, your validation code does not run.

For example, the following code checks that DueDate is within the next 90 days and that the Enable Validation Rules check box is selected.

Code Block
titleConditionally disable validation rule
AND (
    $Setup.ContactWorldIntegrationSettings__c.Enable_Validation_Rules__c,
    DueDate - TODAY() > 90
)


Best practices when creating flows and processes

Custom flows and processes can cause issues when customizing ContactWorld or Salesforce. If you experience an issue with ContactWorld in Salesforce, support will ask you to disable your custom flows and processes rules. This enables us to verify that the standard installation is working.

Create easy-to-disable processes

Expand
titleExpand | Collapse

We recommend that you make your processes easy to disable. To create easy-to-disable processes, perform the following steps:

  1. Create, or edit, a custom settings object, for example, ContactWorldIntegrationSettings.
  2. Add a custom field of Checkbox type, for example, Enable Processes.
  3. Create a custom settings record for your org. Select or clear Enable Processes as required.
  4. Create custom settings records for profiles, users, or both, as required. Select or clear Enable Processes as required.

When you create processes and in all existing processes, include code which checks that you have selected the Enable Processes check box before running. If you have not selected the check box, your process does not run.

The following code checks that the Enable Processes check box is cleared:

Code Block
titleConditionally disable process
$Setup.ContactWorldIntegrationSettings__c.Enable_Processes__c = false


Create easy-to-disable workflow rules

Expand
titleExpand | Collapse

We recommend that you make your workflow rules easy to disable. To create easy-to-disable workflow rules, perform the following steps:

  1. Create, or edit, a custom settings object, for example, ContactWorldIntegrationSettings.
  2. Add a custom field of Checkbox type, for example, Enable Workflow Rules.
  3. Create a custom settings record for your org. Select or clear Enable Workflow Rules as required.
  4. Create custom settings records for profiles, users, or both, as required. Select or clear Enable Workflow Rules as required.

When you create workflow rules and in all existing workflow rules, include code which checks that you have selected the Enable Workflow Rules check box before running. If you have not selected the check box, your process does not run.

The following code checks that NumberOfEmployees is greater than 30 and that the Enable Workflow Rules check box is selected.

Code Block
titleWorkflow rule formula
AND($Setup.ContactWorldIntegrationSettings__c.Enable_Workflow_Rules__c,
NumberOfEmployees > 30)


Best practices when integrating with call tasks

At the end of a call, a trigger creates a task record relating to that call. To avoid causing issues in ContactWorld, when you create task triggers or flows, take care not to interfere with this feature. The best way to avoid issues is to identify and handle ContactWorld tasks differently.

Exclude ContactWorld tasks from problematic trigger code

Expand
titleExpand | Collapse

You can identify ContactWorld tasks because they have values in ContactWorld custom fields. Custom fields include CW start time.

If you have existing triggers on task creation or update, and they are having a negative impact on how your tasks are created, edit the triggers so they skip over ContactWorld tasks. The following code checks for a value in the NVMContactWorld__CW_Call_Start_Time__c field. If a value is present, the task is a ContactWorld task and the trigger should not run on the record.

Code Block
languagejava
titleSkipping ContactWorld tasks on your triggers
linenumberstrue
trigger MyTrigger on Task (before insert, before update) {
    for (Task t: trigger.new)
    {
        // Skip NVM Tasks
        if (t.NVMContactWorld__CW_Call_Start_Time__c != null) continue;

   	    // Do stuff   
    }
}


Use an embedded Visualforce page to keep a count of ContactWorld tasks

Expand
titleExpand | Collapse

Sometimes you might want to know the number of tasks related to a specific Salesforce object, for example, a contact or lead. You can use this number in reports later.

The easy, but not recommended, way to count tasks is to use a trigger. The trigger updates the count in a custom field on the related record. This method is likely to cause concurrent editing issues.

Instead we recommend you use an embedded Visualforce page to view a count of related task records.

To create a Visualforce page and embed it in the page layout, perform the following steps:

  1. Create an Apex Class which counts the task records relating to the object.
    The following example code counts tasks related to contacts. Modify this code to count tasks related to other Salesforce objects such as leads or accounts.

    Code Block
    languagejava
    titleTaskCountController class to count tasks
    linenumberstrue
    public class TaskCountController
    {
        private Contact currentContact;
    
        public TaskCountController (ApexPages.StandardController base)
        {
            currentContact = (Contact) base.GetRecord ();
        }
    
        public Integer GetNumberOfAssociatedTasks () {
            return [SELECT COUNT () FROM Task WHERE WhoId = :currentContact.Id ];
        }
    }


  2. Create the Visualforce page and include the class you create in step 1.
    The following example Visualforce page uses the code in the TaskCountController class.

    Code Block
    languagexml
    titleVisualforce page to count tasks
    linenumberstrue
    <apex:page standardcontroller="Contact" extensions="TaskCountController">
        <apex:outputLabel for="taskCount" style="font-weight: bold;color: #4a4a56">Task count</apex:outputLabel>&nbsp;
        <apex:outputText id="taskCount" value="{!NumberOfAssociatedTasks}"/>
    </apex:page>


  3. Embed the Visualforce page you create in step 2 in your object's page layout. Set the height of the Visualforce component to 14px so the field looks like a normal row on the page.

Use an embedded Visualforce page to report on ContactWorld tasks

Expand
titleExpand | Collapse

Instead of using triggers to create reports on ContactWorld tasks, we recommend that you embed a report in a page layout.

To embed a report in a page layout, perform the following steps. The following steps describe adding a report to a contact object. Modify this method to add a report to another Salesforce object.

  1. Create a new report, for example Activities with Contacts.
  2. Configure the report using the following settings:

    FieldValue or valuesDescription
    ShowAll Activities, Completed Activities, TasksThe report is run on all completed task records
    FilterCW Call Start Time not equal to ""The task records must have a value in the SW Call Start Time field. The task record is therefore a ContactWorld task.
    Date FieldCreated DateUse the Created Date field.
    RangeAll TimeThe report is run on tasks created from the beginning of time.


  3. In the Preview section, set the report format to Summary Format and group the results by ContactID.
  4. Add a chart of your choice, such as a bar chart, donut chart, or pie chart, and customize as required. Optionally, create a bucket field to group calls into long, medium, short calls and group the results by call duration.
  5. Save the report into a folder other than My Personal Custom Reports.
  6. Add the report to a contact page layout.

The following report is embedded in a contact record. The report shows that one short, two medium and one long call has been made or received in relation to this contact:

Create report

Best practices when customizing incoming call popping

To customize incoming call popping, use SoftPhone layouts. For information about using SoftPhone layouts to customize incoming call popping, see Configuring advanced popping.

Best practices when interacting with Dial Lists and Dial Entries

Dial List and Dial Entries are custom objects in the Connect managed package. As with custom objects in the ContactWorld managed package, you must take care when interacting with these objects.

...