← back to Prestige Car Wash

scripts/places-read.js

62 lines

#!/usr/bin/env node
'use strict';
/**
 * places-read.js — read-only pull of the Google Business listing via the Places API.
 * Writes data/places.json (hours, rating, reviews, photos). No writes to Google.
 *
 * Needs GOOGLE_PLACES_API_KEY + PCW_PLACE_ID (Steve-gated: adding the key + billing).
 * Without them it leaves the mock in place and explains what to do.
 */
const fs = require('fs');
const path = require('path');
const OUT = path.join(__dirname, '..', 'data', 'places.json');

function keyFrom(name) {
  if (process.env[name]) return process.env[name];
  try {
    const m = fs.readFileSync(path.join(process.env.HOME, 'Projects/secrets-manager/.env'), 'utf8')
      .match(new RegExp('^' + name + '=(.+)$', 'm'));
    return m ? m[1].trim() : '';
  } catch { return ''; }
}
const KEY = keyFrom('GOOGLE_PLACES_API_KEY');
const PLACE = process.env.PCW_PLACE_ID || keyFrom('PCW_PLACE_ID');

async function main() {
  if (!KEY || !PLACE) {
    console.log('⚠ GOOGLE_PLACES_API_KEY / PCW_PLACE_ID not set — keeping mock data/places.json.');
    console.log('  Gated setup: enable Places API + billing on Google Cloud, then `/secrets` the key.');
    return;
  }
  // Places API (New) Place Details
  const url = `https://places.googleapis.com/v1/places/${PLACE}`;
  const r = await fetch(url, {
    headers: {
      'X-Goog-Api-Key': KEY,
      'X-Goog-FieldMask': 'displayName,formattedAddress,nationalPhoneNumber,rating,userRatingCount,regularOpeningHours,websiteUri,googleMapsUri,reviews,photos'
    }
  });
  if (!r.ok) { console.error(`Places API ${r.status}: ${(await r.text()).slice(0, 200)}`); process.exit(1); }
  const p = await r.json();
  const out = {
    _mock: false,
    name: p.displayName?.text || 'Prestige Car Wash',
    address: p.formattedAddress || '',
    phone: p.nationalPhoneNumber || '',
    rating: p.rating || null,
    reviews_count: p.userRatingCount || 0,
    hours: p.regularOpeningHours?.weekdayDescriptions || [],
    website: p.websiteUri || '',
    maps_url: p.googleMapsUri || '',
    place_id: PLACE,
    reviews: (p.reviews || []).slice(0, 5).map(rv => ({
      author: rv.authorAttribution?.displayName || '', rating: rv.rating, text: rv.text?.text || ''
    })),
    photos: (p.photos || []).slice(0, 6).map(ph => ph.name),
    updated_at: new Date().toISOString()
  };
  fs.writeFileSync(OUT, JSON.stringify(out, null, 2));
  console.log(`✔ wrote data/places.json — ${out.name}, ${out.rating}★ (${out.reviews_count})`);
}
main().catch(e => { console.error(e); process.exit(1); });