Monday, July 29, 2013

Allowing Customer Portal Users To Edit Their Own Contact Information

Customer Portal users have the ability to edit some information about themselves via the My Profile page.  That page allows them to edit their own User record, but not their own Contact or Account record.  However, the User record does have some fields in common with Contact and Account, and with a quick bit of Apex, you can make it such that when the portal user updates his information, that gets reflected in his Contact or Account record as well.

To allow portal users to see the My Profile link, go to Setup->Home->Home Page Layouts.  Make a separate home page layout for your Customer Portal (if youhaven't already done so) and add the Customer Portal Welcome componentto the top of it.  That will render a little area in the sidebar with a My Profile link (which will allow them to edit their user information) and a Logout link.

Now to synchronize that User information with the Contact information.  The example given here shows that synchronization just with the Contact, but it can easily be modified to apply to an Account or a Person Account.  While the code itself is simple, it's not as straightforward as it seems.  As this page of the Apex docs indicates, you can't just make a User trigger that updates a Contact or an Account, because it's forbidden to modify those "non-setup" objects from a "setup" object like User.  Fortunately there is a simple solution: the @future annotation .  The @future annotation allows you to create Apex that runs asynchronously at some point in the future (in my tests I've found that it runs immediately, or at least very soon after the trigger executes).  Methods that use @future are subject to different limits than normal trigger operations because @future methods don't hold up the trigger (and therefore the entire user experience) while they're working.  Therefore @future methods are often used to perform long-running web service callouts from triggers asynchronously.  However, they can also be handy for a case like ours, where we want to update an object that we're not normally eligible to update. Here I'll show some snippets of code that allow me to accomplish this synchronization.

You can download the full trigger and class including test methods at the Developing with Service Cloud page here.

Calling a method that has been marked as @future is just like calling any other static method.  Here's my trigger, short and sweet:

