The applicant portal of SAP SuccessFactors Recruiting does not have the most modern UI, nor is there any real way of customizing the user experience. Which is why many companies end up developing various add-ons/plug-ins in order to add new features to the portal. Examples for such applications can be found in the SAP app center and range from quick apply solutions to video interview integrations.
If applicants should be able to jump from the applicant portal into the add-on, you will need to pass something to add-on that let’s it know which applicant it is. So you need to extract some sort identifier from the applicant portal before the user jumps over to your custom integration. I have seen plug-ins that use the applicant’s email address, since it can be easily extracted from the corresponding input field.
This, however, has two downsides: Firstly, it means that the user can only jump to your add-on from a page that contains the “Contact email”-field. Secondly, it results in you sending personally identifiable information to the add-on. Sending PII to a third party usually requires some sort of legal framework that clarifies how the data is processed and/or stored by the third party. So, in order to keep legal costs down and simplify your implementation, you might want to use the candidate or application id instead.
The Component._registry
During my work with the applicant portal, I discovered the JavaScript component/object that Recruiting Management, which the applicant portal is a part of, uses to store all of the data it needs.
The object can be accessed by logging into any SuccessFactors applicant portal, opening your browser’s developer tools and typing Component._registry
in the console before hitting enter. Your browser will then show you the object in the console.
Structure of the Component._registry object
As you can see in the screenshot above, the Component._registry object has a somewhat strange structure to it. It’s properties (all objects themselves) have keys similar to array indexes followed by a colon. So, unfortunately, finding the candidate id or an application id is not as simple as accessing Component._registry.candidate.id
.
Also, the registry neither contains the same properties every time nor are the properties in any particular order. Thus, you cannot use Component._registry['56:']
just because that’s where you found the candidate information last time.
You will have to loop over the properties of the registry in order to find what you are looking for.
Finding the candidate id
Let’s first look at how to find and extract the candidate id. There are several objects in the registry that contain the candidate id somewhere in their properties. However, the easiest to work with and probably the most obvious are instances of RCMCandJobsInformation
and RCMProfileInformation
. They both contain a config
property that contains the desired candidateId
.
We will focus on the RCMCandJobsInformation
object, because SuccessFactors adds a RCMProfileInformation
instance without a candidate id to the registry when a user is on the “Apply”-page.
Let’s build a small function that extracts the candidate id with what we have learned. It could look something like this:
function getCandidateIdFromRegistry() {
// Find the first instance of an object containing the candidate id
var containingObject = Object.values(Component._registry).find(object => object instanceof RCMCandJobsInformation);
// If a containing object was found, get the candidate id from the object and return it
if (typeof containingObject !== 'undefined') return containingObject.config.candidateId;
}
Please note: The above function will not return anything for a user who is in the application process. However, we will get back to this.
Finding the application id
Now that we know how to get the candidate id, let’s look into how we can get an application id. Notice that I wrote “an” application id, not “the” application id. That’s going to be be imported because while you find the candidate id in several places, there is only one. The same cannot be said for the application id(s). As the user navigates through the applicant portal, they might submit a new application, look at a previously saved draft and/or look at an application they submitted earlier. At each of those steps, the Component._registry
will contain a different application id.
The objects containing the application id are instances of RCMJobSpecificInfo
.
So, we now know where to retrieve the application id from. However, SuccessFactors makes it just a little more difficult to retrieve the application id during the application process: When a user enters the “Apply”-page, the portal immediately adds an instance of RCMJobSpecificInfo
to the registry. But because the user can just now start to fill out the application fields, no application has been created yet. Thus, that first instance of RCMJobSpecificInfo contains an applicationId
of -1
. An application id is only assigned if and once the user either saves the application as a draft or submits it. Either action creates a new RCMJobSpecificInfo
object in the registry. So, in order to get the real application id if one has been assigned, we are going to search the registry in reverse order. That way, we either get a real application id we can work with or the initial -1
application id and we know that the user has neither saved nor submitted their application yet.
Here’s a function that put’s everything together:
function getApplicationIdFromRegistry() {
// Find the last instance of an object containing an application id
var containingObject = Object.values(Component._registry).reverse().find(object => object instanceof RCMJobSpecificInfo);
// If a containing object was found, get the application id from the object and return it
if (typeof containingObject !== 'undefined') return containingObject.config.applicationId;
}
A quick note on extracting the application id after the user saves a draft: SuccessFactors will display a “draft application saved”-message. The real application id seems to be added to the registry only after/as that message disappears. So be careful what event you use to trigger the extraction.
Finishing touches
Remember that I mentioned we would get back to extracting the candidate id during the application process? You might have already spotted where we find it while on the “Apply”-page: In the RCMJobSpecificInfo
object(s).
Now we need to change one last thing. As you can see in the screenshots, all of the objects we looked at so far contain both a config
and a _config
with the same data. This works fine on both the “Profile” and the “Apply”-page. On the “Settings”-page, however, you will only find object containing the candidateId
in their _config
property. And, because it’s SuccessFactors, the candidate id is stored as a string in those objects (all other objects store it as an integer).
So, in order to get our function to work on the settings page, we need to switch to using the _config
rather than the config property and we need to add our new object types to our .find
-condition. Also, let’s convert the candidate id to an integer so our function always returns the same type.
Here is a version of getCandidateIdFromRegistry
that takes all that into consideration:
function getCandidateIdFromRegistry() {
// Find the first instance of an object containing the candidate id
// Skipping an instances of relevant object that do not contain a candidate id
var containingObject = Object.values(Component._registry).find(object => object instanceof RCMCandJobsInformation || object instanceof RCMJobSpecificInfo || object instanceof RCMCareerAccountManagementPage);
// If a containing object was found, get the candidate id from the object and return it
if (typeof containingObject !== 'undefined') return parseInt(containingObject._config.candidateId);
}
Where/when do these functions work?
The getCandidateIdFromRegistry
-function works:
- on the “Profile”-page
- on the “Settings-page
- on the “Apply”-page
- after opening an application draft (since this lead to the “Apply”-page)
- after opening a submitted application (the page seems to be a slightly different version/rendering of the “Apply”-page)
The getApplicationIdFromRegistry
-function works:
- on the “Apply” page, once/if the user saved or submitted the application
- after opening an application draft (see above)
- after opening a submitted application (again, see above)
Please note that both functions only work in the Recruiting Management applicant portal. Neither will allow you to get an id while the user is still on the Recruiting Marketing (RMK)/Career Site Builder (CSB) portal. That portal is basically “read-only” and does not receive any candidate/application data as far as I am aware.