Si estás pagando, sí
Este es un complemento independiente, el soporte no es gratuito y no ofrezco ninguna garantía; lo usas bajo tu propio riesgo.
Podría haberlo ocultado fácilmente y no haberlo compartido en absoluto, en ningún sitio.
3 Me gusta
Esto ya está fusionado, gracias de nuevo a los patrocinadores @祁同伟 y @nathank
main ← automated_ip_based_user_location_determination
merged 09:02PM - 31 Jan 26 UTC
## IP‑based User Location (MaxMind → GeoNames)
### What this adds
- Auto… matically determines a user’s location from their IP after post creation.
- Uses **MaxMind (DiscourseIpInfo)** for identity + GeoNames for canonical lat/lon.
- Stores exactly **one granularity level** per user (`country` / `province` / `city`) in `UserCustomField`
`geo_location`.
- Ensures lat/lon match the chosen granularity (privacy‑correct coordinates).
- Caches GeoNames lookups by `geoname_id` (no extra gems; uses `FinalDestination::HTTP`).
---
## Prerequisites (official accounts)
You must have valid accounts and credentials from:
- **MaxMind GeoLite2**
Sign up and obtain an Account ID + License Key:
https://www.maxmind.com/en/geolite2/signup
- **GeoNames**
Create a username for the GeoNames API and **enable Web Services** in your GeoNames account settings:
https://www.geonames.org/login
---
## Required Configuration
**Env vars (MaxMind) for `app.yml`**
- `DISCOURSE_MAXMIND_ACCOUNT_ID`
- `DISCOURSE_MAXMIND_LICENSE_KEY`
**Site settings**
- `location_geonames_username` (GeoNames username)
**Dev note (MaxMind DBs)**
- In development, ensure the MaxMind DBs are downloaded:
DISCOURSE_MAXMIND_ACCOUNT_ID=... DISCOURSE_MAXMIND_LICENSE_KEY=... bundle exec rake maxminddb:get
Restart web/sidekiq afterward so `DiscourseIpInfo` reloads the DBs.
---
## Settings
| Setting | Default | Description |
|---|---:|---|
| `location_ip_granularity` | `city` | Controls stored level: `country`, `province` (admin1), `county` (admin2), or `city`. |
| `location_geonames_username` | `""` | GeoNames username for `getJSON` requests. Acts as a feature flag (blank => skip). |
| `location_ip_lookup_cooldown_days` | `1` | Per‑user cooldown between IP lookups (0 disables cooldown). |
| `locations_skip_ip_based_location_update_if_existing` | `true` | Skip IP lookup when existing `geo_location` already has **lat + lon**. |
| `location_ip_auto_lookup_enabled` | `false` | Auto‑enqueue IP lookups on post creation. Rake task still works when off. |
---
## Flow
- `post_created` → enqueue `Jobs::Locations::IpLocationLookup` with user ID + IP.
- Job:
- Guards: plugin enabled, users map enabled, GeoNames username present, MaxMind env vars present, cooldown
OK, and optional “existing location” check.
- Uses `DiscourseIpInfo.get(ip)` to get `geoname_ids`.
- Resolves GeoNames IDs, picks feature by granularity (`country` / `province` / `county` / `city`), builds
`geo_location`.
- Saves `geo_location` to user custom field + updates `locations_user` table.
---
## Job + Hook
**Hook**
- `post_created` now enqueues `Jobs::Locations::IpLocationLookup`
- In development, IP is overridden to a fixed test IP (`2.139.231.7`) to ensure resolvable data.
**Job**
- `Jobs::Locations::IpLocationLookup` (new, in `app/jobs/regular/locations/ip_location_lookup.rb`)
- Logs key steps, skips when prerequisites are missing.
- Writes `geo_location` only when successfully built.
---
## GeoNames Helpers
New modules in `lib/locations/`:
- `GeoNamesClient`
- Calls `https://secure.geonames.org/getJSON` via `FinalDestination::HTTP`.
- Normalizes `geoname_id`, `fcl`, `fcode`, `lat`, `lon`, etc.
- Caches only successful lookups (avoids caching nil).
- `GeoNamesGranularityPicker`
- Selects best `PCLI` / `ADM1` / `PPL*` by desired granularity.
- `GeoLocationBuilder`
- Builds `geo_location` hash with correct `lat/lon`, `state`/`city` based on granularity.
---
## Rake Task
New rake task in `lib/tasks/locations.rake`:
**Task**
rake locations:enqueue_user_ip_location_lookups[username_pattern,pattern_type,delay]
**Behavior**
- Iterates users and enqueues the IP lookup job using `user.ip_address`.
- Progress is based on **matched population** (not total users).
- Skips enqueue when IP is blank.
**Options**
- `username_pattern` (optional): filter users by username.
- `pattern_type`: `string` (default substring match) or `regex`.
- `delay`: seconds between enqueues (float, default `0`).
**Help**
rake locations:enqueue_user_ip_location_lookups:help
Detalles extensos en el PR.
@Roi Noto que no estás pagando por soporte; sin embargo, creo que pude haber mejorado el código en este PR, por favor intenta de nuevo con ese script que publiqué. Si necesitas que lo revise más de cerca, puedes contratarme.
4 Me gusta
Roi
31 Enero, 2026 22:11
1215
@merefield aún no.
Acabo de comprobarlo, la entrada incorrecta se mantuvo también con la nueva versión.
Pero como solo fue un usuario, lo comprobé manualmente y tenía una ciudad en el campo de ubicación “normal” y recreé el campo de ubicación con esa información. Ahora la consulta está vacía.
2 Me gusta
Hola, publiqué un informe de error en otro lugar y me redirigieron a volver a publicarlo en este tema.
Resulta que si habilitas ubicaciones para una categoría y estableces la vista predeterminada para la categoría en el Mapa, navegar a esa categoría provoca un bloqueo.
Aquí hay algunas capturas de pantalla (disculpen la localización, las palabras significan “Apariencia: Lista de temas predeterminada: Caliente, Último, Principal, Mapa”):
Parece que el complemento accede a siteSettings asumiendo que está definido cuando no lo está.
Informe de error original:
Support
Discourse Locations
Environment Discourse Version: v2026.2.0-latest +15 Plugin Commit: c1547ead Steps to Reproduce When using Locations plugin if I check Allow locations to be added to topics in this category and then try to set the map tab as the default view for...
Reading time: 1 mins 🕑
Likes: 1 ❤
1 me gusta
merefield
(Robert)
1 Febrero, 2026 15:25
1217
gracias, si esto es lo suficientemente importante para ti, puedes contratarme para arreglarlo. PR bienvenido.
1 me gusta