Skip to main content

Chrome Extension Integration Plan

This document outlines the plan to fully integrate the Map Scraper Chrome extension into the TrickBook ecosystem, enabling seamless spot discovery and sharing across all platforms.

Current State

The Chrome extension currently:

  • Extracts spot data from Google Maps
  • Syncs spots to TrickBook via /api/spots/bulk
  • Manages spot lists via /api/spotlists endpoints
  • Uses existing JWT authentication

Integration Goals

  1. Unified Spot Experience - Spots saved via extension appear instantly in mobile app and website
  2. Cross-Platform Lists - Users can access their spot lists from any platform
  3. Enhanced Discovery - Enable spot sharing and community discovery features
  4. Chrome Web Store Publication - Make the extension publicly available

Phase 1: API Enhancements

Priority: P1 (High)

Enhance the backend to better support the extension workflow.

1.1 Spot Deduplication

Prevent duplicate spots when syncing from extension.

// New endpoint: POST /api/spots/bulk-upsert
// Deduplicates by lat/lon within ~50m radius

// Request
{
"parks": [
{ "name": "...", "latitude": 40.8034, "longitude": -74.0706, ... }
]
}

// Response
{
"created": [{ "_id": "...", ... }],
"existing": [{ "_id": "...", ... }],
"updated": []
}

Backend Changes:

// routes/spots.js
router.post('/bulk-upsert', auth, async (req, res) => {
const { parks } = req.body;
const results = { created: [], existing: [], updated: [] };

for (const park of parks) {
// Find existing spot within 50m
const existing = await Spot.findOne({
latitude: { $gte: park.latitude - 0.0005, $lte: park.latitude + 0.0005 },
longitude: { $gte: park.longitude - 0.0005, $lte: park.longitude + 0.0005 }
});

if (existing) {
results.existing.push(existing);
} else {
const spot = await Spot.create(park);
results.created.push(spot);
}
}

res.json(results);
});

1.2 Spot Attribution

Track which user/source created each spot.

// Update Spot schema
{
// ... existing fields
createdBy: { type: ObjectId, ref: 'users' },
source: { type: String, enum: ['app', 'web', 'extension', 'import'] },
googlePlaceId: String, // For future Google integration
}

1.3 Image Proxy/Storage

Move images from Google CDN to S3 for reliability.

// New endpoint: POST /api/spots/:id/upload-image
// Downloads image from URL and stores in S3

router.post('/:id/upload-image', auth, async (req, res) => {
const { imageUrl } = req.body;
const spot = await Spot.findById(req.params.id);

// Download and upload to S3
const s3Url = await uploadToS3(imageUrl, `spots/${spot._id}`);

spot.imageURL = s3Url;
await spot.save();

res.json({ imageURL: s3Url });
});

Phase 2: Mobile App Integration

Priority: P1 (High)

Enable mobile users to view and interact with extension-synced spots.

2.1 Spot List Screen Updates

The mobile app already has spot list functionality. Ensure it:

  • Displays all spots including those synced from extension
  • Shows spot source indicator (optional)
  • Renders Google-sourced images correctly

2.2 Map View Enhancement

Add a map view for spot lists:

// screens/SpotMapScreen.js
import MapView, { Marker } from 'react-native-maps';

const SpotMapScreen = ({ spots }) => (
<MapView
initialRegion={calculateRegion(spots)}
style={{ flex: 1 }}
>
{spots.map(spot => (
<Marker
key={spot._id}
coordinate={{ latitude: spot.latitude, longitude: spot.longitude }}
title={spot.name}
description={spot.description}
/>
))}
</MapView>
);

2.3 Spot Detail Screen

Create a detailed view for individual spots:

FieldDisplay
NameLarge header
ImageFull-width hero
LocationCity, State with map preview
TagsPill badges
DescriptionText block
RatingStar display
Actions"Get Directions" button

Phase 3: Website Integration

Priority: P2 (Medium)

Add spot features to the TrickBook website.

3.1 Spot Explorer Page

Public page showing community-shared spots:

/spots                    # Browse all spots
/spots?city=Los+Angeles # Filter by city
/spots?tags=bowl # Filter by tags
/spots/:id # Individual spot detail

3.2 User Spot Lists

Private spot list management:

/my/spots                 # User's spot lists
/my/spots/:listId # Individual list view

3.3 Embeddable Map Widget

Allow users to embed their spot map:

<iframe
src="https://thetrickbook.com/embed/spots/user123"
width="600"
height="400"
></iframe>

Phase 4: Extension Enhancements

Priority: P2 (Medium)

Improve the extension based on user feedback and integration needs.

4.1 Real-time Sync Status

Show sync status in popup:

