diff --git a/README.md b/README.md index 0f6dcbd..8a3ee08 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ Sample: https://chatFn.io The repo provides the following tools you can use out of the box: - 🗺️ ShowPoisOnMap: A tool that can show points of interest on a map. +- 🌐 ReverseGeocode: A tool that can convert coordinates into a human-readable address. - ⏰ Clock: A clock that can tell you the time. - 🧮 Calculator: A simple calculator that can do basic arithmetic. Input should be a math expression. - 🔍 GoogleCustomSearch: A wrapper around the Google Custom Search API. Useful for when you need to answer questions about current events. Input should be a search query. diff --git a/tools/reverseGeocode.test.ts b/tools/reverseGeocode.test.ts new file mode 100644 index 0000000..1bea493 --- /dev/null +++ b/tools/reverseGeocode.test.ts @@ -0,0 +1,19 @@ +import { createReverseGeocode } from './reverseGeocode'; +import { expect, it } from 'vitest'; + +const reverseGeocode = createReverseGeocode({ + mapboxAccessToken: process.env.MAPBOX_ACCESS_TOKEN || 'YOUR_FALLBACK_MAPBOX_ACCESS_TOKEN', +}); + +it('should successfully return an address from coordinates', async () => { + const result = await reverseGeocode.execute({ + latitude: 40.7128, + longitude: -74.006, + }); + + console.log(result) + + expect(result).toMatchObject({ + address: expect.stringContaining(','), + }); +}); diff --git a/tools/reverseGeocode.ts b/tools/reverseGeocode.ts new file mode 100644 index 0000000..633d8a1 --- /dev/null +++ b/tools/reverseGeocode.ts @@ -0,0 +1,54 @@ +// reverseGeocode.ts +import { z } from 'zod'; + +function createReverseGeocode({ + mapboxAccessToken, +}: { + mapboxAccessToken: string; +}) { + if (!mapboxAccessToken) { + throw new Error('Please set the Mapbox Access Token in the plugin settings.'); + } + + const paramsSchema = z.object({ + latitude: z.number(), + longitude: z.number(), + }); + + const name = 'reverseGeocode'; + const description = ` + Converts latitude and longitude coordinates to a human-readable address using the Mapbox Geocoding API. + latitude: The latitude of the location to be geocoded. + longitude: The longitude of the location to be geocoded. +`; + + const execute = async ({ latitude, longitude }: z.infer) => { + const accessToken = mapboxAccessToken; + + if (!accessToken) { + throw new Error('Please set the Mapbox Access Token in the plugin settings.'); + } + + const url = `https://api.mapbox.com/geocoding/v5/mapbox.places/${longitude},${latitude}.json?access_token=${accessToken}`; + + let response = await fetch(url); + if (!response.ok) { + throw new Error('Network response was not ok'); + } + + const data = await response.json(); + if (!data || !data.features || !data.features.length) { + throw new Error('No address found for the provided coordinates.'); + } + + // Assuming the first feature is the most relevant result + const place = data.features[0]; + return { + address: place.place_name, + }; + }; + + return { paramsSchema, name, description, execute }; +} + +export { createReverseGeocode };