Salesforce - log a call - want to add disposition

  • 1
  • Question
  • Updated 1 month ago
  • Answered
On the salesforce log a call window (the window that is installed as part of the RingCentral app that is installed in a Salesforce org) - - I need to add an additional field that is on the ActivityHistory record.  (That's the record that the window writes to).

My Question is - is there a way to modify this page?  Is there a way to write my own custom page?  Are there any experts that have been into that portion of integration?

Thanks
Photo of Jeff Stevens

Jeff Stevens

  • 384 Points 250 badge 2x thumb

Posted 3 years ago

  • 1
Photo of Jitender Kumar

Jitender Kumar, Official Rep

  • 930 Points 500 badge 2x thumb
Hello Jeff, 

You can select a call disposition by clicking on check box icon right by the call Log text field.  By default is say "Inbound call from ..."  . You can overwrite to enter your own text and use a value from the drop down.

These values are populated from Subject field in Task object in Salesforce, If you need to add or change call disposition, you can go to Task object in your Salesforce and edit the Subject field, Subject field a picker then you can edit the values for 

Here is the reference for Task Object 

https://help.salesforce.com/HTViewHelpDoc?id=task_fields.htm&language=en_US 

Please let us know if that does not help 
Photo of Jeff Stevens

Jeff Stevens

  • 384 Points 250 badge 2x thumb
Yep - that's very helpful.  The SF field is actually called Subject - on the Task.  Those picklist values can be modified and added to.  I can write trigger's from there to populate my custom fields.

Thanks!

Just for discussion purposes though - IF we wanted to modify that page - is that possible?  Would (Can?) we write a new custom VF page to go in that spot?  I'd like to continue this discussion a bit on this subject. 

Thanks
Photo of SAMANTHA LEE

SAMANTHA LEE

  • 306 Points 250 badge 2x thumb
Following this topic! Jeff can you share some instances where you wrote triggers? The reason being is that I do not want the subject to have to be the Call disposition. I think that they need to add the call disposition field onto the ring central/salesforce integration, it's already bad enough that I have to use subject instead of task type to record the call, becasue I like to track if it an initial call or follow up call, 2nd follow up call, but that has nothing to do with how the call went, good or bad or if I have to call back or send something.  The app is there, but not good enough I am thinking that Salesfoce has a call center, I am wondering if I can create a call center with more options.  Or like you said..is there a way to create a new VF page, (which- I have NO clue how to do)  
Photo of Jeff Stevens

Jeff Stevens

  • 384 Points 250 badge 2x thumb
We wanted to know the outcome of the call, and what of our services were presented on each call.  We also wanted to be able to pull up an Account record and see when the last time we talked with the Account, and if any services were presented.

So we broke this down into two steps.  First, at the call - we needed to keep what the outcome of the call was, and what of our services was presented.

Since each call generates a task/activity - I added two custom fields to our activity object.  "Call Disposition", and "Services Presented", both were pick-list fields.  We then wrote a trigger on the Task object that looks at the services presented, and copies those to a related object on the Account. 
Photo of Benjamin Dean

Benjamin Dean, Alum

  • 8,642 Points 5k badge 2x thumb
Great information Jeff, thanks for sharing!
Photo of SAMANTHA LEE

SAMANTHA LEE

  • 306 Points 250 badge 2x thumb
Can you share how to copy to related objects? Do you ave a formula that you would be will to share??? :) thanks so much!
Photo of Jeff Stevens

Jeff Stevens

  • 384 Points 250 badge 2x thumb
Sure,

If you haven't written any apex before - there would a bit of a learning curve.  Even if you've written in other languages - Java, or .net - you need to be aware of the limits that Salesforce has - if effects how you write code.

But here is the trigger on the Task, and the helper class/method that writes the related services for the account.....

