Your Salesforce organization has a need to place users by profile into public groups for use in sharing rules, reports, dashboards. etc. The roles in your org do not neatly map one to one to a profile and you don’t want to get into the business of manually adding/removing people to and from a group when they get created and if users change profiles. I foresee a maintenance nightmare up ahead.
Have no fear, you can automate the assignment of a user to the appropriate public group based on the user’s profile. This can be all done declaratively, no code involved, with public groups, sharing rules, process builder, visual workflow and a custom metadata type.
Quick sidebar on custom metadata types, this is a great feature to add to your admin toolset. If you like custom settings, you will like custom metadata types.
Custom metadata types are new to Salesforce, introduced in Winter 16.
Custom metadata is customizable, deployable, packageable, and upgradeable application metadata. First, you create a custom metadata type, which defines the form of the application metadata. Then you build reusable functionality that determines the behavior based on metadata of that type. Similar to a custom object or custom setting, a custom metadata type has a list of custom fields that represent aspects of the metadata. Unlike custom settings, the record data is metadata and can be deployed with the custom metadata type in a Change Set. No more exporting the related data and importing it to the destination org as you would do when deploying a custom setting.
For more information on custom metadata types, visit Salesforce Help & Training.
Here are a few lessons learned from implementing this use case:
- There is currently a known issue with custom metadata types using a checkbox always returning false. You have to limit the field API name to less than 30 characters and the checkbox will return the proper value.
- Data records associated with a custom metadata type are deployable via a changeset. You can locate the data records by looking for the custom metadata type’s name under the Component list. Do not look for it under Custom Metadata Type. Thanks, Mohith Shrivastava for helping me with that.
- You don’t need to “hardcode” ID references in your visual workflow. This can be avoided with a record lookup and a couple of variables
- Provide descriptions, where provided, in Salesforce. This may be tedious step, I know, but your future self will thank you when you are trying to remember what you configured or assist other/future admins when troubleshooting or enhancing what was built. This includes noting the data stored in a custom field, where a visual flow is invoked from, the purpose of a flow variable, etc.
- For any data actions (fast and record lookup, create, update and delete actions) performed in visual workflow, best practice is to include a flow element to send an email to your Salesforce administrator about the fault.
Flow trick: To getting the Fault connector to appear, either draw the regular connector link to another flow element or connect it to a temporary flow element. Draw the fault connector to the Send Email element. Then, go back and delete the regular connector.
Business Use Case: Addison Dogster is a system administrator at Universal Container. Sammy Sunshine, the business sponsor, would like users in the same profile to be associated to the same group.
Solution: Addison was able to address Sammy’s requirements all through declarative actions, no code. Her solution involves a creation of public groups, custom metadata type, process builder and a visual flow.
Quick Steps:
1. Create a public group for each profile (Manage Users | Public Groups). In our example, we have three profiles – ProfileA, ProfileB and ProfileC.
2. Create a Custom Metadata Type (Develop | Custom Metadata Types), click on the “New Custom Metadata Type” button.
A. Provide the label name and label name in plural and save.
Best Practice Tip: Don’t forget to provide a description so you and other/future admins know what this custom metadata type is used for.
B. Create a custom field as a checkbox data type for each public group created in Step 1
Best Practice Tip: Don’t forget to provide a description so you and other/future admins know what this custom metadata type is used for.
C. You can organize the new custom fields into their own Public Group Assignment section on the Custom Metadata Type page layout.
D. Now, we need to create the data records for each profile to indicate which public group will be assigned to which profile. Click on the “Manage Profile Public Groups” button.
E. Now, you create a data record for each profile and its associated public group. Provide the Master Label, Object Name (same as Master Label) and the appropriate checkbox, and save.
F. Create a custom view that shows the public group assignments for ease of review.
We’ve configured ProfileA to be associated with the ProfileA-Public Group, ProfileB to be associated with the ProfileB-Public and ProfileC to be associated with the ProfileC-Public Group.
3. Create a Custom Metadata Type to store the SFDC IDs for the public groups (Develop | Custom Metadata Types), click on the “New Custom Metadata Type” button.
A. Provide the label name and label name in plural and save
Best Practice Tip: Don’t forget to provide a description so you and other/future admins know what this custom metadata type is used for.
B. Create a custom field as a text data type for each public group created in Step 1.
Best Practice Tip: Don’t forget to provide a description so you and other/future admins know what this custom metadata type is used for.
C. You can organize the new custom fields into their own Public Group IDs section on the Custom Metadata Type page layout.
D. Now, we need to create one data record to store the public group IDs. Click on the “Manage Public Group IDs” button.
Create a data record called OrgPublicGroupID (Master Label and Object Name) and provide the 18 character SFDC ID for each public group name.
Need help with obtaining the SFDC ID for the public group?
1.Navigate to the public group record.
2.Copy the SFDC ID in the browser window – highlighted in below screenshot
3. Place it in a converter tool to convert the 15 character SFDC ID to the 18 character SFDC ID.
4. Since Process Builder does not allow for the creation/update of records in Public Groups, we need to enlist the help of Visual Workflow (Create | Workflow & Approvals | Flows). In the following steps, we will build the flow out to look like the below.
A. Create the following 10 variables to match the screenshots below. These will be used in the various flow elements that we will create. This can be done by going to the Resources Tab and creating a variable.
Best Practice Tip: Don’t forget to provide a description so you and other/future admins know what these variables are used for.
B. Create a formula which will take the public group assignment for the user’s profile and then determine the associated public group’s SFDC ID.
Formula:
If ({!varProfileAPublicGroup}=true, {! varProfileAGroupID},
If ({!varProfileBPublicGroup}=true, {! varProfileBGroupID},
If ({!varProfileCPublicGroup}=true, {! varProfileCGroupID}, null
)))
Best Practice Tip: Don’t forget to provide a description so you and other/future admins know what this formula is used for.
C. Create a Record Lookup flow element to lookup the public group IDs as stored in the Custom Metadata Type where the data record’s Master Label is “OrgPublicGroupID”. Once found, it will take the values from the ProfileA-PublicGroup, ProfileB-PublicGroup and ProfileC-PublicGroup and store them in a flow variable.
Best Practice Tip: Don’t forget to provide a description so you and other/future admins know what this flow element is used for.
D. Set this Record Lookup flow element as the starting element.
E. Let’s perform another Record Lookup where we will lookup a user’s specific group. Here we will look in the GroupMember object (this contains the user or group’s assignment to a public group). We want to lookup a record where the UserorGroupId field matches the user’s ID and is associated to either one of the three Profile Group IDs. Once found, we are storing the GroupID value to the variable varUserAssignedPublicGroupID.
Best Practice Tip: Don’t forget to provide a description so you and other/future admins know what this flow element is used for.
F. Add a Decision flow element. We need the flow to determine whether a user is part of a profile public group (if the varUserAssignedPublicGroupID variable has a value). Otherwise, the user is not part of a public group.
Best Practice Tip: Don’t forget to provide a description so you and other/future admins know what this flow element is used for.
G. We now need another Record Lookup flow element to look up the user’s associated profile’s developer name. This performs a lookup on the Profile object where the Id matches the variable varUserProfileID. Once found, it will store the value in the Name field (Profile Developer Name) in the variable varProfileDeveloperName. We will use this later to assign the profile public group.
Best Practice Tip: Don’t forget to provide a description so you and other/future admins know what this flow element is used for.
H. Create a Record Delete flow element. If a user has an existing profile public group and has changed profiles, we want to remove the user from the previous public group. It will delete the record in the GroupMember object where the UserorGroupID is the current user and the GroupId matches the value stored in varUserAssignedPublicGroupID.
Best Practice Tip: Don’t forget to provide a description so you and other/future admins know what this flow element is used for.
I. From the Decision flow, draw the “Public Group Found” connector to the Record Delete flow element and the “No Public Group” to the Record Lookup – Lookup Profile Information so it looks like this below.
J. We will do another Record Lookup to the Custom Metadata Type where we stored the profile public group assignment by profile. We will locate the data record where the Master Label matches the user’s profile. Once found, it will take the public group assignments (true/false) and store them into their respective variables.
Best Practice Tip: Don’t forget to provide a description so you and other/future admins know what this flow element is used for.
K. Next, we has a Record Create flow element that will assign the user to his/her profile public group. The UserorGroupId field is the user’s ID and the GroupId is the formula UserToBeAssignedToPublicGroupFormula.
Best Practice Tip: Don’t forget to provide a description so you and other/future admins know what this flow element is used for.
L. As a best practice, where there is a DML action (fast or record create, update, delete or lookup action) in a flow, you should also include notification of a flow fault.
I create a single Send Email fault to keep the flow relatively clean, but depending n your use case, you may want individual Send Email faults for each DML. I would say, start small with one and then build individual, if the need arises.
Note: To avoid “hardcoding” email addresses in a fault email, refer to a post Using Custom Metadata Type in Visual Workflow Fault Emails.
Select the Send Email flow element that is listed under Static Actions, not under Quick Actions.
Configure the body to show the fault message, subject and email address(es).
Body: Fault Message: {!$Flow.FaultMessage}
Subject: Error – Update Person Account Mailing Address
Best practice tip: Don’t forget to provide a description so you and other/future admins know what this send email element is supposed to do.
You will need to draw a connector line between the Record Lookup, Record Update and Send Email elements.
Can’t seem to get the fault connector to appear? Create a temporary flow element (circled below), draw your first connector to that temporary flow element. Then, draw another connector to the send element. This connector has the word “FAULT” in it.
Once that is completed, delete the temporary flow element you created. This is the end result.
M. Click on the Save button and provide the following information
Best Practice Tip: Don’t forget to provide a description so you and other/future admins know what this visual workflow is for.
N. Click the “Close” button.
O. On the flows screen, activate the flow.
5. Create the assignment process with Process Builder (Create | Workflow & Approvals | Process Builder).
A. Provide your process name, description and save.
B. For the Object, select User and the process should execute when a record is created or edited.
C. We want to specify the criteria to execute when a user is new or if the user’s profile ID is changed. Since there is no ability to specify “Is New” via point and click – as Is New is not a user object field, we need to go the formula route.
Formula: ISNEW() || ISCHANGED([User].ProfileId)
Note: the “||” means or. So the formula reads, the user record is new OR the user’s profileID has changed.
D. Once the criteria is met, we want to execute an Immediate Action of assigning the public group. Since process builder does not provide the ability to create a public group record, we will need to invoke the help of visual workflow (created in Step 4).
We will pass two variables to the visual workflow. User’s ID in the varUserID and the user’s profileID in the varUserProfileID.
E. Click the Save button.
F. Click the Activate button in the upper right hand corner. Click the “Ok” button.
Congrats, you’ve implemented the solution!
Now, before you deploy the changes to Production, you need to test your configuration changes.
- Create a new user.
- Upon save, confirm the user is associated to the correct profile public group.
- Change to another profile
- Repeat the above steps 2-3 until you’ve confirmed each profile.
- Create a new user associated to each profile.
- Upon save, confirm the user is associated to the correct profile public group.
Deployment Notes/Tips:
- The two custom metadata types and associated data records, visual flow and process builder can be deployed to Production in a change set.
- You will find the custom metadata type information under the Custom Metadata Type in the Component Type dropdown. However, locate the data records for the custom metadata types by looking for the custom metadata type names in the Component Types dropdown.
- You will find the process builder and visual workflow components in a change set under the Flow Definition component type.
- Activate the visual flow and process builder after they are deployed in Production as they are deployed as inactive.
Jen, I’m wondering if a shortened version of this flow could auto assign a custom profile to a customer/community user, based on account status.
For example, a “Gold” level account would have 24 hour support. The primary contact of that account would be a customer/community user with a custom profile called “Customer Community Gold User.”
The desired outcome would be a flow that would auto assign all customer/community users the “Customer Community Gold User” profile if their associated account had 24 hour support. 24 hour support is already a checkbox on the Account.
Just thinking out loud here. Main question is could I do this without creating a public group.?
LikeLike
You can create a process that will then launch a flow to update the user’s profile Id to the custom community profile. I dont believe you can update the user record within a process. You dont need public groups. That was just a use case to assign users of a given profile automatically to public groups.
LikeLike