what3words on Alerts
Every operator alert carries the what3words address of its origin, for
example ///filled.count.soap. That is the unique name of the 3 m × 3 m square under the pin. Crews
can read three words over a radio or phone far more reliably than a pair of decimal coordinates.
Similar-sounding addresses are deliberately far apart, so a mis-heard word does not land next door.
Where the address comes from
Frontend.API looks it up at the moment the alert's position is set:
| When | Handler | What happens |
|---|---|---|
| Alert created | CreateAlertMessageCommandHandler | Lookup runs in parallel with the map-image upload, then is stored with the alert. |
| Alert moved (alert-update) | UpdateAlertMessageCommandHandler | Lookup for the new position. On failure NULL is stored: the old address names the old square, and no address is better than a wrong one. |
The lookup is IWhat3WordsClient.ConvertTo3waAsync (Infrastructure, HttpClients/What3WordsClient.cs).
It makes one attempt with no retries and is bounded by What3WordsOptions:TimeoutSeconds (3 s). Any
failure returns null: no key, timeout, quota, outage, or a malformed answer. An alert is never
blocked or failed by what3words; it goes out without an address.
The address is computed server-side rather than sent by the browser. That way the stored address always matches the stored coordinates, whichever client created or moved the alert.
Where it is stored and shown
| Place | Field | Notes |
|---|---|---|
SQL dbo.AlertMessage | What3Words NVARCHAR(64) NULL | Written by AlertMessageInsert / AlertMessageUpdate (@What3Words, default NULL). |
{{What3WordsBlock}} under Lat/Long | what3words: ///filled.count.soap, linked to https://w3w.co/filled.count.soap. | |
| SMS | Second line of the body | Location: ///filled.count.soap https://w3w.co/filled.count.soap (SMS is currently disabled by NotificationOptions:SmsEnabled). |
| Phone call | Spoken after the alert type | "The location's what three words address is: filled. count. soap." The full stops make the voice pause between words. The address reaches the call-automation callback as ?w3w= on the callback URL. That endpoint is anonymous, so only a well-formed address is ever spoken. |
| External-client webhook | what3words | camelCase JSON, null when unknown. |
| ArcGIS Alerts layer | what3words attribute | Written on create; rewritten on move (emptied if the lookup fails). The layer needs the field (see rollout). |
All channel text lives in Alert.CA.Notification/Extensions/What3WordsNotificationText.cs. With no
valid address, every channel is byte-for-byte what it was before.
Configuration
| Key (App Configuration) | Value |
|---|---|
What3WordsOptions:ApiKey | Key Vault reference to secret What3WordsApiKey. This is the same secret the web frontend's BFF reads. |
What3WordsOptions:TimeoutSeconds | Optional, default 3. |
What3WordsOptions:BaseUrl | Optional, default https://api.what3words.com/v3. |
Cost. One convert-to-3wa call per alert create or move, which is tens a day. Conversions to
3 words are unlimited on paid plans, so there is no quota exposure. Latency is under 0.5 s typically and
3 s worst case, overlapped with the map-image upload on create. Storage is ≤ 64 bytes per alert row.
Rollout order (per environment)
Merging to development triggers the Infrastructure (database) and API pipelines in parallel.
New API code calls the stored procedures with @What3Words, which an old database rejects, so the
order matters:
- ArcGIS Online: add a String field named
what3words(length 64) to the Alerts layer:ALERTCalifornia_Alerts_Test,ALERTCalifornia_Alerts_UATandALERTCalifornia_ALERTS_for_Operational_Platform_View. Do this before step 4, so the field exists before alerts start sending the attribute. - Key Vault: create secret
What3WordsApiKeyin the environment's vault. Do this before step 5: every app that loads App Configuration fails to start on a dangling Key Vault reference. - Database PR: merge the
Alert.CA.Infrastructure.Datachange alone (column + both procedures). The procedures default@What3WordstoNULL, so the API that is running keeps working. - Code PR: Infrastructure + Frontend.API + Notification. Until step 5 the key is empty, lookups
are skipped and alerts go out without an address. Note: moving an alert writes
what3wordsto the layer (empty when there is no address), which is why the field must exist first (step 1). - Terraform: apply
What3WordsOptions:ApiKey, then restart Frontend.API (App Configuration is read at start-up).
Check: create a test alert. The email should show a what3words: row, the AlertMessage row
should have What3Words set, and the Frontend.API logs should have no what3words convert-to-3wa
warnings.