question

jeff-stevens avatar image
jeff-stevens asked jitender-kumar3362 commented

Salesforce - log a call - want to add disposition

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

sdk
1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

jitender-kumar avatar image
jitender-kumar answered
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 

1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

jeff-stevens avatar image
jeff-stevens answered
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
1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

samantha-lee avatar image
samantha-lee answered samantha-lee commented
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)  
6 comments
1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

jeff-stevens avatar image jeff-stevens commented ·
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. 
1 Like 1 ·
jeff-stevens avatar image jeff-stevens commented ·
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();

}

}

1 Like 1 ·
samantha-lee avatar image samantha-lee commented ·
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. 
1 Like 1 ·
samantha-lee avatar image samantha-lee commented ·
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.

1 Like 1 ·
benjamin-dean avatar image benjamin-dean commented ·
Great information Jeff, thanks for sharing!
0 Likes 0 ·
Show more comments
jitender-kumar avatar image
jitender-kumar answered jitender-kumar3362 commented
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 :) 

11 comments
1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

samantha-lee avatar image samantha-lee commented ·
Just wanted to say thank you!! This is awesome!! 
1 Like 1 ·
jitender-kumar avatar image jitender-kumar commented ·
Your feedback means a lot for us.  Thanks you. 
0 Likes 0 ·
samantha-lee avatar image samantha-lee commented ·
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. 

0 Likes 0 ·
jitender-kumar avatar image jitender-kumar commented ·
The option to create lead or contact is determined by Softphone layout setting in Salesforce. 
0 Likes 0 ·
charlie-wong2704 avatar image charlie-wong2704 commented ·
I'm not seeing the Call Result field being available for selection.  Is there a reason that it shouldn't be?
0 Likes 0 ·
dan830 avatar image dan830 commented ·
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.
0 Likes 0 ·
michael-uy11085 avatar image michael-uy11085 commented ·
@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. 
0 Likes 0 ·
jitender-kumar avatar image jitender-kumar commented ·
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 
0 Likes 0 ·
michael-uy11085 avatar image michael-uy11085 commented ·
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.
0 Likes 0 ·
michael-uy11085 avatar image michael-uy11085 commented ·
Hi Jitender, 

I was just wondering if there's an answer to my last question about this functionality being added to the app. 

These picklist values are quite valuable for us to determine our call penetration rates and I'd love to find a solution for this. Thanks. 
0 Likes 0 ·
jitender-kumar3362 avatar image jitender-kumar3362 commented ·
Hello Michael, 
I am sending you an email to discuss the issue offline. I need a better understanding of your requirements
0 Likes 0 ·
samantha-lee avatar image
samantha-lee answered
hmm.. I thought I had updated to the latest version, but it tell me that this page does not exist.


1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

samantha-lee avatar image
samantha-lee answered
oh right on..I just clicked the link you provided and it open in MY salesforce! YAY!
1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

jitender-kumar avatar image
jitender-kumar answered
Cool, means we are on the same Salesforce PODs :) 
1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

samantha-lee avatar image
samantha-lee answered
I fixed the errors by making edits to my soft phone!!! YAYAYAYAYYAAY! Again you rock. 

1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

samantha-lee avatar image
samantha-lee answered
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
1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

jeff-stevens avatar image
jeff-stevens answered
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.
1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

Developer sandbox tools

Using the RingCentral Phone for Desktop, you can dial or receive test calls, send and receive test SMS or Fax messages in your sandbox environment.

Download RingCentral Phone for Desktop:

Tip: switch to the "sandbox mode" before logging in the app:

  • On MacOS: press "fn + command + f2" keys
  • On Windows: press "Ctrl + F2" keys