Skip to main content

Volunteers

How to configure the Flourish Liminal managed package to run volunteer signups.

Overview​

The volunteer module gives your supporters a five-step web flow:

  1. Pick an event: choose from your active Campaigns.
  2. Pick a role: what kind of help you need (e.g. Greeter, Setup Crew, Driver).
  3. Pick a time slot: a specific shift on that event.
  4. Fill in their details: name, email, phone, and organization.
  5. Get a confirmation page: and, if configured, a confirmation email.

Behind the scenes, Salesforce creates a Contact (or matches an existing one by email), an Opportunity with volunteer details, a Selection record linking everything together, and a Campaign Member connecting the volunteer to the event.

One person can also sign up a whole group, if you turn that on. See Group sign-ups.

Volunteers can change or cancel their own sign-up from a link in their confirmation email, without calling you. See Letting volunteers manage their own sign-up.

For day-of operations, a separate Volunteer Check-In page lets staff manage arrivals with a simple table view.

Admins also have access to two additional tools:

  • Engagement Builder: create and configure events, roles, and shifts in a guided interface. This is where you set almost everything about an event.
  • Engagement Dashboard: view rosters, check in/out volunteers, cancel bookings, export data, and monitor capacity.

For paid tickets, donations, products, or bookable time slots, see Events & Shops. The two modules are independent: you can use either, both, or neither.


Before You Start​

Make sure you have:

  • The Flourish Liminal managed package installed in your org.
  • Permission to create Campaigns, edit Lightning pages, and manage Flows.
  • An idea of which events and roles you want to publish.
  • A way for volunteers to reach the page, typically a Salesforce Experience Cloud site, but any Lightning page works.

NPSP is not required for volunteer signup.


Step 1: Create the Event (Campaign)​

A volunteer "event" is a standard Salesforce Campaign, and the Engagement Builder is the way to make one. It creates the Campaign, its roles and its shifts in one place, and it is the only interface for most of an engagement's settings.

The Campaign itself carries:

  • Campaign Name: the public title volunteers will see (e.g. Spring Park Cleanup).
  • Description: a short summary. Plain text shows best; rich formatting will be stripped on the event card.
  • Start Date / End Date: the date window of the event. Volunteer slots must fall inside this window.
  • Engagement Type: set to Volunteer.
  • Status: Draft, Published or Archived. This is the publish control. Only a Published engagement appears to volunteers; the builder keeps the Campaign's own Active checkbox in step for you, so you do not set it yourself.
  • Tags: free text, comma separated. Used for searching the builder's engagement list and for your own reporting.
  • Timezone Name and Timezone Offset: filled in when you save. Defaults to America/Chicago (US Central). The offset is DST-aware based on Start Date. Change the timezone name if your event is in a different timezone; the offset recomputes automatically.

Everything else about an engagement is set in the builder, not on Campaign fields. The hero image, the address shown on the event card, the brand colors and logo, the confirmation email wording, whether past shifts are listed, and the group sign-up settings are all stored together on the Campaign in one settings field that the builder reads and writes. They are deliberately not individual fields: a packaged field can never be removed once shipped, and these are display settings nobody reports on.

The practical consequence is that you configure an engagement through the Engagement Builder. Looking for an Event Image URL or a Brand Color field on the Campaign page layout will not find one.

Each engagement gets its own share key when it is created, and the public link is built from that rather than from the Campaign's record Id. That means a link can be retired without touching the record.


Step 2: Create One or More Roles (Liminal Offerings)​

A "role" is what kind of help you need. Each role is a Liminal Offering record linked to your Campaign.

  1. From the Liminal Offerings tab, click New (or use the Engagement Builder).
  2. Fill in:
    • Name: short internal name (e.g. Greeter).
    • Label: public name shown to volunteers. Leave blank to use the Name.
    • Description: what the role involves.
    • Image (Landing): a public URL for a per-role photo. Optional.
    • Engagement: look up the Campaign you created in Step 1.
  3. Save.

You don't need to set price, stock, or any of the e-commerce fields. Just leave them blank.


Step 3: Create the Time Slots (Liminal Availabilities)​

