Backend Setup: Google Apps Script

Deployment Steps

  1. Open Google Apps Script: Go to your Google Sheet: Tire Management Sheet. Click on Extensions > Apps Script. This will open the Apps Script editor.
  2. Add the Code: If there is any existing code in the Code.gs file, delete it. Copy the entire content from the code block below and paste it into the editor. Save the project (File > Save, or Ctrl+S/Cmd+S).
  3. Deploy as a Web App: Click the Deploy button in the top-right corner and select New deployment. Click the gear icon next to "Select type" and choose Web app.
  4. Configure Deployment:
    • Description: Tire Management API (or something similar).
    • Execute as: Me (your Google account).
    • Who has access: Anyone (This is crucial for JSONP to work from the web app).
    Click Deploy.
  5. Authorize Permissions: Google will ask for authorization. Click Review permissions. Choose your Google account. You may see a warning screen. Click Advanced, then click Go to [Your Project Name] (unsafe). Click Allow to grant the necessary permissions.
  6. Get the URL: After deployment, you will get a Web app URL. Important: The URL in this application's code is already set to the one you provided. If you create a brand new script project and get a different URL, you would need to update the APP_SCRIPT_URL constant at the top of the script in this file. If you are re-deploying to the same script project, the URL should remain the same.
  7. Redeploying Changes: If you ever change the script, you must create a new deployment version. Click Deploy > Manage deployments, select your deployment, click the pencil icon (Edit), choose New version, and click Deploy.

Code.gs (Copy this code)


var sheetId = "1VrRsDBy4-9qYxP2xeNrFBdLc6CnXV8qKPh95rtXGMJQ";
var sheetName = "TireData";

// Helper function to get or create the sheet
function getSheet() {
  var spreadsheet = SpreadsheetApp.openById(sheetId);
  var sheet = spreadsheet.getSheetByName(sheetName);
  if (!sheet) {
    sheet = spreadsheet.insertSheet(sheetName);
    var initialHeaders = [
      "timestamp", "vehicleId", "fleet", "checkDate", "checkMileage", "technicianNotes",
      "FL_brand", "FL_size", "FL_serial", "FL_installDate", "FL_installMileage", "FL_tread_g1", "FL_tread_g2", "FL_tread_g3", "FL_pressure_std", "FL_pressure_act", "FL_photo",
      "FR_brand", "FR_size", "FR_serial", "FR_installDate", "FR_installMileage", "FR_tread_g1", "FR_tread_g2", "FR_tread_g3", "FR_pressure_std", "FR_pressure_act", "FR_photo",
      "RL_brand", "RL_size", "RL_serial", "RL_installDate", "RL_installMileage", "RL_tread_g1", "RL_tread_g2", "RL_tread_g3", "RL_pressure_std", "RL_pressure_act", "RL_photo",
      "RR_brand", "RR_size", "RR_serial", "RR_installDate", "RR_installMileage", "RR_tread_g1", "RR_tread_g2", "RR_tread_g3", "RR_pressure_std", "RR_pressure_act", "RR_photo"
    ];
    sheet.appendRow(initialHeaders);
  }
  return sheet;
}

function doGet(e) {
  // This check prevents errors when the script is run directly from the editor
  // or when the URL is visited without parameters.
  if (!e || !e.parameter || !e.parameter.action) {
    return HtmlService.createHtmlOutput(
      "

Tire Management System Backend

" + "

This script is running correctly. It is the backend for the Tire Management web application.

" + "

It should not be run directly from the Apps Script editor. Please access the web application to use it.

" + "

If you are setting this up for the first time, please follow the deployment instructions provided in the web app's HTML file.

" ); } var callback = e.parameter.callback; var action = e.parameter.action; var response; try { if (action == "write") { response = writeData(e); } else if (action == "read") { response = readData(); } else { response = { status: "error", message: "Invalid action specified." }; } } catch (error) { // Log the full error for debugging Logger.log("Error in doGet: " + error.toString() + "\nStack: " + error.stack); response = { status: "error", message: "An error occurred: " + error.message, details: error.stack }; } // Return as JSONP var jsonResponse = JSON.stringify(response); if (callback) { return ContentService.createTextOutput(callback + "(" + jsonResponse + ")").setMimeType(ContentService.MimeType.JAVASCRIPT); } else { return ContentService.createTextOutput(jsonResponse).setMimeType(ContentService.MimeType.JSON); } } function writeData(e) { var sheet = getSheet(); // Use the helper to ensure sheet exists var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0]; var newRow = headers.map(function(header) { if (header === "timestamp") { return new Date(); } return e.parameter[header] || ""; // Default to empty string if param is missing }); sheet.appendRow(newRow); return { status: "success", message: "Data saved successfully." }; } function readData() { var sheet = getSheet(); // Use the helper to ensure sheet exists var range = sheet.getDataRange(); var values = range.getValues(); if (values.length < 2) { return { status: "success", data: [] }; // No data rows } var headers = values[0]; var data = []; for (var i = 1; i < values.length; i++) { var rowObject = {}; for (var j = 0; j < headers.length; j++) { var header = headers[j]; var value = values[i][j]; // Format dates nicely if (value instanceof Date) { if (header.toLowerCase().includes('date')) { rowObject[header] = value.toISOString().split('T')[0]; } else { rowObject[header] = value.toISOString(); } } else { rowObject[header] = value; } } data.push(rowObject); } return { status: "success", data: data }; }