trigger UpdateContactFromPortalUser on User (after update) {
    //We only want to run on the single item that the user edited
    if (
        User u =_[0];
        //And only if it's a portal user
        if (u.ContactId!=null) {

My @future method is named UpdateContactFromPortalUser.updateContacts.  Let's see how that works. 

In the example given here, I just update a couple of fields from the user record: the name, the email address, and the title.

global class UpdateContactFromPortalUser {
    @future public static void updateContacts(String userId) {
        User u = [select ContactId,Email,FirstName,LastName,Title
                    from User
                    where Id=:userId];

        if (u!=null && u.ContactId!=null) {
            Contact c = new Contact (Id=u.ContactId,Email=u.Email,FirstName=u.FirstName,LastName=u.LastName,Title=u.Title);
            update c;

(note that the above is just a snippet -- download the whole class here)

By putting the @future above my method, I'm telling the system that when I call this method, it should be run asynchronously.  This allows me to bypass those pesky trigger restrictions and update my contact.  Note that the @future method does impose some constraints: the method has to be static, return void, and cannot take sObjects as parameters (which is why I passed the user ID in instead of the User sObject itself).

That's all there is to it!

Monday, July 22, 2013

Another Way To Skip The Case Close Page

Some time ago I wrote about The Quick Case Close Button as one means of skipping the Close Case page.  In fact, there's another way to close cases quickly: you can show closed case statuses directly in the Status field of Case.  This is not enabled by default, so many people miss this option.

You'll find the options that enable this in Setup->Customize->Case->Support Settings, and there are two of them.

Show Closed Statuses in Case Status Field does exactly what its name implies: it allows you to show closed case statuses right in that Status field.  This means you can actually create a case and close it in a single step. Once you have closed statuses in that Status field, you can hide the Close Case button on the Case detail page by editing the Case page layout.  

However, the page layout editor does not allow you to control the buttons on the edit page, and so you may be left with one redundant button, namely the Save & Close button.  Fortunately there's another option for that on the Support Settings page, namely the Hide Save & Close Button.  When this is enabled, the Save & Close button disappears from the edit page also.

For many customers, this little addition should reduce the number of clicks it takes for their agents to create and close a case.

Monday, July 15, 2013

The Quick View Tab

Lots of people would love to have a tab that just opens directly to a view of their choice.  Unfortunately, standard object tabs can only open the relevant standard overview page, which shows a list of recently viewed cases -- that page can't be preset to open a certain view as soon as you hit the tab.  However, you can create a custom tab which will instantly redirect itself to the view you'd like.  Here's how.

The most common request I get is to create a tab for views on Case, so that's the example I'll give here.  Of course, this technique can be used to create a tab for any kind of view for any object.

First, navigate to the view you'd like to tab-ify by going to the overview page and selecting that view.  In my case, I'll go to the Cases tab and click on the Open Cases view, which is a view I created that shows all the open cases in my org. 

Save the URL of this view; you'll need it later.  It will look something like

Now go to Setup->Customize->Create->Tabs.  Click the New button under Web Tabs.  Set it to Full Page Width.  Set the Tab Type to URL, and give it a label that makes sense (I called mine "Open Cases" but you can call yours "Cases" if you intend to hide the normal case tab -- just make sure you don't end up with 2 tabs labelled "Cases").  Pick any Tab Style -- it's going to redirect to the Case tab anyway so this doesn't matter.

On the next page of the wizard, enter the following in the Button or Link URL:

javascript:parent.navigateToUrl('<your url here>');

Don't forget those single-quotes around the URL.  So in my example it looks like this:


And voila!  You now have a tab that navigates directly to your view.

Bear in mind that a quick JavaScript navigation of this sort breaks the Back button minorly -- if you click this tab and then hit the back button, you'll get bounced right back to your view.  You have to click the Back button twice in rapid succession to get back where you started.  Consider yourself warned!

Monday, July 8, 2013

Stamping A "First Response" Field When An Email Goes Out On A Case

A common service-level agreement (or SLA) in the support world is the first response time.  Support organizations are often contractually obligated to respond to a given case within a certain number of hours.  It is a little-known fact that you can use to manage this type of SLA using simple workflow rules -- no Apex Code required!

First, we should note the existence of the Entitlements Processes functionality built into  This capability allows you to measure and track your response, workaround and resolve time SLAs, both in calendar hours and business hours, so if you have some significant entitlement and SLA needs, Entitlements Processes are worth checking out.  It's fairly involved to set that up, though, so today's post is focused more on people with more lightweight needs.  Today we'll look at just using a simple workflow rule to stamp your first response time.

Your first step will be to add a First Response date/time field to Case.  Next, if you haven't turned on Email To Case, do so by going to Setup->Case->Email To Case.  You don't even have to activate any routing addresses.  The reason for this is that once you have turned on Email To Case, there's an object under case called Email Message. 

You can make workflows on this Email Message object which update the parent Case.  So your next step is to create a workflow rule on the Email Message object.  Here, set your criteria such that you stamp your field when the email message is outbound (i.e. "Is Incoming equals false") and the First Response field is empty (because you don't want to stamp it again once it's been stamped). 

Finally, put a field update on this workflow rule to stamp the First Response field to NOW(). 

That's all it takes -- once you activate this workflow rule, your First Response field will begin getting stamped immediately, and you can start reporting on it. 

Also: Note that if you are using the Customer Portal or Self-Service Portal, another means of responding to your customers would be via a public Case Comment.  You can use a very similar process to that given above to stamp your First Response field from a Case Comment -- just set the object on the workflow rule to Case Comment instead of Email Message.

Monday, July 1, 2013

How To Create A Mass Email Distribution List in

Today we have a quick but common question from the Answers boards.  People often ask, "I want to email a bunch of people from at once.  How do I do that?"

Note that this post covers how to send an email from's default Campaign functionality.  Just prior to when this blog was posted, acquired ExactTarget, which is a much more industrial-strength solution for outbound email.  This blog post is intended for people that just need to send mass emails to 1000 or less people.

The answer is a little bit roundabout, but:

1.  Create a Campaign that will represent your mailing list.  If you can't see the Campaigns tab, be sure that in your user record Marketing User is checked on, and that in your profile you have create access for Campaigns.
2.  Either fill the campaign manually using the Edit Campaign Members button, or create a report on Contacts with the criteria as needed and press the Add To Campaign button to fill your campaign.
3.  Now go to the Contacts tab and click Create New View.  Set it to All Contacts, put no criteria on it, and enter your campaign in the Filter By Campaign box.  Save the view.
4.  Go back to the Contacts tab and click the link entitled Mass Email Contacts.  Select the view you created in step 3, select your email template, and you're off to the races.

Note that a campaign can contain either Contacts or Leads (or both), so if you want to email Leads instead, modify steps 3 slightly to say "Go to the Leads tab" and "click the link entitled Mass Email Leads."