{"id":50705540,"url":"https://github.com/devhardiyanto/maps-llm-backend","last_synced_at":"2026-06-09T11:03:40.402Z","repository":{"id":310156119,"uuid":"1038504419","full_name":"devhardiyanto/maps-llm-backend","owner":"devhardiyanto","description":null,"archived":false,"fork":false,"pushed_at":"2025-08-16T04:09:09.000Z","size":8,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-16T06:23:34.288Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/devhardiyanto.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-08-15T10:20:45.000Z","updated_at":"2025-08-16T04:09:13.000Z","dependencies_parsed_at":"2025-08-16T06:23:35.679Z","dependency_job_id":"db897cde-7476-454d-9803-75750ba79967","html_url":"https://github.com/devhardiyanto/maps-llm-backend","commit_stats":null,"previous_names":["devhardiyanto/maps-llm-backend"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/devhardiyanto/maps-llm-backend","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devhardiyanto%2Fmaps-llm-backend","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devhardiyanto%2Fmaps-llm-backend/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devhardiyanto%2Fmaps-llm-backend/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devhardiyanto%2Fmaps-llm-backend/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/devhardiyanto","download_url":"https://codeload.github.com/devhardiyanto/maps-llm-backend/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devhardiyanto%2Fmaps-llm-backend/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34103419,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-09T02:00:06.510Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-09T11:03:39.897Z","updated_at":"2026-06-09T11:03:40.397Z","avatar_url":"https://github.com/devhardiyanto.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# backend-google-maps\n\nLightweight backend built with Bun + Hono to extract search intent from natural language (via OpenAI) and perform place search on Google Maps (Places API), then return front-end ready results.\n\n## Tech Stack\n- Bun\n- Hono\n- OpenAI (chat completion, JSON mode)\n- Google Maps Places API (Legacy Text Search + v1 fallback)\n\n## Prerequisites\n- Bun \u003e= 1.0 (latest recommended)\n- OpenAI API Key\n- Google Maps API Key (enable Places API)\n\n## Quick Setup\n1) Copy env and set keys\n```sh\ncp .env.example .env\n# Edit .env then set:\n# PORT=3001               # optional, default 3000 if not set\n# OPENAI_API_KEY=...\n# GOOGLE_MAPS_API_KEY=...\n```\n\n2) Install dependencies\n```sh\nbun install\n```\n\n3) Start dev server (hot reload)\n```sh\nbun run dev\n```\n\n4) Check health endpoint\n- http://localhost:3000/health (or match PORT in .env)\n\n## Environment Variables\n- `PORT` — default `3000` (see `src/index.ts`), `.env.example` uses `3001`\n- `OPENAI_API_KEY` — OpenAI API key\n- `GOOGLE_MAPS_API_KEY` — Google Maps API key with Places API enabled\n\n## Endpoints\n- `GET /health` → `{ message: \"OK\" }`\n- `GET /api/chat` → `{ message: \"OK\" }` (route ping)\n- `POST /api/chat`\n  - Body (JSON):\n    ```json\n    { \"message\": \"find good ramen in Cimahi open now\" }\n    ```\n  - Response (general shape):\n    ```json\n    {\n      \"query\": \"...\",\n      \"resolved_location\": \"Cimahi\" ,\n      \"provider\": \"legacy\",\n      \"status\": \"OK\",\n      \"error_message\": null,\n      \"results\": [\n        {\n          \"name\": \"...\",\n          \"address\": \"...\",\n          \"lat\": -6.9,\n          \"lng\": 107.6,\n          \"place_id\": \"ChIJ...\",\n          \"rating\": 4.5,\n          \"user_ratings_total\": 1234,\n          \"directions_url\": \"https://www.google.com/maps/dir/?api=1\u0026destination=place_id:ChIJ...\",\n          \"maps_url\": \"https://www.google.com/maps/place/?q=place_id:ChIJ...\",\n          \"embed_iframe_src\": \"https://www.google.com/maps?q=-6.9,107.6\u0026output=embed\"\n        }\n      ]\n    }\n    ```\n\n### cURL example\n```sh\ncurl -X POST \"http://localhost:3000/api/chat\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"message\":\"find a cozy cafe in Bandung open now\"}'\n```\n\n## How it works\n- `src/routes/chat.ts`\n  - `GET /api/chat` for ping.\n  - `POST /api/chat` accepts `{ message }`, simple in-memory rate limit: 10 req / 10s per IP.\n- `src/services/map.ts`\n  - `processChat(message)`: call LLM → build query → call Google Places → return payload.\n- `src/services/llm.ts`\n  - `extractMapsIntent()`: uses `gpt-4o-mini` (JSON mode) to extract intent: `query`, `location?`, `radius_km?`, `top_k?`, `filters.open_now?`.\n- `src/services/maps.ts`\n  - `textSearchPlaces(q, openNow, topK)`: first tries Legacy Text Search; if it fails, falls back to Places API v1 (`places:searchText`). Maps to a consistent structure with navigation and embed URLs.\n- `src/config/openai.ts`\n  - Initializes OpenAI Client with `OPENAI_API_KEY`.\n- `src/config/middleware.ts`\n  - `prettyJSON()` to pretty-print JSON output.\n- `src/constants/endpoints.ts`\n  - Base route `API.CHAT = \"/api/chat\"`.\n- `src/index.ts`\n  - Registers routes and middleware, healthcheck, error handler. Exports `{ fetch, port }` for Bun.\n\n### Rate Limiting\n- In-memory bucket (simple): 10 requests / 10 seconds per IP.\n- IP is read from `cf-connecting-ip` or `x-forwarded-for` headers (fallback `local`).\n\n## Project Structure (brief)\n```\nsrc/\n  config/\n    middleware.ts\n    openai.ts\n  constants/\n    endpoints.ts\n  routes/\n    chat.ts\n  services/\n    llm.ts\n    map.ts\n    maps.ts\n  index.ts\n```\n\n## Notes\n- CORS is not explicitly enabled. If accessing from browsers cross-origin, add CORS middleware as needed for Hono.\n- Ensure your Google Cloud project has Places API enabled and the API key is allowed for the endpoints used.\n- The OpenAI model (`gpt-4o-mini`) can be changed depending on needs/perf/cost.\n\n## License\nUse for internal needs. Add a LICENSE file if needed.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevhardiyanto%2Fmaps-llm-backend","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdevhardiyanto%2Fmaps-llm-backend","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevhardiyanto%2Fmaps-llm-backend/lists"}