pulse-ai-utils
Version:
Utility functions and helpers for AI-powered applications
199 lines • 7.93 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const env_loader_1 = require("../config/env-loader");
const google_maps_services_js_1 = require("@googlemaps/google-maps-services-js");
class GooglePlacesHelper {
constructor(apiKey) {
this.apiKey = apiKey || (0, env_loader_1.getEnvVar)('GOOGLE_PLACES_API_KEY');
if (!this.apiKey) {
throw new Error('Google Places API key is required');
}
this.client = new google_maps_services_js_1.Client({});
}
/**
* Search for places in a given area
*/
async searchPlaces(options) {
try {
const response = await this.client.textSearch({
params: {
key: this.apiKey,
query: options.query || 'popular spots',
location: options.location,
radius: options.radius || 5000,
type: options.type,
minprice: options.minprice,
maxprice: options.maxprice,
opennow: options.opennow,
language: (options.language || 'en'),
},
});
if (response.data.status !== 'OK' && response.data.status !== 'ZERO_RESULTS') {
throw new Error(`Google Places API error: ${response.data.status}`);
}
const places = response.data.results.map((result) => ({
google_place_id: result.place_id,
name: result.name,
address: result.formatted_address || null,
rating: result.rating || null,
user_ratings_total: result.user_ratings_total || null,
price_level: result.price_level || null,
types: result.types || null,
location: result.geometry?.location
? {
lat: result.geometry.location.lat,
lng: result.geometry.location.lng,
}
: null,
image_url: result.photos?.[0]
? this.getPhotoUrl(result.photos[0].photo_reference)
: null,
source: 'google_places',
source_url: `https://www.google.com/maps/place/?q=place_id:${result.place_id}`,
}));
return places;
}
catch (error) {
console.error('Error searching places:', error);
throw error;
}
}
/**
* Get detailed information about a specific place
*/
async getPlaceDetails(placeId, options) {
try {
const fields = options?.fields || [
'place_id',
'name',
'formatted_address',
'address_components',
'formatted_phone_number',
'website',
'rating',
'user_ratings_total',
'price_level',
'types',
'geometry',
'photos',
'opening_hours',
'business_status',
];
const response = await this.client.placeDetails({
params: {
key: this.apiKey,
place_id: placeId,
fields: fields,
language: (options?.language || 'en'),
},
});
if (response.data.status !== 'OK') {
throw new Error(`Google Places API error: ${response.data.status}`);
}
const result = response.data.result;
// Extract address components
let city = null;
let state = null;
let country = null;
let postalCode = null;
if (result.address_components) {
for (const component of result.address_components) {
if (component.types.includes('locality')) {
city = component.long_name;
}
if (component.types.includes('administrative_area_level_1')) {
state = component.short_name;
}
if (component.types.includes('country')) {
country = component.long_name;
}
if (component.types.includes('postal_code')) {
postalCode = component.long_name;
}
}
}
const place = {
google_place_id: result.place_id,
name: result.name || '',
address: result.formatted_address || null,
city,
state,
country,
postal_code: postalCode,
phone: result.formatted_phone_number || null,
website: result.website || null,
rating: result.rating || null,
user_ratings_total: result.user_ratings_total || null,
price_level: result.price_level || null,
types: result.types || null,
location: result.geometry?.location
? {
lat: result.geometry.location.lat,
lng: result.geometry.location.lng,
}
: null,
image_url: result.photos?.[0]
? this.getPhotoUrl(result.photos[0].photo_reference)
: null,
source: 'google_places',
source_url: `https://www.google.com/maps/place/?q=place_id:${result.place_id}`,
};
return place;
}
catch (error) {
console.error('Error getting place details:', error);
throw error;
}
}
/**
* Search for places nearby a location
*/
async nearbySearch(location, radius = 5000, type) {
try {
const response = await this.client.placesNearby({
params: {
key: this.apiKey,
location,
radius,
type: type,
},
});
if (response.data.status !== 'OK' && response.data.status !== 'ZERO_RESULTS') {
throw new Error(`Google Places API error: ${response.data.status}`);
}
const places = response.data.results.map((result) => ({
google_place_id: result.place_id,
name: result.name,
address: result.vicinity || null,
rating: result.rating || null,
user_ratings_total: result.user_ratings_total || null,
price_level: result.price_level || null,
types: result.types || null,
location: result.geometry?.location
? {
lat: result.geometry.location.lat,
lng: result.geometry.location.lng,
}
: null,
image_url: result.photos?.[0]
? this.getPhotoUrl(result.photos[0].photo_reference)
: null,
source: 'google_places',
source_url: `https://www.google.com/maps/place/?q=place_id:${result.place_id}`,
}));
return places;
}
catch (error) {
console.error('Error searching nearby places:', error);
throw error;
}
}
/**
* Generate photo URL from photo reference
*/
getPhotoUrl(photoReference, maxWidth = 400) {
return `https://maps.googleapis.com/maps/api/place/photo?maxwidth=${maxWidth}&photoreference=${photoReference}&key=${this.apiKey}`;
}
}
exports.default = GooglePlacesHelper;
//# sourceMappingURL=google-places-helper.js.map