Each shift is a Liminal Availability record under a role.

  1. From the role's record page, scroll to Liminal Availabilities and click New (or use the Engagement Builder's Shifts tab).
  2. In the record-type picker, choose Slot.
  3. Fill in:
    • Offering: should default to the role you started from.
    • Engagement: the Campaign.
    • Start Datetime / End Datetime: when the shift begins and ends. Both must fall inside the Campaign's date window (a validation rule enforces this).
    • Max Bookings: how many volunteers can claim this shift. Defaults to 1 if left blank.
    • Slot Open/Close: must be set to Open. If creating manually, you must set this yourself or the shift won't be counted in capacity rollups.
  4. Save.

Tip: The Engagement Builder's Shifts tab provides a calendar view where you click a date, click "Add Shift," fill in the start/end times and max bookings, and save. It handles the record type, Slot Open/Close, and timezone conversion automatically.


Step 4: Publish the Signup Page​

The volunteer wizard is a single component called Volunteer Signup.

  1. Open Lightning App Builder, then create or edit a page.
  2. From the Custom - Managed components, drag Volunteer Signup onto the canvas.
  3. Save and Activate. For a public-facing site, build the page inside an Experience Cloud site.

Note: Place the Volunteer Signup component on the page, not Volunteer Event List. The signup component is the full wizard that wraps all five steps.

Making It Public​

If you're using an Experience Cloud site for public-facing signups:

  1. Set the page to allow guest access.
  2. On the Guest User Profile, grant access to the Lim_VolunteerController Apex class.

That is the whole grant. No object permissions, no field permissions, and no guest user sharing rules.

Liminal's public pages run their reads and writes in system context, so the guest profile never needs to reach the data itself. What limits a guest is what each page asks for: published engagements, open slots, shifts inside the event window. Granting Campaign or Contact access on top widens what the guest user can reach across your whole org without enabling a single feature, and sharing rules are dead weight that nothing consults.

If you inherited a site set up the older way, the object permissions and sharing rules can come off.

Then record the site's URL in your org-wide settings as the Volunteer Site URL. Share links and the confirmation email's button are built from it.


Step 5: Set Up the Check-In Page (Optional)​

The Volunteer Check-In component provides a day-of management interface for staff.

  1. Create a new page in Lightning App Builder (or an Experience Cloud page for on-site tablets).
  2. Drag Liminal: Volunteer Check-In onto the canvas.
  3. Save and Activate.

The check-in page provides:

  • Date picker: defaults to today.
  • Event dropdown: auto-populated based on the selected date.
  • Include Unconfirmed toggle: shows volunteers with Claimed status in addition to Ordered.
  • Stats bar: "X of Y checked in" with a progress bar.
  • Search: filter by name, email, organization, or role.
  • Volunteer table: alphabetical list with Check In, Check Out, and Undo buttons.
  • Filter persistence: the date, event, and toggle state are saved in the browser so refreshing keeps your selection.

On an Experience Cloud site, the guest profile needs access to the Lim_CheckInPublicUtility Apex class, and nothing else.

Think before putting check-in on a public page. It returns a full roster with names, email addresses and phone numbers, and it records arrivals. On a public site that is readable and writable by anyone who has the URL. Put it behind authentication unless you have decided that exposure is acceptable.


Step 6: Email​

Liminal sends volunteer email itself. There is no Flow to clone and no email template to build.

Three kinds of message go out:

MessageWhen
ConfirmationSomeone signs up.
Change noticeTheir booking changes, from either the dashboard or their own manage page.
Cancellation noticeTheir sign-up is canceled.

Org-wide settings​

Set these once, in the FL Liminal custom metadata type on the global record:

SettingWhat it does
Sender EmailA verified Org-Wide Email Address that every send is routed through. Set this first.
Email From NameThe display name, used only when no Sender Email is configured.
Organization NameYour organization's name in the message. Defaults to the org's own name.
Brand Color, Brand Color Secondary, Logo URLOrg-wide branding.
Volunteer Site URLWhere the confirmation's button sends people.
Volunteer Manage URLThe self-service page. See below.

If you set only one brand color, the second follows it, so your messages never pick up somebody else's accent color. Leave the logo blank and a wordmark is used.

Per-engagement wording​

Branding is set once for the org; the wording is set per engagement, in the Engagement Builder. Each of the three messages takes its own subject and body, and anything you leave blank falls back to the packaged wording. An engagement can also override the org's colors and logo, and turn off the white logo band above the header.

