Skip to main content
Utilities for scraping Google Maps saved places, parsing location data, and synchronizing with Notion databases.

Overview

This module provides functions to:
  • Scrape Google Maps saved places using Puppeteer
  • Parse place data into structured JSON
  • Sync places to Notion database
  • Manage duplicate detection

Types

Place

Represents a geographical place with metadata.
interface Place {
  name: string;
  address: string;
  latitude: number;
  longitude: number;
  notes: string;
  timestampMs: number;
  graphId: string;
}
name
string
required
The name of the place
address
string
required
Full street address
latitude
number
required
Latitude coordinate
longitude
number
required
Longitude coordinate
notes
string
required
User notes or description
timestampMs
number
required
Timestamp in milliseconds when place was saved
graphId
string
required
Google Maps internal graph ID

Functions

parseArrayToJson()

Converts Google Maps raw array data into a structured Place object.
data
any[]
required
Raw array data from Google Maps APP_INITIALIZATION_STATE
place
Place
Parsed place object with structured fields
function parseArrayToJson(data: any[]): Place {
  return {
    name: data[2],
    address: data[1][4],
    latitude: data[1][5][2],
    longitude: data[1][5][3],
    notes: data[3],
    timestampMs: data[9][0] * 1000,
    graphId: data[1][7],
  };
}

getData()

Scrapes Google Maps saved places using Puppeteer and saves to JSON file. Process:
  1. Launches headless Chrome browser with Chromium
  2. Navigates to Google Maps place list URL
  3. Extracts APP_INITIALIZATION_STATE from window object
  4. Parses nested array structure
  5. Saves to public/places.json
void
Promise<void>
Writes parsed data to public/places.json
Configuration:
  • Uses @sparticuz/chromium for serverless environments
  • Headless mode enabled
  • 30-second navigation timeout
  • 500ms wait for dynamic content
async function getData() {
  const placeId = "hie8OZlTQ5613oEw5K-wWg";
  const url = `https://www.google.com/maps/place/data=!3m1!4b1!4m3!11m2!2s${placeId}!3e3`;
  
  const browser = await puppeteer.launch({
    executablePath: await chromium.executablePath(),
    headless: true,
    args: [...chromium.args, "--disable-web-security", "--no-sandbox"],
  });
  
  // ... scraping logic
}

getExistingPages()

Queries Notion places database and returns a map of existing coordinates.
pages
Map<string, string>
Map with keys as “latitude,longitude” and values as place names
Purpose: Prevents duplicate place entries by checking coordinates.
async function getExistingPages(): Promise<Map<string, string>> {
  const placesDbId = import.meta.env.NOTION_DB_ID_PLACES;
  const response = await queryNotionDatabase(placesDbId);
  
  const pages = new Map<string, string>();
  response.forEach((page) => {
    const coords =
      page.properties.latitude["number"] +
      "," +
      page.properties.longitude["number"];
    pages.set(coords, page.properties.name["title"][0].text.content);
  });
  return pages;
}

createPlacePage()

Creates a new place entry in the Notion database.
place
Place
required
Place object to create in Notion
response
CreatePageResponse
Notion API response with created page details
Properties created:
  • name (title): Place name
  • address (rich_text): Full address
  • latitude (number): Latitude coordinate
  • longitude (number): Longitude coordinate
  • notes (rich_text): User notes
  • timestampMs (number): Save timestamp
  • graphId (rich_text): Google Maps graph ID
async function createPlacePage(place: Place): Promise<CreatePageResponse> {
  const placesDbId = import.meta.env.NOTION_DB_ID_PLACES;
  const dataSourceId = await getDataSourceId(placesDbId);

  return await notion.pages.create({
    parent: { data_source_id: dataSourceId, type: "data_source_id" },
    properties: {
      name: { title: [{ text: { content: place.name } }] },
      address: { type: "rich_text", rich_text: [{ text: { content: place.address } }] },
      // ... other properties
    },
  });
}

writeToNotion()

Reads public/places.json and syncs new places to Notion database. Process:
  1. Reads JSON file from public/places.json
  2. Fetches existing pages from Notion
  3. Checks for duplicates using coordinates
  4. Creates new pages for unique places
  5. Logs skipped and created pages
void
Promise<void>
Logs summary of created and skipped pages

Usage Example

import { getData, writeToNotion } from '@lib/places';

// Scrape Google Maps and save to JSON
await getData();

// Sync scraped data to Notion
await writeToNotion();

Configuration

PLACES_SAVE_PATH
string
default:"public/places.json"
File path where scraped places data is saved
NOTION_DB_ID_PLACES
string
required
Environment variable for Notion places database ID
  • Used by: Map component (src/components/Map.tsx:20)
  • Depends on: src/lib/notion-cms.ts, src/lib/notion-client.ts
  • Source: src/lib/places.ts:1

Build docs developers (and LLMs) love