trigger Task on Task (before insert, before update, after insert, after update) {

HandlerTask taskHandler = new HandlerTask();


/*

BEFORE INSERT, BEFORE UPDATE

*/

if(trigger.isBefore) { 

taskHandler.maintainPresentedIds(trigger.new); 

}


/*

AFTER INSERT, AFTER UPDATE

*/

if(trigger.isAfter) {

// Check for any presented services....

boolean servicesPresented = false;

for(Task t :trigger.new) {

if(t.Services_Presented__c != null && t.Services_Presented__c != 'null') {

servicesPresented = true;

}

}

if(servicesPresented) {

if(util_utilities.alreadyExecuted != true) {

util_utilities.alreadyExecuted = true;

taskHandler.addUpdateAccountServices(trigger.newmap);

}

}

 

// Update case & add new Tasks if needed....

taskHandler.caseManagement(trigger.new,trigger.oldmap);

 

}








HandlerTask.cls.....

public with sharing class HandlerTask {

/*

MAINTAIN SERVICES PRESENTED IDs

*/

public void maintainPresentedIds(list<Task> triggeredTasks) {


// Build map<ServiceName,ServiceId> mServiceNameId - from Service__c master

map<string,id> mServiceNameId = new map<string,id>();

map<id,string> mServiceIdName = new map<id,string>();

for(Service__c s :[SELECT id,name FROM Service__c]) {

mServiceNameId.put(s.name,s.id);

mServiceIdName.put(s.id,s.name);

}

for(Task t :triggeredTasks) {

list<string> presentedServiceNames = new list<string>();

presentedServiceNames = stringNullCheck(t.Services_Presented__c).split(';');

string presentedServiceIds = '';

for(string presentedServiceName :presentedServiceNames) {

if(mServiceNameId.containsKey(presentedServiceName))

if(presentedServiceIds.length()>0) {

presentedServiceIds = presentedServiceIds + ';';

}

presentedServiceIds = presentedServiceIds + mServiceNameId.get(presentedServiceName);

}

t.ServicePresentedIds__c = presentedServiceIds;

}

}

/*

ADD UPDATE ACCOUNT-SERVICES AS NEEDED 

*/

public void AddUpdateAccountServices(map<id,Task> mTriggeredTasks) {

system.debug('');

system.debug('HandlerTask.AddUpdateAccountServices....');

system.debug('');

// Get all services from Service Master ...

// Build map<ServiceName,ServiceId> mServiceNameId - from Service__c master

map<string,id> mServiceNameId = new map<string,id>();

map<id,string> mServiceIdName = new map<id,string>();

for(Service__c service :[SELECT id,name FROM Service__c]) {

mServiceNameId.put(service.name,service.id);

mServiceIdName.put(service.id,service.name);

}

// Get all services presented on this call

// Build Map<TaskId,list<PresentedServiceIds>> mTaskPresentedServicesIds

map<id,list<id>> mTaskPresentedServiceIds = new map<id,list<id>>();

set<id> accountIds = new set<id>();

set<id> presentedServiceIds = new set<id>();

for(Task t :mTriggeredTasks.values()) {

system.debug('Task='+t);

if(t.Account__c != null) {

accountIds.add(t.Account__c);

if(t.ServicePresentedIds__c != null && t.ServicePresentedIds__c != 'null') { 

list<string> iterPresentedServiceIds = t.ServicePresentedIds__c.split(';');

system.debug('t.ServicePresentedIds__c='+t.ServicePresentedIds__c);

system.debug('iterPresentedServiceIds='+iterPresentedServiceIds);

for(string s :iterPresentedServiceIds) {

system.debug('s='+s);

presentedServiceIds.add(s);

}

}

}

}

system.debug('presentedServiceIds='+presentedServiceIds);

// Get existing AccountService records

// Build map of Account to list<AccountService>

map<id,list<AccountService__c>> mAccountAccountServices = new map<id,list<AccountService__c>>();

map<string,AccountService__c> mAccountServiceIdsToAccountService = new map<string,AccountService__c>();

list<AccountService__c> accountServices = [SELECT id,name,Account__c,Last_Call_Disposition__c,

Last_Call_Services_Presented__c,Last_Contact__c,

Service__c,Status__c

FROM AccountService__c 

WHERE Account__c IN :accountIds

AND Service__c IN :presentedServiceIds 

];

for(AccountService__c accountService :accountServices) {

system.debug('accountService='+accountService);

string combinedIds = string.valueOf(accountService.Account__c) + string.valueOf(accountService.Service__c);

mAccountServiceIdsToAccountService.put(combinedIds,AccountService);

list<AccountService__c> iterAS = new list<AccountService__c>();

if(mAccountAccountServices.containsKey(accountService.Account__c)) {

iterAs = mAccountAccountServices.get(accountService.Account__c);

}

iterAs.add(accountService);

mAccountAccountServices.put(accountService.Account__c,iterAs);

}

// Loop through triggered Tasks - and update/write new AccountService__c's

list<AccountService__c> accountServicesToAdd = new list<AccountService__c>();

map<id,AccountService__c> accountServicesToUpdate = new map<id,AccountService__c>();

for(Task t :mTriggeredTasks.values()) {

system.debug('HandlerTask.AddUpdateAccountServices.Task='+t);

if(t.Account__c != null) {

list<string> iterPresentedServiceIds = t.ServicePresentedIds__c.split(';');

if(!mAccountAccountServices.containsKey(t.Account__c)) {

// No services for this account  - add them

for(id presentedServiceId :iterPresentedServiceIds) {

accountServicesToAdd.add(new AccountService__c(Name=mServiceIdName.get(presentedServiceId),

Account__c = t.Account__c,

Last_Call_Disposition__c = stringNullCheck(t.Call_Disposition__c),

Last_Call_Services_Presented__c = stringNullCheck(t.Services_Presented__c),

Last_Contact__c = t.CreatedDate,

Service__c = presentedServiceId,

Status__c = 'Presented',

TaskId__c = t.id

));

}

} else {

// Update existing AccountServices, add missing ones....

for(id presentedServiceId :iterPresentedServiceIds) {

string combinedIds = string.valueOf(t.Account__c) + string.valueOf(presentedServiceId);

if(mAccountServiceIdsToAccountService.containsKey(combinedIds)) {

// Update the AccountService__c record

AccountService__c iterAccountService = new AccountService__c();

iterAccountService = mAccountServiceIdstoAccountService.get(combinedIds);

if(t.CreatedDate > iterAccountService.Last_Contact__c) {

iterAccountService.Last_Contact__c = t.CreatedDate;

iterAccountService.Last_Call_Disposition__c = stringNullCheck(t.Call_Disposition__c);

iterAccountService.Last_Call_Services_Presented__c = stringNullCheck(t.Services_Presented__c);

If(iterAccountService.Status__c == null || 

iterAccountService.Status__c == 'None' ||

iterAccountService.Status__c == 'Opportunity Lost'

) {

iterAccountService.Status__c = 'Presented';

}

}

accountServicesToUpdate.put(iterAccountService.id,iterAccountService);

} else {

// Add a new AccountService__c record

accountServicesToAdd.add(new AccountService__c(Name=mServiceIdName.get(presentedServiceId),

Account__c = t.Account__c,

Last_Call_Disposition__c = stringNullCheck(t.Call_Disposition__c),

Last_Call_Services_Presented__c = stringNullCheck(t.Services_Presented__c),

Last_Contact__c = t.CreatedDate,

Service__c = presentedServiceId,

Status__c = 'Presented',

TaskId__c = t.id

));

}

}

}

}

}

// DML updates as needed

if(accountServicesToAdd.size()>0) {

system.debug('accountServicesToAdd='+accountServicesToUpdate);

insert accountServicesToAdd;

}

If(accountServicesToUpdate.values().size()>0) {

system.debug('accountServicesToUpdate='+accountServicesToUpdate.values());

update accountServicesToUpdate.values();

}

}

Photo of SAMANTHA LEE

SAMANTHA LEE

  • 306 Points 250 badge 2x thumb
WOW! Thanks...I sure wish I could use this information. haha. I am looking at another CTI phone system that might do this for me and if so, then I might just change from ringcentral because the other solution is much cheaper. If I do not change though...do you know anyone that can do these changes for me? You see I would also like the recordings to be added to the contact records notes And I would like the call to be notated on the contact records completed activities even if I have made the call through their phone app, or accepted the call from the call being forwarded.Right now it will only log a call on salesforce if I made the call through the ring central saleoforce app. Most times I am out in the field and the call then doesn't get recorded into salesforce. This is a problem because it is not accurately displaying all calls that have occurred on all contacts. 
(Edited)
Photo of SAMANTHA LEE

SAMANTHA LEE

  • 306 Points 250 badge 2x thumb
As I learn more and more, the code above can help me so much! Even without changing DTI, which I do NOT need to do. I have done so much research and the softphone that ringcentral has provided is by far the best, and with the cost it makes it even better! I still need some work (learning curve) on triggers and updating objects automatically based on triggers, but I am slowly beginning to figure out what I want to happen when a trigger takes place! Thanks for your time as well!! I am wishing you much success in your business.
Photo of Jitender Kumar

Jitender Kumar, Official Rep

  • 930 Points 500 badge 2x thumb
Samantha, You may want to try this

We have added a new feature in the App recently where you can customize the call log area, basically you can pick and choose fields from Task object.  

If you have installed latest version of the App 3.40.  You can go to https://ringcentral.na17.visual.force.com/apex/adminUI (keep the first part of your Salesforce URL and just append /apex/adminUI) 

We are in the process of documenting this in our administrator guide.  Could not help myself sharing since I saw this discussion :) 
Photo of SAMANTHA LEE

SAMANTHA LEE

  • 306 Points 250 badge 2x thumb
Just wanted to say thank you!! This is awesome!! 
Photo of Jitender Kumar

Jitender Kumar, Official Rep

  • 930 Points 500 badge 2x thumb
Your feedback means a lot for us.  Thanks you. 
Photo of SAMANTHA LEE

SAMANTHA LEE

  • 306 Points 250 badge 2x thumb
So question...it used to open up a box that would give me the option to create a lead or contact, but it is not working or showing up anymore. Also I think the two softphones, (my desktop and the ringcentral salesforce app) are fighting with each out, because it is now logging both an inbound and outbound call on everycall. 
Photo of Jitender Kumar

Jitender Kumar, Official Rep

  • 930 Points 500 badge 2x thumb
The option to create lead or contact is determined by Softphone layout setting in Salesforce. 
Photo of Charlie Wong

Charlie Wong

  • 60 Points
I'm not seeing the Call Result field being available for selection.  Is there a reason that it shouldn't be?
Photo of Dan

Dan

  • 62 Points
Is there a link or any documents explaining how to use the Salesforce app? I want to learn how to create follow up activities and log a call. It seems whenever I try to log a call, it saves my number and the caller ID says my number if I use the click to dial.
Photo of Michael Uy

Michael Uy

  • 70 Points
@jitender 

Is there any way these fields can accommodate picklists with field dependencies? It doesn't look like it does as I pulled in two fields, one being controlled by the other. 

It seems it just pulls all the picklist values regardless of what's enabled or not based on picklist conditions. 
Photo of Jitender Kumar

Jitender Kumar, Official Rep

  • 930 Points 500 badge 2x thumb
Hi Michael, 
This is correct, Unfortunately the App is not smart enough the honor the validation as user input the data. But the save log should fail with a prompt from Salesforce. I know it is not clean but at least you don't have dirty data inserted in your Salesforce 
Photo of Michael Uy

Michael Uy

  • 70 Points
Is there anything in your product roadmap to remedy this?

I know the error happens when "incorrect" picklist items are selected, but we have a rather complicated field dependent picklist hierarchy that it would be rough on our end users to go through these. We'd like to have these fields required but if RC can't accommodate it, we place the accuracy of our data at risk.
Photo of SAMANTHA LEE

SAMANTHA LEE

  • 306 Points 250 badge 2x thumb
hmm.. I thought I had updated to the latest version, but it tell me that this page does not exist.
Photo of SAMANTHA LEE

SAMANTHA LEE

  • 306 Points 250 badge 2x thumb
oh right on..I just clicked the link you provided and it open in MY salesforce! YAY!
Photo of Jitender Kumar

Jitender Kumar, Official Rep

  • 930 Points 500 badge 2x thumb
Cool, means we are on the same Salesforce PODs :) 
Photo of SAMANTHA LEE

