Source Code Viewer

Google Apps Script - Google Workspace Status Webhook


const TESTING_BYPASS_CACHE = false;
const STATUS_FEED_URL = "https://www.google.com/appsstatus/dashboard/en/feed.atom";
const STATUS_ALERT_WEBHOOK = "WEBHOOK URL"; 

function checkWorkspaceServiceStatus() {
  const response = UrlFetchApp.fetch(STATUS_FEED_URL);
  const feedXml = response.getContentText();

  const document = XmlService.parse(feedXml);
  const root = document.getRootElement(); //  with namespace

  const ns = root.getNamespace();
  const entries = root.getChildren("entry", ns);
  if (!entries || entries.length === 0) {
    sendWorkspaceStatusMessage("❗ No entries found in Atom feed.");
    return;
  }

  // Use empty object if bypassing cache for testing
  const alertsSent = TESTING_BYPASS_CACHE ? {} : getStoredIncidents();
  const currentIncidents = {};

  let newAlerts = [];
  let resolvedAlerts = [];

  entries.forEach(entry => {
    const id = entry.getChildText("id", ns);
    const title = entry.getChildText("title", ns);
    const summary = entry.getChildText("summary", ns) || "";
    const updated = entry.getChildText("updated", ns);

    const isResolved = /resolved|restored|issue has been fixed/i.test(summary);

    currentIncidents[id] = { title, summary, updated };

    if (!alertsSent[id]) {
      newAlerts.push({ id, title, summary, updated });
    } else if (!alertsSent[id].resolved && isResolved) {
      resolvedAlerts.push({ id, title, summary, updated });
    }
  });

  newAlerts.forEach(alert => {
    const mdSummary = htmlToMarkdown(alert.summary);
    sendWorkspaceStatusMessage(`🚨 *New Issue Detected:*\n${alert.title}\n\n${mdSummary}`);
    alertsSent[alert.id] = { ...alert, resolved: false };
  });

  resolvedAlerts.forEach(alert => {
    const mdSummary = htmlToMarkdown(alert.summary);
    sendWorkspaceStatusMessage(`✅ *Issue Resolved:*\n${alert.title}\n\n${mdSummary}`);
    alertsSent[alert.id].resolved = true;
  });

  // Only save if NOT bypassing cache
  if (!TESTING_BYPASS_CACHE) {
    saveStoredIncidents(alertsSent);
  }
}

function truncate(text, limit) {
  return text.length > limit ? text.substring(0, limit) + "..." : text;
}

function sendWorkspaceStatusMessage(text) {
  const payload = JSON.stringify({ text });
  UrlFetchApp.fetch(STATUS_ALERT_WEBHOOK, {
    method: "post",
    contentType: "application/json",
    payload
  });
}

function getStoredIncidents() {
  const raw = PropertiesService.getScriptProperties().getProperty("workspaceStatusIncidents");
  return raw ? JSON.parse(raw) : {};
}

function saveStoredIncidents(incidents) {
  PropertiesService.getScriptProperties().setProperty("workspaceStatusIncidents", JSON.stringify(incidents));
}

function htmlToMarkdown(html) {
  if (!html) return "";
  return html
    .replace(/(.*?)<\/strong>/g, '*$1*')
    .replace(/(.*?)<\/a>/g, '[$2]($1)')
    .replace(/<\/p>/g, '\n\n')
    .replace(/<\/div>/g, '\n\n')
    .replace(//g, '\n')
    .replace(/<[^>]+>/g, '')  // remove all other tags
    .replace(/\s+/g, ' ')
    .trim();
}

function resetStoredIncidents() {
  PropertiesService.getScriptProperties().deleteProperty("workspaceStatusIncidents");
  Logger.log("Stored incidents cleared!");
}