(+91)7275894867 [email protected]
OutRightCRM Login
📅 Published on August 16, 2024 ✏️ Updated on April 22, 2025

Mastering SEO : Free Apps Script for Bulk Audit Spreadsheet Backlinks

Author Avatar
Author
Editorial Team

Mastering SEO : Free Apps Script for Bulk Audit Spreadsheet Backlinks

Master SEO effortlessly with a free Google Apps Script to bulk audit backlinks in a spreadsheet. Import URLs, and the script checks their status, response codes, and anchor texts using fetch requests or APIs. Ideal for monitoring link health, identifying broken links, and optimizing your backlink strategy at scale.
  1. Step 1: Click on the Copy button to copy the code snippet.
  2. Step 2: Paste the copied code into your project’s script editor.

Apps Scripts Blog

Read Blog

Apps Scripts Code

function onOpen() {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('Scan and Check')
    .addItem('Scan and Check', 'scanAndCheck')
    .addToUi();
}




function scanAndCheck() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var data = sheet.getDataRange().getValues();


  var successUrls = [];
  var failedUrls = [];
  var invalidUrls = [];


  // Store visited domains to skip redundant checks
  var visitedDomains = [];


  // Add a column for "Status on Current Date" if it doesn't exist
  var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
  var statusColumnIndex = headers.indexOf("Status on Current Date");
  if (statusColumnIndex === -1) {
    statusColumnIndex = headers.length + 1;
    sheet.getRange(1, statusColumnIndex).setValue("Status on Current Date");
  }


  var currentDate = new Date();
  var year = Utilities.formatDate(currentDate, "GMT", "yyyy");
  var month = Utilities.formatDate(currentDate, "GMT", "MM");
  var day = Utilities.formatDate(currentDate, "GMT", "dd");
  var formattedDate = day + "-" + month + "-" + year;


  // Check if the date has already been set
  var dateAlreadySet = false;
  for (var i = 1; i < data.length; i++) {
    var statusValue = sheet.getRange(i + 1, statusColumnIndex).getValue();
    if (statusValue && statusValue.includes(formattedDate)) {
      dateAlreadySet = true;
      break;
    }
  }


  // Set the date at the top of the "Status on Current Date" column if not already set
  if (!dateAlreadySet) {
    sheet.getRange(1, statusColumnIndex).setValue(formattedDate);
  }


  // Add a new column for the status
  var statusTextColumnIndex = statusColumnIndex + 1;
  sheet.getRange(1, statusTextColumnIndex).setValue("Status");


  for (var i = 1; i < data.length; i++) {
    var url = data[i][0];


    // Check if the URL is empty
    if (!url) {
      continue; // Skip empty rows
    }


    // Validate the URL
    if (!isValidUrl(url)) {
      // Skip invalid URLs and mark them as "Invalid"
      invalidUrls.push(url);
      sheet.getRange(i + 1, statusTextColumnIndex).setValue("Invalid domain").setFontColor("blue");
      continue;
    }


    // Check link validity
    checkLinkValidity(url, i, statusColumnIndex, statusTextColumnIndex, sheet, successUrls, failedUrls, visitedDomains);
  }


  // Display results in an alert
  var resultMessage = "Successful URLs with outrightcrm.com backlink:\n" + successUrls.join("\n") + "\n\nFailed URLs:\n" + failedUrls.join("\n") + "\n\nInvalid URLs:\n" + invalidUrls.join("\n");


  // Show alert in the browser
  var ui = SpreadsheetApp.getUi();
  ui.alert('Scan Results', resultMessage, ui.ButtonSet.OK);
}


