Track Campaign RSVP's with Campaign Member Triggers (Summer '09 part 1)
May 28, 2009With the Summer ’09 release, there are some major
improvements to Campaign Members! Over
the next month we’ll do our best to give a few examples of how to take
advantage of these improvements.
To help make it more real, we’ll follow Whitney, a marketing
manager who is responsible for putting together a webinar for her company
TechCo. We’ll break this down into
several parts:
1) Creating
a basic trigger to keep a quick count of the # RSVP’s
2) Using
workflow & triggers to auto-email non-respondents 7 days later
3) Using
Salesforce Sites for event registration landing pages
4) Using
campaign member custom fields to prioritize responses from the webinar
5) Using
campaign member custom fields & reports for offer management across
campaigns
Create Campaign Custom Field
We join Whitney after she’s sent out a blast to invite, and wants to create an RSVP counter on the Webinar campaign. First, she creates a number custom field on Campaign with a label of “# RSVP Yes” and a field name of “RSVP_Yes”.
When she’s done, she adds it to the Campaign layout:


![]()

Next, she creates a new trigger from Setup-->Customize-->Campaigns-->Campaign
Members-->Triggers.

With some help from the Salesforce Community, she copies
and pastes the code below and saves the trigger, and she’s done!
trigger
UpdateCmpRegistered on CampaignMember (before update) {
Campaign c = [select Id,Registered__c, name
from Campaign where Id = :Trigger.new[0].CampaignId limit 1];
for(CampaignMember cm : Trigger.new){
if (cm.Status == 'RSVP-Yes') {
if (c.Registered__c== null) {
c.Registered__c=0;
}
c.Registered__c += 1;
}
}
update(c);
}

For inquiring minds, here’s what’s happening at each line in English:
1) Run
the trigger called UpdateCmpRSVP on all campaign members that are updated
2) Find
the ID of the campaign for these campaigns
3) Loop
through all the campaign members that were updated
4) If
the Status = RSVP Yes, do the rest of the stuff, otherwise,s do nothing
5) If
the Campaign custom field doesn’t have a value, then do the stuff on the next
line
6) Set
the campaign field RSVP_Yes__c to 0 if it was null in line 5
7) Signals
the end of stuff to do for the line 5 criteria
8) Now
add 1 to the campaign field RSVP_Yes__c
9) Signals
the end of stuff to do for the line 4 criteria
10) Update
the campaign
11) Signals
the end of the trigger
Note that this trigger isn’t best practice, and though it
works, the triggers you create should generally have more checks to test to check for bad
results, such as if the RSVP_Yes__c field doesn’t exist as well.

I am able to track RSVPs just by passing a pre-defined campaign status as a hidden field in the web-to-lead form. For example, the campaign member status for everyone who submits the registration form can be automatically set-up as 'Registered', which in turn has been set-up as a Response. The number of responses is automatically updated and shown in the detail of the campaign. No triggers needed.
Posted by: Bernardo | June 05, 2009 at 08:49 PM
Hi Bernardo - I agree that if you can track responses such as RSVP in status, by all means do so as it's easier to do. I intended this post for those looking to track more granular details such as # people registered for an event compared to the # that actually attended.
Status will only let you track one of these at a time, not both, so using custom fields to track the information and a trigger to sum up the results is a great way to have finer details tracked for campaigns.
Posted by: John Kucera | June 08, 2009 at 10:56 AM
Umm, be careful -- your Trigger will run whenever CampaignMember updates. This is fine if it is a Status update, but if any other data changes while the status is "RSVP-Yes", then the count will be incorrectly incremented again.
This could be avoided by including a check that the matching Trigger.old.Status is not already equal to "RSVP-Yes".
It will also increment if people are taken out of the "RSVP-Yes" status and then put in again, so you might want the Trigger to detect the move away from the status and decrement the count.
Posted by: The Enforcer | June 15, 2009 at 10:48 PM
Thanks for the note - I agree that this trigger is far from best practice as it misses a lot of key functionality including:
- A unit test to make sure it works as expected
- A way to decrement the count for certain status reversions but not others
- A way to fail elegantly & catch the error
My goal was more to show how a few lines of code can be used to update another object, but perhaps I did a disservice by over simplifying it.
I'll make the examples in the future more robust.
Posted by: John Kucera | June 16, 2009 at 11:43 AM