Posted by Dave Averdick on July 18, 2022
The Many Ad Agency wanted to upgrade their careers page which was currently using a simple embedded version of the Greenhouse Job Board on their website. They wanted the job board to better integrate with their website and brand to help fill a large number of job openings.
The goal was to allow The Many to continue to curate and post job openings on Greenhouse and have these posts automatically update on their website, which is built with WordPress.
Here’s how we did it:
Greenhouse has an API and webhooks that we utilized to automatically create, delete and update posts on wordpress. The webhooks fired any time a new job post was created, when a job post was updated and when one was removed. These webhooks triggered several functions that then used the Greenhouse API to check the current status, then made the appropriate updates to the WordPress posts.
You can read about how to create your API credentials and how to use the Greenhouse API here:
Information about webhooks can be found here:
We created a custom post type of “Careers” on WordPress which will have one post for every job opening shown in Greenhouse. The challenge here was mapping the data from Greenhouse to custom fields created with Advanced Custom Fields. Some of the data from Greenhouse could be “repeating data”, nested, etc. We had to study the way Greenhouse had organized their data in their API payload, then build fields that matched these.
This is a fairly tedious process – and to save you the trouble, you snag our ACF JSON, which can then be uploaded via ACF Tools tab to build your fields automatically below. Copy the code, paste into a JSON doc and upload.
Just to be sure our data is in sync with Greenhouse, we run a cron task every 6 hours to check in with their API. Greenhouse does say in their docs that the Webhooks won’t always fire, so this is a good practice. Granted, from our experience they are pretty reliable.
Setup the cron job:
In the cron job above, you’ll see we are calling a function called gh_get_all_jobs(). This function is what calls the API. Below you can see the code, remember to replace “[your_board_name]” in the CURLOPT_URL line.
We now have all of the job data from Greenhouse via the API call in the last step. Now we must process this data, and you’ll see we call “gh_process_job_posts” and pass the data.
Below you’ll see we first determine the number of jobs in the data we received from Greenhouse, then we loop through all of these, and do the following:
That last step might not be obvious in terms of the why. But here’s the deal – the webhook should get triggered and automatically delete the post, but if this for some reason fails – during this 6 hour check the API simply won’t contain that job ID – thus we need to create the array of job IDs from Greenhouse, then compare those with what we have. If we have any job posts that don’t match the live job IDs from Greenhouse, then we need to delete it.
Before we update or create a post, we’ll want to do another API call – this time to get detailed data about this individual job post. The previous API call that gives us information about all the active job openings doesn’t include all of the details we need.
Additionally we need to add a query param to the request, ?questions=true. This tells Greenhouse to provide application questions – which we can then use when building the application form.
In the code below you’ll see where we’ve passed 3 parameters to the function, $job_id, $action, $post_id. The $job_id is used in the API call. The $action is either “create” or “update”, this determines what is done with the data after it’s fetched. The $post_id is passed if the action is “update”.
Remember to change [your_board_name].
Okay finally, we can now create a job post after all of that. In the code below you’ll see where we loop through some of the data up top to standardize the formatting. From there, we’re using WordPress’s API to create a post. You’ll need to update the domain name, username, and application password to be your own.
As a bonus, if you are using the plugin All In One SEO and wish to customize the SEO headline and description for the post, you’ll see how you can do so. Otherwise, delete or comment out those lines as you won’t need them.
The function for updating the job post is almost identical to the function for creating the job post. You can see the code here:
Finally, the last piece of the puzzle, setting up the webhooks. You’ll see in the code, first we register the webhook, then we used the function greenhouse_webhooks to determine what the webhook contained based on the “action” and then make the appropriate adjustments based on the action type.