function checkLinkValidity(url, rowIndex, statusColumnIndex, statusTextColumnIndex, sheet, successUrls, failedUrls, visitedDomains) {
  try {
    var response = UrlFetchApp.fetch(url);
    var statusCode = response.getResponseCode();
    if (statusCode == 200) {
      // Task 1: Scan URL
      // Perform actions for scanning the URL (you can replace this with your own logic)


      // Task 2: Check if the URL is from the self website or outside website
      var isSelfWebsite = url.startsWith("https://outright") || hasBacklink(url, "outrightcrm.com");
     
      // Store the results
      if (isSelfWebsite) {
        successUrls.push(url);
        // Update the "Status on Current Date" column for success with today's date
        sheet.getRange(rowIndex + 1, statusColumnIndex).setValue("Targeted Url").setFontColor("green");
        // Update the new "Status" column with "Successful"
        sheet.getRange(rowIndex + 1, statusTextColumnIndex).setValue("backlink found").setFontColor("green");
      } else {
        failedUrls.push(url);
        // Update the "Status on Current Date" column for failure with today's date
        sheet.getRange(rowIndex + 1, statusColumnIndex).setValue("Outside Website").setFontColor("red");
        // Update the new "Status" column with "Failed"
        sheet.getRange(rowIndex + 1, statusTextColumnIndex).setValue("No backlink found").setFontColor("red");
      }


      // Mark the domain as visited
      var domain = getDomain(url);
      visitedDomains.push(domain);
    } else {
      // Handle non-200 status code
      failedUrls.push(url);
      // Update the "Status on Current Date" column for failure with today's date
      sheet.getRange(rowIndex + 1, statusColumnIndex).setValue("Failed (Non-200)").setFontColor("red");
      // Update the new "Status" column with "Failed"
      sheet.getRange(rowIndex + 1, statusTextColumnIndex).setValue("Failed (Non-200)").setFontColor("red");
    }
  } catch (error) {
    // Handle fetch error
    failedUrls.push(url);
    // Update the "Status on Current Date" column for failure with today's date
    sheet.getRange(rowIndex + 1, statusColumnIndex).setValue("Failed (Error)").setFontColor("red");
    // Update the new "Status" column with "Failed"
    sheet.getRange(rowIndex + 1, statusTextColumnIndex).setValue("Failed (Error)").setFontColor("red");
    Logger.log('An error occurred while checking the link validity: ' + error);
  }
}


// Function to extract domain from URL
function getDomain(url) {
  var match = url.match(/^(?:https?:\/\/)?(?:[^@\n]+@)?(?:www\.)?([^:\/\n?]+)/);
  return match ? match[1] : null;
}


// Function to check if the URL has a backlink to outrightcrm.com
function hasBacklink(url, domain) {
  // Implement logic to check if the URL has a backlink to the specified domain
  // You may use regular expressions or other methods
  var urlContent = getContentFromUrl(url);
  var regex = new RegExp('outrightcrm\\.com', 'i');
  return regex.test(urlContent);
}


// Function to get content from a URL
function getContentFromUrl(url) {
  try {
    var response = UrlFetchApp.fetch(url);
    return response.getContentText();
  } catch (e) {
    // Handle any errors or return an appropriate value
    Logger.log("Error fetching content from URL: " + url);
    return '';
  }
}


// Function to validate URLs
function isValidUrl(url) {
  var urlRegex = /^(https?|ftp):\/\/[^\s\/$.?#].[^\s]*$/i;
  return urlRegex.test(url);
}


// Function to fetch tasks from ChatGPT using its API
const OPENAI_API_KEY = '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';  // Replace with your actual API key


// Function to call OpenAI API
function callOpenAI(prompt) {
    const url = 'https://api.openai.com/v1/engines/davinci-codex/completions';
    const payload = {
        prompt: prompt,
        max_tokens: 150
    };


    const options = {
        method: 'post',
        contentType: 'application/json',
        headers: {
            'Authorization': `Bearer ${OPENAI_API_KEY}`
        },
        payload: JSON.stringify(payload)
    };


    const response = UrlFetchApp.fetch(url, options);
    const responseJson = JSON.parse(response.getContentText());
    return responseJson.choices[0].text;
}


// Function to execute script code
function executeScript(scriptCode) {
    try {
        const result = eval(scriptCode);
        return { success: true, result: result };
    } catch (error) {
        return { success: false, error: error.toString() };
    }
}


// Function to handle the web app's GET request
function doGet() {
    const htmlOutput = HtmlService.createHtmlOutputFromFile('Index');
    return htmlOutput.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}




// Main workflow function
function mainWorkflow(initialPrompt) {
    let scriptCode = callOpenAI(initialPrompt);
    let executionResult = executeScript(scriptCode);


    if (!executionResult.success) {
        Logger.log('Error encountered: ' + executionResult.error);
        // Additional error handling and feedback mechanism should be implemented here
    } else {
        Logger.log('Execution successful: ' + executionResult.result);
        // Handle successful execution
    }
}

Scroll to Top