SAMANTHA LEE

  • 306 Points 250 badge 2x thumb
I fixed the errors by making edits to my soft phone!!! YAYAYAYAYYAAY! Again you rock. 
Photo of SAMANTHA LEE

SAMANTHA LEE

  • 306 Points 250 badge 2x thumb
I just wanted to reach out one more time and let you know that, that link you provided has saved me so much time and money. I am so thankful for your time and willingness to post on here. I can now trigger workflows right from ringcentral's softphone! Without having to sacrifice my Subject notes! SOO now all we need to do is get that recording to post on the activity record and this would be a Grandprize WINNER! hint hint
Photo of Jeff Stevens

Jeff Stevens

  • 384 Points 250 badge 2x thumb
Yep - we are waiting for posting the recording to the activity record also.  It's not critical yet, but I think it will come up at some point for us also.  I think that with the API connectivity I've seen we could probably do this from the Salesforce trigger side, but it would be better to have it in the RingCentral Salesforce app.  Like Samanatha - I agree that would be a great addition to your existing package.
Photo of Ann Situ

Ann Situ

  • 60 Points
I still don't see how we can do this: edit what fields show up in the Dialer when we're calling a contact in Salesforce. Is this not possible anymore? The only fields that display are "Subject, Contact Name, Related To, and Description". Is there a way to change what the default subject line is or be able to add more fields to this screen?