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/spotlistsendpoints - Uses existing JWT authentication
Integration Goals
- Unified Spot Experience - Spots saved via extension appear instantly in mobile app and website
- Cross-Platform Lists - Users can access their spot lists from any platform
- Enhanced Discovery - Enable spot sharing and community discovery features
- 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:
| Field | Display |
|---|---|
| Name | Large header |
| Image | Full-width hero |
| Location | City, State with map preview |
| Tags | Pill badges |
| Description | Text block |
| Rating | Star 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
| Phase | Priority | Dependencies |
|---|---|---|
| Phase 1: API Enhancements | P1 | None |
| Phase 2: Mobile Integration | P1 | Phase 1 |
| Phase 3: Website Integration | P2 | Phase 1 |
| Phase 4: Extension Enhancements | P2 | Phase 1 |
| Phase 5: Web Store Publication | P2 | Phase 4 |
| Phase 6: Community Features | P3 | Phase 1-3 |
Technical Debt to Address
| Item | Effort | Impact | Notes |
|---|---|---|---|
| Move Google API key to backend | Low | High | Security concern |
| Add image caching layer | Medium | Medium | Reduce Google CDN dependency |
| Implement spot search | Medium | High | Required for discovery |
| Add geospatial indexing | Low | High | MongoDB 2dsphere index |
| Rate limit bulk endpoints | Low | Medium | Prevent 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
| Risk | Mitigation |
|---|---|
| Google Maps scraping blocked | Add fallback manual entry mode |
| Google CDN images expire | Implement S3 proxy (Phase 1.3) |
| Rate limiting by Google | Cache geocoding results, batch requests |
| Extension review rejection | Follow Chrome Web Store policies strictly |
| Duplicate spots flooding DB | Implement 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