Searching for jobs in todayâs age of AI and fake job postings can be exhausting. Without a referral or âknowing a guyâ youâre stuck cold applying to companies that are likely using AI tools to filter results. The landscape has changed dramatically, but that doesnât mean all is lost. In fact, you can employ the same AI tools large companies use to help you scale your job search efforts. Instead of spending hours combing through postings on Indeed, let Google Workspace Studio search for openings and create a database for you.
Hereâs what youâll need to get started:
- Google Sheets: This will be your database.
- Google Workspace Studio: This is the automation engine that searches jobs and populates your database.
- Google Apps Script (optional): This will be used to format the data from Gemini.
How It Works
Google Workspace Studio passes the below prompt into Gemini. Feel free to tweak it to suit your needs. However, if you change the column names, youâll need to do so in Apps Script. More on that later.
The Prompt
Role:
You are a Professional Technical Recruiter and Data Analyst specializing in Remote CRM and Automation roles. All roles must be United States based and fully remote.
Objective:
Scrape and identify active, remote-only job listings for the following roles:
CRM Developer (Dynamics / Salesforce)
CRM Admin
IT Director
Business Systems Admin / Developer
Python Developer
Automation Engineer
Power Automate / Power Apps Developer
Data Requirements:
Search across LinkedIn, Indeed, and specific company Careers pages.
Only include actual job listings with verifiable details.
If a specific data point (such as Phone or Email) is not listed, enter "N/A".
For Salary, only use the range explicitly stated in the job listing.
Provide the Direct Job Link (the URL where the application lives).
Formatting Rules (CRITICAL for Automation):
Output each job using the exact label format below.
Every line must end with a pipe symbol (|) so a Google Sheets script can parse the data.
Do not include any introductory or concluding text.
Start immediately with "Company:"
Company: [Name] |
Job Title: [Text or N/A] |
Phone Number: [Number or N/A] |
Email: [Email or N/A] |
Description: [2-3 sentence summary of core duties] |
Salary Range: [Amount or N/A] |
Date Posted: [Date or Timeframe] |
Keywords for Resume: [Comma separated list of tech stack/skills] |
Job Link: [Full URL] |
Once this prompt is passed into Gemini itâll start searching for jobs and contracts in accordance with the guidelines you defined. Once itâs done its work, youâll get a notification via email letting you know itâs found new opportunities.
Next, it takes the information it found and adds it into a Google Sheets doc for review. Finally, this part is optional. Apps Script takes that giant block of text and splits it into human-readable columns and rows. Hereâs a high-level overview of the process.
- At a predefined interval your prompt is passed to Gemini.
- Gemini executes your job search.
- It deposits results in a spreadsheet.
- You receive an email letting you know there are new opportunities to review.
- Apps Script cleans up the extracted data.
Google Sheets: The Database
This is going to serve as your CRM. All your prospects will be stored here along with their names, email addresses, salary ranges, job titles, and more. At a minimum youâll want to structure the table housing your data as follows:
| Company |
| Phone Number |
| Description |
| Salary Range |
| Date Posted |
| Keywords |
| Job Link |
Google Workspace Studio: The Automation Engine
While not as robust as tools like Power Automate and n8n, Google Workspace Studio has just enough functionality and integrations to make some seriously useful workflows. It is the engine that powers the data extraction and entry. A task that takes hours for us humans to do and is extremely error-prone as you pile on more data.
Once youâve created the spreadsheet, itâs time to include it in your flow.
Note: Make sure you create the spreadsheet within the same account Workspace Studio resides in.
Hereâs an overview of the Job Extraction workflow.
- On a schedule: I like to set this after my workouts during the week. So mine comes in at 7:30 AM.
- Ask Gemini: Using the prompt I gave you above, Gemini will start its job search.
- Notify me by email: I prefer email but you have the option of getting a message on Google Chat as well.
Add a row: This is where prospects are stored. Be sure to choose the right sheet if you have multiple. And, if youâre keen on preserving history, choose the âAfter last data rowâ option in the Add row section.
Cleaning and Formatting Data: Apps Script (optional)
This step is optional but recommended so your data doesnât come in as giant blocks of text. To enable Apps Script in your Sheets, select the Extensions option in the top menu. Next, click Apps Script.
Next, youâll be taken to the Apps Script editor and given some boilerplate JavaScript code. Delete that and replace it with this.
/**
* Adds a custom menu to the Google Sheet toolbar.
*/
function onOpen() {
const ui = SpreadsheetApp.getUi();
ui.createMenu('Job Portal')
.addItem('Sync All Jobs Now', 'processFullJobSuite')
.addToUi();
}
/**
* Main Function:
* 1. Finds raw data in Column A.
* 2. Extracts fields based on your Gemini template.
* 3. Appends new unique jobs to the bottom.
* 4. Deletes the original raw data rows to remove gaps.
*/
function processFullJobSuite() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
// 1. Setup Headers (only if row 1 is empty or missing headers)
const headers = ["Company", "Job Title", "Phone Number", "Email", "Description", "Salary Range", "Date Posted", "Keywords", "Job Link", "Reliability Score"];
if (sheet.getLastRow() === 0 || sheet.getRange(1,1).getValue() === "") {
const headerRange = sheet.getRange(1, 1, 1, headers.length);
headerRange.setValues([headers]);
headerRange.setFontWeight("bold").setBackground("#f3f3f3").setVerticalAlignment("middle");
}
// 2. Map existing Job Links to prevent duplicates
// We look at Column I (Index 8) where the Job Link is stored
const currentValues = sheet.getDataRange().getValues();
const existingLinks = currentValues.map(row => row[8] ? row[8].toString().toLowerCase().trim() : "");
let allExtractedRows = [];
let rowsToDelete = [];
// 3. Iterate through rows from BOTTOM to TOP
// This is critical for deleting rows without messing up the numbering
for (let i = currentValues.length - 1; i >= 1; i--) {
let cellContent = currentValues[i][0].toString();
// Check if the cell contains the keyword "Company:"
if (!cellContent || !cellContent.includes('Company:')) continue;
// Split cell into individual job blocks (handles multiple jobs in one cell)
let jobBlocks = cellContent.split(/(?=Company:)/g);
for (let block of jobBlocks) {
if (block.trim() === "" || !block.includes(':')) continue;
// Helper function to extract text after a label and before a pipe or newline
const getVal = (label) => {
const regex = new RegExp(label + ":\\s*([^|\\n]+)");
const match = block.match(regex);
return match ? match[1].trim() : "N/A";
};
let jobLink = getVal("Job Link");
let uniqueKey = jobLink.toLowerCase().trim();
// DUPLICATE CHECK: Skip if this URL is already in our list
if (jobLink !== "N/A" && existingLinks.includes(uniqueKey)) continue;
let company = getVal("Company");
let jobTitle = getVal("Job Title");
let phone = getVal("Phone Number");
let email = getVal("Email");
let description = getVal("Description");
let salary = getVal("Salary Range");
let datePosted = getVal("Date Posted");
let keywords = getVal("Keywords for Resume");
// Calculate Reliability Score
let score = 0;
if (company !== "N/A") score += 20;
if (jobTitle !== "N/A") score += 20;
if (salary !== "N/A") score += 20;
if (jobLink !== "N/A") score += 20;
if (description.length > 50) score += 20;
allExtractedRows.push([
company,
jobTitle,
phone,
email,
description,
salary,
datePosted,
keywords,
jobLink,
score + "/100"
]);
}
// Mark this row for deletion
rowsToDelete.push(i + 1);
}
// 4. Append the extracted jobs to the bottom of the table
if (allExtractedRows.length > 0) {
const startRow = sheet.getLastRow() + 1;
// We reverse it back because we collected them while looping backwards
allExtractedRows.reverse();
const outputRange = sheet.getRange(startRow, 1, allExtractedRows.length, headers.length);
outputRange.setValues(allExtractedRows);
// Formatting for readability
outputRange.setVerticalAlignment("top").setWrap(true);
sheet.autoResizeColumns(1, headers.length);
sheet.setColumnWidth(5, 400); // Set Description width to 400px
}
// 5. Delete the original raw rows (removes white space/gaps)
if (rowsToDelete.length > 0) {
rowsToDelete.forEach(rowNum => {
sheet.deleteRow(rowNum);
});
}
}
Hit CTRL + S or CMD + S to save your script. Next, click the Triggers option.
Select the +Add Trigger button. Next, fill in the fields as outlined below.
The purpose of this section is to tell Apps Script to run the processFullJobSuite function every minute on the data in your Job Search database. Finally, if it fails for any reason, it needs to notify you each time. The most common reason for failure is altering the column names or table structure. The names of the columns are hard-coded in, so changing them results in your code getting confused and bombing out.
Why is this better than job alerts
You might be wondering why you should go through all of this instead of subscribing to job alerts from the various sites. There are two important reasons to go this route over the native subscriptions to Indeed, Glassdoor, etc. Privacy and Efficiency. The first reason is arguably the most important.
Each time you log into one of these sites, your information is tracked and depending on the site, sometimes sold. This results in dozens of unsolicited emails, calls, and text messages. Itâs a gross violation of privacy and can be very risky from a security perspective. By employing this automation, job sites arenât tracking you. Instead, you are tracking job sites.
You cherry-pick the companies you actually are interested in and provide them with your resume and contact information when you feel comfortable doing so. This is not only secure but highly efficient. You control what types of jobs you want to see by allowing Gemini to filter out ones that arenât a good fit for you.
Once prospects are found, a database is filled with leads you can start contacting. Instead of blindly spamming resume uploads, you are conducting targeted searches on qualified leads. You regain control of the job hunt by creating a sales pipeline.
Automate your way into a bigger bank account
Companies are adopting AI at a record pace. To stay competitive and relevant in the job market, youâll need to do the same. While many automation tools like Power Automate and UI Path are expensive and complicated, Google Workspace Studio is extremely easy to use and relatively inexpensive. Take advantage of enterprise-grade automation and AI with Gemini and take your job hunt to the next level.
If youâre interested in automating more of your workday, check out how I built a free alternative to SEMRush vibe coding with Googleâs AI Studio. Read it here.