// Show sync indicator
const syncStatus = {
lastSync: '2 minutes ago',
pendingSpots: 3,
syncErrors: []
};

4.2 Offline Queue

Queue spots when offline, sync when connection restored:

// utils.js
async function queueForSync(spot) {
const queue = await chrome.storage.local.get('syncQueue') || [];
queue.push({ ...spot, queuedAt: Date.now() });
await chrome.storage.local.set({ syncQueue: queue });
}

async function processSyncQueue() {
const { syncQueue } = await chrome.storage.local.get('syncQueue');
if (!syncQueue?.length) return;

try {
await syncSpots(syncQueue);
await chrome.storage.local.remove('syncQueue');
} catch (err) {
console.error('Sync failed, will retry', err);
}
}

4.3 Quick Actions

Add right-click context menu:

// background.js
chrome.contextMenus.create({
id: 'save-spot',
title: 'Save to TrickBook',
contexts: ['page'],
documentUrlPatterns: ['*://www.google.com/maps/*']
});

chrome.contextMenus.onClicked.addListener((info, tab) => {
if (info.menuItemId === 'save-spot') {
chrome.tabs.sendMessage(tab.id, { action: 'extractAndSave' });
}
});

Phase 5: Chrome Web Store Publication

Priority: P2 (Medium)

Make the extension publicly available.

5.1 Pre-Publication Checklist

  • Update manifest.json with production URLs
  • Create extension icons (16x16, 48x48, 128x128)
  • Write store description
  • Create promotional screenshots
  • Create demo video
  • Privacy policy page on website
  • Terms of service

5.2 Store Listing Content

Title: TrickBook Spot Saver - Save Skateparks from Google Maps

Short Description: Save skateparks and street spots from Google Maps directly to your TrickBook account. Tag, organize, and sync spots across all your devices.

Category: Productivity

5.3 Privacy Policy Requirements

Document data collection:

  • Location data (coordinates from Google Maps)
  • User authentication tokens
  • Spot images (from Google CDN)

Phase 6: Community Features

Priority: P3 (Backlog)

Enable spot sharing and discovery.

6.1 Public Spot Database

Allow users to contribute spots to a public database:

// New field on spots
{
visibility: { type: String, enum: ['private', 'public'], default: 'private' },
verifiedBy: [{ type: ObjectId, ref: 'users' }],
reportCount: Number
}

6.2 Spot Discovery Feed

API endpoint for discovering new spots:

GET /api/spots/discover?lat=40.80&lon=-74.07&radius=50

6.3 Spot Ratings & Reviews

// New collection: spotReviews
{
spotId: ObjectId,
userId: ObjectId,
rating: Number, // 1-5
review: String,
visitedAt: Date,
photos: [String]
}

Implementation Timeline

PhasePriorityDependencies
Phase 1: API EnhancementsP1None
Phase 2: Mobile IntegrationP1Phase 1
Phase 3: Website IntegrationP2Phase 1
Phase 4: Extension EnhancementsP2Phase 1
Phase 5: Web Store PublicationP2Phase 4
Phase 6: Community FeaturesP3Phase 1-3

Technical Debt to Address

ItemEffortImpactNotes
Move Google API key to backendLowHighSecurity concern
Add image caching layerMediumMediumReduce Google CDN dependency
Implement spot searchMediumHighRequired for discovery
Add geospatial indexingLowHighMongoDB 2dsphere index
Rate limit bulk endpointsLowMediumPrevent abuse

Metrics to Track

Extension Metrics

  • Extension installs (Chrome Web Store)
  • Active users (weekly)
  • Spots extracted per user
  • Sync success rate
  • Sync error types

Spot Metrics

  • Total spots in database
  • Spots by source (app/web/extension)
  • Average spots per user
  • Most popular cities/states
  • Tag distribution

Engagement Metrics

  • Cross-platform usage (users using both app + extension)
  • List creation rate
  • Spots per list average
  • Map view engagement

Risk Mitigation

RiskMitigation
Google Maps scraping blockedAdd fallback manual entry mode
Google CDN images expireImplement S3 proxy (Phase 1.3)
Rate limiting by GoogleCache geocoding results, batch requests
Extension review rejectionFollow Chrome Web Store policies strictly
Duplicate spots flooding DBImplement deduplication (Phase 1.1)

Success Criteria

Phase 1 Complete When:

  • Bulk upsert endpoint deployed
  • No duplicate spots created
  • Source attribution on all new spots

Phase 2 Complete When:

  • Extension spots visible in mobile app
  • Map view functional
  • Deep linking from extension to app works

Full Integration Complete When:

  • Extension published on Chrome Web Store
  • 100+ users actively using extension
  • Cross-platform sync works reliably
  • Community discovery features launched