Turning off the confirmation does not turn off the others. The confirmation is the one you can switch off per engagement. Change and cancellation notices are decided per action instead, which means an engagement that never sends a confirmation can still tell somebody their spot was released.

Deciding per action​

Whoever makes a change chooses whether the volunteer hears about it, and both dialogs on the dashboard roster carry that toggle. Left alone, the volunteer is told: someone whose spot was released should hear about it unless you deliberately decide otherwise.

A volunteer changing their own booking always triggers the notice, since they are not deciding on anyone else's behalf.

A change says what they now hold; a cancellation names what was released. Somebody who dropped one of four shifts sees the three that remain rather than having to work it out.

Neither notice goes to the organization. You find out by looking at the roster.


Group sign-ups​

One person can register a party rather than just themselves. It is off unless you turn it on for the engagement, because it changes what the public form asks for.

In the Engagement Builder, turn on group sign-ups and optionally set the largest party this engagement takes. The package caps a party at 100 regardless.

You also choose what the form asks a group for:

ModeThe form asks forWhat gets created
HeadcountOne numberOne Contact and one Opportunity for the organizer. One booking per shift, holding all the seats. Check-in shows one row, "Party of 6".
NamedFirst name, last name and email for each person, typed in or imported from a spreadsheetA Contact and an Opportunity per person. One booking each. Check-in shows six ordinary rows.
EitherThe volunteer choosesWhichever they picked.

Leave the mode unset and volunteers get the choice.

Named members must have an email address, and that is the point of choosing Named. Matching is on email, so a member entered without one is a row you can never reconcile: the same person next month becomes a second Contact.

A party that does not fit is told what would. Rather than reporting the shift full, the form says how many places are left ("has room for 4 more people, and you asked for 6"), so an organizer can split across dates instead of giving up.

Capacity counts seats rather than bookings throughout, so a party of six takes six places off a shift.


Letting volunteers manage their own sign-up​

A volunteer can change or cancel their own booking from a public page, reached by a link in their confirmation email.

It is off until you point at a page. Set Volunteer Manage URL in the FL Liminal settings to the page hosting the manage component, usually another path on the same Experience site. Blank means the confirmation email does not offer the link at all, rather than offering one that goes nowhere.

The guest profile needs the same Lim_VolunteerController class the signup page uses, and nothing else.

From that page a volunteer can:

ActionNotes
Remove a shiftTakes their whole booking off that shift. Refused on the last one, which points at Cancel instead.
Remove a personNamed parties only. Drops that person from every shift the booking holds. Refused on the last one.
Change the sizeHeadcount groups only. Growing re-checks that the room is still there; shrinking always works. A named party's size is how many people are in it, so this is refused and the message says to remove somebody.
Cancel the sign-upReleases everything. Shifts already under way are kept, since a shift that has started is a record of what happened.

The order code in the link is the whole credential, so anyone holding the link can read and cancel the booking. The page is built with that in mind: it shows a first name, the address the confirmation went to, the shifts, and group members by name only. No phone numbers and no member email addresses, so forwarding the email hands on nothing extra. An unknown code and a canceled one look identical, so the page cannot be used to find out which codes exist.

Only the organizer's link works. In a named party each member gets their own order code, but only the organizer's addresses the booking, and members are never emailed. A member who wants out asks the person who booked them.


Canceling​

A cancellation is a status, not a deletion. The seats return immediately, the row leaves the dashboard roster and the check-in page, and the record survives for reporting. Deleting would free the seats too, and take the evidence with it.

An admin cancels from the dashboard roster. Canceling a group takes everyone booked under that order on that shift, so canceling Tuesday never quietly cancels the same party's Thursday.

Any check-in stamp is cleared by a cancellation, so a canceled booking cannot keep counting toward the day's attendance.

There is no undo on the dashboard, because a canceled row is filtered out of the roster and there is nothing left to click. The record is still there and an admin can set its status back by hand, but doing so does not re-check capacity, so a shift that filled in the meantime can be put over.


Step 7: Use the Engagement Dashboard​

The Engagement Dashboard is an admin tool for monitoring and managing volunteer events.

  1. Add the Liminal: Engagement Dashboard component to a Lightning App Page.
  2. The left panel shows an Overview plus sections for Events, Shops, and Volunteers.

For Volunteer engagements, the dashboard shows:

  • Metrics strip: Total Slots, Signed Up, Checked In, Checked Out, No-Show.
  • Charts: fill rate donut and volunteers-by-role bar chart.
  • Search bar: filter by name or email in real time.
  • Roster tree: Date → Role → Shift → Volunteer, all collapsible. Shows volunteer name (linked to the Contact record), email, status pill, and Check In / Check Out / Undo buttons.
  • CSV export: downloads the full roster as a CSV file.

What Gets Created After a Signup​

For each volunteer signup, four records are created:

RecordWhat it holdsWhere to find it
ContactVolunteer's first name, last name, and email. Matched by email; existing Contacts are reused.Contacts tab
OpportunityNamed Volunteer - Event - Role - email. Stage set to Prospecting. Carries volunteer details (first name, last name, email, phone, organization). Linked to the Campaign.Opportunities tab (filter by Lim Order ID starts with LIM-)
Liminal SelectionThe booking record. Status set to Ordered, linked to the Offering, Availability, and Opportunity. Start/End Datetime copied from the shift.Liminal Selections tab
Campaign MemberLinks the Contact to the Campaign with status Responded. Created once per Contact per Campaign (duplicates are silently skipped).Campaign Members related list on the Campaign

Capacity and "Spots Available"​

Capacity is shown at three levels:

  • Event card: total spots available across all roles.
  • Role card: spots available for that role across all its shifts.
  • Shift button: remaining spots on that specific shift (Max Bookings minus existing Claimed and Ordered selections).

Important: The capacity total on a role only counts Max Bookings from Availabilities where Slot Open/Close is set to Open. If you create Availabilities manually without setting this field, they won't be counted and capacity will show as 0.


Common Questions​

Can a volunteer sign up for two shifts? Yes. Capacity updates immediately after each booking.

Can a volunteer cancel? Yes, from the link in their confirmation email, once you have set a Volunteer Manage URL. See Letting volunteers manage their own sign-up. An admin can also cancel from the dashboard roster. Either way the spot frees up immediately and the record is kept.

What if the volunteer enters an email that already exists? The existing Contact is reused. No duplicate is created.

Why does the check-in page show no events? The date picker defaults to today. Make sure your Campaign's Start Date and End Date span today's date.

Why does my dashboard show 0 slots? Check that Slot Open/Close is set to Open on your Availability records. If you have many records to fix, a developer can run a quick backfill script; see the note below.

Backfill script for missing Slot Open/Close values (requires developer access)

Run the following in Anonymous Apex (Setup → Developer Console → Debug → Open Execute Anonymous Window):

List<Lim_Availability__c> avails = [
SELECT Id FROM Lim_Availability__c
WHERE Slot_Open_Close__c = null
AND RecordType.DeveloperName = 'Slot'
];
for (Lim_Availability__c a : avails) {
a.Slot_Open_Close__c = 'Open';
}
update avails;

Why is the volunteer name blank in the dashboard? The dashboard reads volunteer details from the Opportunity's order fields (First Name, Last Name, Email, etc.). If a name is blank, the Opportunity is missing those field values, usually older data created before the package populated them.


Quick Setup Checklist​

  • Engagement created in the Engagement Builder, Engagement Type Volunteer, with Start Date and End Date.
  • Status set to Published.
  • Hero image and address set in the builder.
  • At least one role, with shifts: record type = Slot, Slot Open/Close = Open, Start/End Datetime within the Campaign window, Max Bookings set.
  • Volunteer Signup component placed on a Lightning or Experience page.
  • Guest user profile granted the Lim_VolunteerController Apex class, and nothing else.
  • Volunteer Site URL recorded in FL Liminal settings.
  • Sender Email set to a verified Org-Wide Email Address.
  • Volunteer Manage URL set, and the manage page published (optional, enables self-service).
  • Group sign-ups turned on and a mode chosen (optional).
  • Volunteer Check-In component placed on a staff-facing page (optional, and behind authentication).
  • Engagement Dashboard placed on an admin page (optional).
  • End-to-end test completed in an incognito browser.